Step 1 of 5 · Reading · ~4 min
Read
Math & Integration
2D Vectors
Every quantity in the engine you are building is a pair of numbers: a position, a velocity, a force, a direction. After this lesson your program will answer vector questions from a script: how far apart are these two points, what is the part of this motion that points along a wall, and where does a ball leave after hitting a surface?
A vector is an arrow
A 2D vector (x, y) is an arrow with a length and a direction. The same pair can mean a place ("the ball is at (3, 4)") or a displacement ("it moved by (1, -2)"). The engine mixes them constantly, so keep the arithmetic in one place.
- Add
a + b = (ax + bx, ay + by): walk alonga, then alongb. - Subtract
a - b = (ax - bx, ay - by): the arrow that points frombtoa. This is how you get "from body A to body B". - Scale
s * a = (s*ax, s*ay): same direction,stimes as long. A negativesflips it.
Length and direction
The length follows from Pythagoras: |a| = sqrt(ax^2 + ay^2). Many tests only need to compare distances, and for those the squared length ax^2 + ay^2 is enough: |d| < r and |d|^2 < r^2 agree when r >= 0, and the second form needs no square root.
A unit vector has length 1 and carries only direction. To normalize, divide both components by the length. The zero vector has no direction, and dividing by its length is 0 / 0. Decide what to return for it (this course returns the zero vector) and do it before dividing. Do not use a "small enough" cutoff: a legitimate vector such as (0.0003, 0.0004) is tiny but still has a direction, and it must normalize to (0.6, 0.8).
Dot product: how much do they agree?
a . b = ax*bx + ay*by, and geometrically a . b = |a| |b| cos(angle).
- Positive: the arrows point broadly the same way. Zero: perpendicular. Negative: broadly opposite.
- If
nis a unit vector,a . nis the signed length ofa's shadow on the line throughn. Collision code uses this constantly: "how fast is B approaching along the contact normal" is a dot product.
Projection. The part of a that lies along b is the shadow length times the direction of b:
proj_b(a) = ( (a . b) / (b . b) ) * b
Dividing by b . b instead of assuming b is a unit vector makes it work for any non-zero b. If b is zero there is no line to project onto, so return the zero vector.
Worked trace with a = (2, 5), b = (0, 2): a . b = 10, b . b = 4, so the factor is 2.5 and the projection is (0, 5). The leftover a - proj = (2, 0) is perpendicular to b. Together they rebuild a.
2D cross product: which side?
In 2D the cross product is a single signed number: a x b = ax*by - ay*bx. Its size is the area of the parallelogram the two arrows span, and its sign says which way you turn from a to b: positive is counter-clockwise, negative is clockwise, zero means parallel. Swapping the operands flips the sign. Rotating a vector 90 degrees counter-clockwise gives the perpendicular perp(x, y) = (-y, x); edge normals of polygons come from it.
Reflection
A ball with velocity v hits a surface whose normal is the unit vector n. Split v into the part along n (the part that hits the wall) and the rest (the part sliding along it). Bouncing reverses only the first part:
v' = v - 2 (v . n) n
Only a unit n makes the factor 2 correct. If the caller hands you (0, 2) as a normal you must normalize it first. Sanity check: v = (4, -3) bouncing off a floor with n = (0, 1) has v . n = -3, so v' = (4, 3).
Common mistakes
- Dividing by the length of the zero vector and printing
nan. Guard it first. - Treating a short vector as the zero vector. Only an exactly zero length has no direction.
- Projecting with
(a . b) * band forgetting the division byb . b; the answer is only right whenbhas length 1. - Reflecting about a normal that is not unit length. The bounce is then scaled wrongly.
- Mixing up the cross product's operand order.
a x bandb x adiffer in sign.
Your exercise
The starter reads commands and prints results; the helpers for add, subtract, scale, length and perpendicular are already written. You implement dot, cross, normalize, project and reflect. The most likely mistake is forgetting to normalize the surface normal in reflect.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…