Vectors
Excalibur provides three vector types to handle spatial math:
- Vector: 2D vectors for positioning, velocities, and physics on a plane.
- Vector3: 3D vectors commonly used for spatial transforms, lighting, and shader uniforms.
- Vector4: 4D vectors primary used for homogeneous coordinates, WebGL shaders, and matrix transformations.
Excalibur uses the Vector structure to represent points. The Vector class has many different static methods available for doing vector math as well as instance methods to combine vectors together in different ways.
Creating Vectors
To quickly create vectors, use the global shorthand functions vec, vec3, or vec4:
tsimport {vec ,vec3 ,vec4 } from 'excalibur'constpoint2D =vec (0, 10)constpoint3D =vec3 (0, 10, 5)constpoint4D =vec4 (0, 10, 5, 1)
tsimport {vec ,vec3 ,vec4 } from 'excalibur'constpoint2D =vec (0, 10)constpoint3D =vec3 (0, 10, 5)constpoint4D =vec4 (0, 10, 5, 1)
Alternatively, you may see examples of using the more verbose new Vector(x, y) format:
tsimport {Vector ,Vector3 ,Vector4 } from 'excalibur'constpoint2D = newVector (0, 10)constpoint3D = newVector3 (0, 10, 5)constpoint4D = newVector4 (0, 10, 5, 1)
tsimport {Vector ,Vector3 ,Vector4 } from 'excalibur'constpoint2D = newVector (0, 10)constpoint3D = newVector3 (0, 10, 5)constpoint4D = newVector4 (0, 10, 5, 1)
To set the value of an existing vector, use Vector.setTo:
tsimport {vec ,vec3 ,vec4 } from 'excalibur'constpoint2D =vec (0, 10).setTo (10, 10)constpoint3D =vec3 (0, 10, 0).setTo (10, 10, 10)constpoint4D =vec4 (0, 0, 0, 0).setTo (10, 10, 10, 1)
tsimport {vec ,vec3 ,vec4 } from 'excalibur'constpoint2D =vec (0, 10).setTo (10, 10)constpoint3D =vec3 (0, 10, 0).setTo (10, 10, 10)constpoint4D =vec4 (0, 0, 0, 0).setTo (10, 10, 10, 1)
Each vector class provides built-in constants for common directional and utility vectors:
| Feature | Constants Available |
|---|---|
| Vector | Zero, One, Half, Left, Right, Up, Down |
| Vector3 | Zero, One, Left, Right, Up, Down, Forward, Back |
| Vector4 | Zero, One |
Cloning vectors
Vectors are objects, so mutating them will change the state for all references. Use the Vector.clone method to clone a vector to mutate it:
tsimport {vec } from 'excalibur';constpoint =vec (0, 10);point .setTo (8, 8);constsamePoint =point ;constanotherPoint =point .clone ();anotherPoint .setTo (50, 50);console .log (point .toString ()); // "(8, 8)"console .log (samePoint .toString ()); // "(8, 8)"console .log (anotherPoint .toString ()); // "(50, 50)"
tsimport {vec } from 'excalibur';constpoint =vec (0, 10);point .setTo (8, 8);constsamePoint =point ;constanotherPoint =point .clone ();anotherPoint .setTo (50, 50);console .log (point .toString ()); // "(8, 8)"console .log (samePoint .toString ()); // "(8, 8)"console .log (anotherPoint .toString ()); // "(50, 50)"
Notice how both point and samePoint share the same vector reference, so using setTo mutates the vector. Use clone to ensure you are not changing vectors unexpectedly!
setTo returns void so that it "feels awkward" to chain it.
This is intentional to avoid confusion about whether you are mutating the vector or creating a new one.
Linear interpolation (lerp) between vectors
All vector classes support lerp, which returns a new vector representing a point along the path between two vectors. Given a target vector and an interpolation factor t between 0 and 1, it produces the intermediate vector.
The standard formula for linear interpolation is:
lerp(a, b, t) = a + (b - a) * t
lerp(a, b, t) = a + (b - a) * t
- a = starting vector
- b = target vector
- t = interpolation factor (0 ≤ t ≤ 1)
When t = 0, the result is a.
When t = 1, the result is b.
When t = 0.5, the result is exactly halfway between a and b.
tsimport {vec ,vec3 } from 'excalibur'conststart2D =vec (0, 0)constend2D =vec (100, 200)constmid2D =start2D .lerp (end2D , 0.5) // vec(50, 100)conststart3D =vec3 (0, 0, 0)constend3D =vec3 (10, 20, 30)constmid3D =start3D .lerp (end3D , 0.5) // vec3(5, 10, 15)
tsimport {vec ,vec3 } from 'excalibur'conststart2D =vec (0, 0)constend2D =vec (100, 200)constmid2D =start2D .lerp (end2D , 0.5) // vec(50, 100)conststart3D =vec3 (0, 0, 0)constend3D =vec3 (10, 20, 30)constmid3D =start3D .lerp (end3D , 0.5) // vec3(5, 10, 15)