2

首先,我将在下面发布的一些 JavaScript 代码中出现“超出最大调用堆栈大小”错误,我不确定它来自哪里。我不认为我在递归调用任何东西,而且我环顾四周找不到任何其他错误原因。我正在使用 Chrome 来执行程序,我可以从控制台中得到的唯一细节是“Vector Vector Vector Vector Vector Vector Vector...”等。我认为这意味着 Vector 函数正在递归调用自身,但是,再一次,我不知道发生在哪里。因此,首先,这是 Vector 函数:

function Vector(top,left) { //a vector constructor, with all necessary vector operations
    this.top = top; //the 'top' component, which points down
    this.left = left;   //the 'left' component, which points right
    this.in = 0;        //the 'in' component, which points out of the screen
    this.magnitude = Math.sqrt(this.top*this.top+this.left*this.left);  //the magnitude of the vector
    this.reverse = new Vector(-this.top,-this.left);                            //the vector that points opposite of this vector
    this.unit = this.Scale(1/this.magnitude);                                       //the unit vector pointing in this vector's direction
    this.Scale = Scale;         //multiplying vectors by a constant
    this.Add = Add;             //easier vector addition
    this.Subtract = Subtract;   //and subtraction
    this.Dot = Dot;             //a dot product operation
    this.Cross = Cross;         //the cross product of two planar vectors; it returns the 'in' component of the resulting vector
    this.Project = Project;     //the projetion of the parameter vector onto this vector
        function Scale(scalar) {return new Vector(scalar*this.top,scalar*this.left);}
        function Add(vector) {return new Vector(this.top+vector.top,this.left+vector.left);}
        function Subtract(vector) {return new Vector(this.top-vector.top,this.left-vector.left);}   //the abovedescribed methods
        function Dot(vector) {return this.top*vector.top+this.left*vector.left;}
        function Cross(vector) {return this.top*vector.left-this.left*vector.top;}
        function Project(vector) {return this.Scale(this.Dot(vector)/Math.pow(this.magnitude,2))}
    }

var zeroVector = new Vector(0,0);

这是完整的代码。随意完全忽略它,尽管也许有些东西对你来说是显而易见的,而这些东西对我来说是无可挑剔的。

<!DOCTYPE html>
<html>

<head>
    <title>temp</title>
</head>

<body>
    <canvas
        id="canvas"
        height="768px"
        width="1366px"
        style="position:fixed;top:0px;left:0px;"
        />
</body>

<script>
/*------------------------------------------------------------Composition Center--------------------------------------------------*/ {
    window.onload = run;    //it'll start running as soon as it's started up

    var interval;   //the interval variable for the 'run' function

    function run() {
        interval = setInterval(function() {
            for (i=0; i!=0; i++) {
                var Point = point;
                var vPrime = zeroVector;
                var netForce = zeroVector;
                for (j=0; j!=0; j++) {
                    var Edge = edge;
                    updateCollision(Point,Edge);
                    }
                updatePosition(Point);
                updateVelocity(Point);
                draw();
                }
            },16);
        }
/*---------------------------------------------------------------------------------------------------------------------------------*/ }



/*-------------------------------------------------------------Physics Engine------------------------------------------------------*/ {
                                //--Constructors--//
    function PointObject(mass,top,left) {   //a point object
        this.mass = mass;                               //mass
        this.position = new Vector(top,left);   //position
        this.velocity = zeroVector;             //velocity
        this.near = nullEdge;                       //a memory tool which stores the edge the point is close to
        }
    function Rectangle(top,left,height,width) { //a rectangle that'll be solid, but not affected by gravity or anything
        this.position = new Vector(top,left);
        this.height = height;   //self-explanatory
        this.width = width;
        }
    function Edge(start,end) {
        this.start = start;                     //the start point (vector)
        this.end = end;                         //end point (vector)
        this.vector = end.Subtract(start);  //the vector pointing from the start to the end point of the edge
        this.RUN = new Vector(this.vector.left,-this.vector.top).unit;  //the RIGHT pointing UNIT NORMAL vector to the edge vector
        this.rightPermeable = false;    //whether or not the edge can be passed through from the right to the left
        this.leftPermeable = true;      //or from the left to the right
        }
                                //--Objects--//
    var base = new Rectangle(3/4*768,33,768/4,1300);                    //the main base solid
    var point = new PointObject(1,base.position.top-201,1366/2);    //the point object at the center of this whole ordeal
    var edge = new Edge(new Vector(base.position.top,base.position.left+base.width),base.position); //a test edge. they'll be auto-assembled later

    var nullEdge = new Edge(zeroVector,zeroVector);

    var deltaT = .01;   //standard time interval

                                //--Loop o' Physics--//
    //Update Collision
        function updateCollision(Point,edge) {  //check if any points are crossing edges and deal with that
            var startToPoint = Point.position.Subtract(edge.start); //the vector from the start point of the edge to the tested point
            if (edge.rightPermeable && edge.vector.Cross(startToPoint) < 0) {return "Negatory.";}   //if it could only approach from a permeable side, stop testing
            if (edge.leftPermeable && edge.vector.Cross(startToPoint) > 0) {return "Negatory.";}
            var projection = edge.vector.Project(startToPoint);     //the projection of that vector onto the edge vector
            if (projection.Dot(edge.vector) < 0) {return "Negatory.";}  //if it's not pointing in the same dircetion as the edge vector, it's not gonna hit the edge
            var distance = startToPoint.Subtract(projection);           //the normal vector to the edge that points to the Point
            var velocity = distance.Project(Point.velocity);            //the component of the point's velocity orthogonal to the edge
            if (distance.Dot(velocity) >= 0) {return "Negatory.";}  //if the orthogonal velocity component is pointing 'to the point,' it won't collide
            var specificT = distance.magnitude/velocity.magnitude;  //the time it'll take for the point to hit the edge, if it continues with it's current velocity
            if (deltaT <= specificT) {return "Negatory.";}  //if the point can't move far enough to cover the distance, it won't collide
            //at this point, the collision will happen
            Point.near = edge;  //have the point remember that it collided with this edge, so it won't have to be totally re-tested for normal forces
            Point.position = Point.position.Add(Point.velocity.Scale(specificT)).Add(distance.Scale(.0001));    //move the point just a wee bit away from the edge
            vPrime = Point.velocity.Add(velocity.reverse);  //impulse away the velocity orthogonal to the edge
            Point.velocity = Point.velocity.Scale(0);   //zero the current velocity
            }
    //Update Position
        function updatePosition(Point) {Point.position = Point.position.Add(Point.velocity.Scale(deltaT));} //d=vt, essentially
    //Update Velocity
        function updateVelocity(Point) {    //via forces
            var gravity = new Vector(20,0); //gravity... hobviously
            netForce = netForce.Add(gravity);   //add up all the current forces to get the right normal force
            if (Point.near != nullEdge) {   //calculating normal force, so it needs to be near an edge
                var startToPoint = Point.position.Subtract(Point.near.start);
                var projection = Point.near.vector.Project(startToPoint);   //same stuff as earlier
                var distance = startToPoint.Subtract(projection);
                if (distance.magnitude <= .01) {                                                                //if it's very near to the edge
                    normalForce = distance.Project(netForce.reverse);                                   //exert enough force to cancel anything going into the edge
                    if (normalForce.Dot(distance) > 0) {netForce = netForce.Add(normalForce);}  //if it is indeed going into the edge
                    } else if (distance.magnitude > 1) {Point.near = nullEdge;} //it's not near the edge any more
                }
            Point.velocity = Point.velocity.Add(netForce.Scale(deltaT/Point.mass)); //v=at, essentially
            }
/*---------------------------------------------------------------------------------------------------------------------------------*/ }



/*----------------------------------------------------Graphics----------------------------------------------------------------------*/ {
    var c = document.getElementById("canvas").getContext("2d"); //the means for drawing all this

    PointObject.prototype.Draw = function() {   //the draw method for point objects
        c.fillStyle = "#000000";    //a black square with the point at its center pixel
        c.fillRect(this.position.left-2,this.position.top-2,5,5);
        }
    Rectangle.prototype.Draw = function() { //draw method for rectangles
        c.fillStyle = "#c0c0c0";    //a grey rectangle; the position is the top left corner
        c.fillRect(this.position.left,this.position.top,this.width,this.height);
        }

    function draw() {   //draws everything
        c.clearRect(0,0,1366,768);  //clear the screen
        base.Draw();                    //paint stuff
        point.Draw();
        }
/*----------------------------------------------------------------------------------------------------------------------------------*/ }



/*------------------------------------------------------------Math Tools-------------------------------------------------------------*/ {
                                //--Vector Tools--//
    function Vector(top,left) { //a vector constructor, with all necessary vector operations
        this.top = top; //the 'top' component, which points down
        this.left = left;   //the 'left' component, which points right
        this.in = 0;        //the 'in' component, which points out of the screen
        this.magnitude = Math.sqrt(this.top*this.top+this.left*this.left);  //the magnitude of the vector
        this.reverse = new Vector(-this.top,-this.left);                            //the vector that points opposite of this vector
        this.unit = this.Scale(1/this.magnitude);                                       //the unit vector pointing in this vector's direction
        this.Scale = Scale;         //multiplying vectors by a constant
        this.Add = Add;             //easier vector addition
        this.Subtract = Subtract;   //and subtraction
        this.Dot = Dot;             //a dot product operation
        this.Cross = Cross;         //the cross product of two planar vectors; it returns the 'in' component of the resulting vector
        this.Project = Project;     //the projetion of the parameter vector onto this vector
            function Scale(scalar) {return new Vector(scalar*this.top,scalar*this.left);}
            function Add(vector) {return new Vector(this.top+vector.top,this.left+vector.left);}
            function Subtract(vector) {return new Vector(this.top-vector.top,this.left-vector.left);}   //the abovedescribed methods
            function Dot(vector) {return this.top*vector.top+this.left*vector.left;}
            function Cross(vector) {return this.top*vector.left-this.left*vector.top;}
            function Project(vector) {return this.Scale(this.Dot(vector)/Math.pow(this.magnitude,2))}
        }

    var zeroVector = new Vector(0,0);
/*-----------------------------------------------------------------------------------------------------------------------------------*/ }
</script>

</html>

无论如何,第二件事是关于我如何编写 Vector 构造函数的一些位,这可能会以某种方式导致我的错误。在不同的地方,我在函数的属性和方法中使用了“new Vector()”,我不知道这是否非法。我想我以前做过没有错误,但我不确定。

另外,对于“幅度”、“反向”和“单位”属性,我应该将它们改写为方法吗?我认为它们在创建时被锁定在向量的幅度/反向/单位向量中,因此如果更改顶部或左侧属性,它们将返回不正确的值。我还没有改变它们的唯一原因是它们让我印象更深的是属性而不是方法,只是在概念上。它还没有引起任何问题或任何事情;就是想。

如果你想在 JSFiddle 或其他类似的东西上这样做,我很乐意为你效劳。

4

0 回答 0