Vectors

A vector is a direction and magnitude (length). Vectors are used to represent many different things - for example, object motion or relative locations of objects. In 3D, vectors are used extensively in lighting.






Vectors

We normally describe a vector as a pair of (X, Y) values (in 2 dimensions), or a triplet of (X, Y, Z) values (in 3 dimensions) - (vx, vy, vz) represents a vector that points vx units in the direction of the X axis, vy units in the direction of the Y axis, and vz units in the direction of the Z axis.

e.g., (2, 0, 0) is a vector pointing in the direction of the X axis, 2 units long. (1, 1, 0) is a vector pointing at a 45 degree angle between the X and Y axes, 1.414 units long.

The magnitude of a vector (x,y,z) is its Euclidean length - the square root of vx2 + vy2 + vz2.






Vector Addition

Two vectors can be combined by adding their corresponding components together.
i.e. (vx, vy, vz) + (wx, wy, wz) is (vx+wx, vy+wy, vz+wz ).

Or, written more expansively:

The result is a vector that is equivalent to sticking the vector W onto the end of vector V, and creating a new vector from the beginning of V to the end of W.






Vector Addition






Vector/Scalar Multiplication

A vector can be multiplied by a single number (a "scalar") to change its length without changing its direction.






Dot Product

The dot product of two vectors is an operation defined as:

The result is a single number, which is equal to the product of the lengths of the two vectors and the cosine of the angle between them.

It can tell us how much two vectors point in the same direction - it is maximum when they point in exactly the same direction, and it's 0 when they're at right angles.






Programming With Vectors

Creating a vector class allows one to work with vectors more simply.

Vector operations just require a single statement, rather than a loop or separate statements for X, Y, & Z components.

    a = Vector3(1, 2, 3)
    b = Vector3(0, -1, 0)
    c = a + 2 * b
    d = a.dot(b)





Motion With Vectors

A vector can be used to represent the motion of an object.

The vector indicates the object's velocity - the direction of the vector is the direction that the object is moving, the magnitude of the vector is the speed.

The vector corresponds to how the object will move in one unit of time.
e.g., a velocity vector of (2, 0, 0) indicates that the object is moving 2 meters/second along the X axis (assuming our units are meters and seconds). If it starts at (3, 1, 0), then after 1 second its position will be (5, 1, 0). After 2 seconds, its position will be (7, 1, 0).

[Note that the choice of units is arbitrary, and is up to you when writing your programs; all that matters is that you be consistent within a program, and not, for instance, try to combine meters per second with miles per hour.]






Simple Motion

In general, if an object starts at position P0, with velocity V, then after t time units, its position P(t) will be:

            P(t) = P0 + t * V





Varying Velocity

The previous formula only works if the object moves with a constant velocity.

In many cases, objects' velocities change over time.

In such a case, velocity is a function that we integrate.

Displacement = Velocity dt

In complex motion, there isn't an analytical solution (i.e. a simple formula).






Euler Integration

Euler integration approximates an integral by step-wise addition.

At each time step, we move the object in a straight line using the current velocity:

    dt = t1 - t0
    P(t1) = P(t0) + V * dt

Example: bounce.py




Acceleration

Velocity is the integral of acceleration:

Velocity = Acceleration dt

Applying Euler integration again gives:

    dt = t1 - t0
    Acc = computeAcceleration()
    Vel = Vel + Acc * dt
    Pos = Pos + Vel * dt





Gravity

Gravity near the Earth's surface produces a constant acceleration of 9.8 m/sec2

In this case:

Acc = Vector3(0, -9.8, 0)


Example: gravbounce.py






Force

Newton's 2nd Law of Motion:

Force = Mass * Acceleration

Which can be rewritten as

Acceleration = Force / Mass

If an object has mass M, and force F is applied to it,
its motion can be calculated via Euler integration:

    Acc = F / M
    Vel += Acc * dt
    Pos += Vel * dt

Note that F, Acc, Vel, and Pos are all vectors. M is a scalar.






Gravity Again

F = (G * M1 * M2) / d2

For a complete simulation, we need to calculate the force on each object every frame.

When multiple forces are applied, their vectors are added.


Example: gravorbit.py






Other Forces

Drag (slow moving objects):

F = Cdrag * V

Drag (fast moving objects):

F = Cdrag * V2

Buoyancy:

F = ρliquid * g * Volume






Springs

Hooke's Law
Force is proportional to displacement

K = spring constant
d = displacement from rest length

Spring is modeled as 2 point masses, linked by the spring

Equal but opposite force is applied to each end






Springs


When spring is stretched, spring force pulls masses together


When spring is compressed, spring force pushes masses apart






Springs

Vector between the points is used to compute displacement and the direction of force:

    v = point1 - point0
    displacement = v.magnitude() - restLength
    v.normalize()
    force = springConstant * displacement * v





Springs






Spring Classes

Two classes needed: PointMass and Spring

PointMass

Attributes:
Mass
Position
Velocity
Acceleration
Functions:
Clear forces
Add force
Update
Freeze





Spring Classes

Spring

Attributes:
Two PointMasses
Spring constant
Rest length
Functions:
Update





Spring-based Objects

Solid objects can be simulated as a collection of springs

Stiff springs (large spring constant) produce rigid objects.
Loose springs produce jello-like objects.






Spring-based Objects

Often, additional internal springs are needed to keep a shape from collapsing






Cloth

Cloth can be simulated by a mesh of springs






Cloth

Diagonal springs are again useful, to keep the mesh from collapsing easily






Numerical Explosion

Spring calculations are prone to "numerical explosion"

Possible solutions:
  • Smaller timesteps
  • Looser springs
  • Arbitrarily limit velocities
  • Better integration method


Creative Commons License
This document is by Dave Pape, and is released under a Creative Commons License.