top of page
Search
  • cedarcantab

Physics Simulation: Vector object

Updated: Jun 19, 2023


2D Vectors in Javascript


Before I start actually trying to code the laws of physics, it's useful to remind ourselves about vectors and vector maths, since moving things about on a 2D plane is a lot easier using vector maths.


What is a vector?

I shall not explain what vectors are since there is plenty of web-sites that give far better explanation that I ever could. This page here for example gives a concise but easy to understand explanation of all the vector maths that you would require in basic collision handling.


Phaser 3 vector class

Phaser 3 actually provides class for defining vectors, together with methods to carry out vector mathematics.


Be careful about the way you apply methods

Typically the method changes the vector that the method is applied to it, as opposed to returning a new vector. So if you want to apply different methods to the same vector but want to keep the original vector intact, you need to use either:

  1. clone(): returns a copy as a new vector,

  2. copy(src): copies the content of the src vector to the vector that the method is applied to it, or

  3. new Vector2(originalVec.x, originalVec.y): create a new vector directly with the relevant components of the vector you want to manipulate


Particularly useful methods for physics engine

Phaser 3 provides pretty much all the typical vector calculation methods, including the following


  • length() returns the magnitude of the vector

  • lengthSq() returns the squared of the magnitude of the vector

  • scale(src); multiples the x and y components by src -- this is not the same as multiply(src) which carries out a component-wise multiplication between this vector and the given vector.

  • negate() simply changes the sign of the x and y components of this vector

  • normalize() means makes the vector's magnitude to 1, but keep the same direction

  • setLength() -- this is NOT the same as scale(), as is clear by the underlying code.

 setLength: function (length) {
        return this.normalize().scale(length);
 },

Graphical illustration of the vector methods

Below picture gives a graphical representation of various vector methods applied between VecA in BLUE and VecB in RED (in drawing the lines, I have shifted everything so that the "origin" is the middle of the screen, so that is it easier to understand).


  • YELLOW: reflection = vecA.clone().reflect(vecB);

  • GREY: mirror = vecA.clone().mirror(vecB);

  • PINK: leftNormal = vecB.clone().normalizeLeftHand();

  • CYAN: rightNormal = vecB.clone().normalizeRightHand();

  • GREEN POINT: projected = Phaser.Geom.Point.Project(vecA, vecB);

    • Above method can be replicated using vector maths

    • vecBUnit = vecB.clone().normalize();

    • projected = vecBUnit.clone().scale(vecA.dot(vecBUnit))



"Projection" of a vector onto another (illustrated by the BLUE vector projected onto the RED vector in the above diagram) is a really important in physics engines, more specifically it is important to understand the dot product, which I will explore in a separate post next.



Adding "immutable" variation of existing methods

Sometimes you want the operation to return a new vector without changing the original vector.


I have done this mainly via 2 variations: (i) by adding an "i" to the end of the equivalent method like below:


   addi(vec) {
    return new Vector2(this.x + vec.x, this.x + vec.y)
  }

Using the above extended Vector class, is easy.


var a = new Vector2(3,5);
var b = new Vector2(5,8);
var c = a.addi(b)
console.log("a=",a,"c=",c);

will return c as {x: 8, y: 11} but will retain a as { x:3, y:5 }


and a static method with the first letter of the method capitalised, like below;


  static Add(vec1, vec2) {
    return new Vector2(vec1.x + vec2.x, vec1.x + vec2.y)
  }

I have included the code in Codepen below.





Useful References



https://youtu.be/-n_C7tD55_A (a practical look at the cross product in 2D)









13 views0 comments
記事: Blog2_Post
bottom of page