- Distances
- Bounds
- Trigonometry
- Interpolation

A*A + B*B = C*C

Distance between two points P0 *(x0,y0)* and P1 *(x1,y1)*:

A = x1 - x0 B = y1 - y0 (x1-x0)*(x1-x0) + (y1-y0)*(y1-y0) = C*C dist = C = sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0))

Distance between two 3D points P0 *(x0,y0,z0)* and P1 *(x1,y1,z1)*:

dist = sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0) + (z1-z0)*(z1-z0))

Note: *sqrt* is considered an expensive (i.e. slow) function

Simple representation of approximate area covered by an object

Always completely contains the object

Typically a box or a circle/sphere

To compute a bounding box of an object, assuming its vertices are
contained in the list `obj.vertices`:

minX = obj.vertices[0][0] maxX = obj.vertices[0][0] minY = obj.vertices[0][1] maxY = obj.vertices[0][1] minZ = obj.vertices[0][2] maxZ = obj.vertices[0][2] for v in obj.vertices: if minX > v[0]: minX = v[0] elif maxX < v[0]: maxX = v[0] if minY > v[1]: minY = v[1] elif maxY < v[1]: maxY = v[1] if minZ > v[2]: minZ = v[2] elif maxZ < v[2]: maxZ = v[2]

To determine if a point `(x,y)` is inside a bounding box:

(x >= minX) and (x <= maxX) and (y >= minY) and (y <= maxY) and (z >= minZ) and (z <= maxZ)

To compute a bounding sphere, find a center, and then the most distant vertex:

xsum,ysum,zsum = 0,0,0 for v in obj.vertices: xsum += v[0] ysum += v[1] zsum += v[2] center = [ xsum / len(obj.vertices) , ysum / len(obj.vertices), zsum / len(obj.vertices) ] radius = 0 for v in obj.vertices: d = distance(v, center) if d > radius: radius = d

To determine if a point `(x,y,z)` is inside a bounding sphere:

distance(center, (x,y,z)) <= radius

Compute the overlap of two boxes - the region of points which are contained in both boxes. If an overlap exists, they collide.

def BoxCollidesWithBox(box1, box2): minx = max(box1.minX, box2.minX) maxx = min(box1.maxX, box2.maxX) miny = max(box1.minY, box2.minY) maxy = min(box1.maxY, box2.maxY) minz = max(box1.minZ, box2.minZ) maxz = min(box1.maxZ, box2.maxZ) return (minx <= maxx) and (miny <= maxy) and (minz <= maxz)

Compute distance between the centers of the two spheres. If it's less than the sum of the radii, then there exist points that lie within both spheres -> the spheres overlap.

def SphereCollidesWithSphere(s1, s2): d = s1.center.distanceSquared(s2.center) rsum = s1.radius + s2.radius return (d <= rsum*rsum)

sin(A) = opposite / hypotenuse cos(A) = adjacent / hypotenuse tan(A) = opposite / adjacent

or

opposite = hypotenuse * sin(A) adjacent = hypotenuse * cos(a)

x = radius * cos(A) y = radius * sin(A)

Standard math library functions use radians

360 degrees = 1 full circle = 2 π radians

(Circumference of unit circle = 2 π)

radians = degrees / 360.0 * 2 * pi

or

radians = degrees / 180.0 * pi(or use Python's pre-defined functions

glBegin(GL_LINE_LOOP) for degrees in range(0, 360): angleInRadians = math.radians(degrees) x = math.cos(angleInRadians) * radius y = math.sin(angleInRadians) * radius glVertex2f(x,y) glEnd()

Vehicle has direction and speed of travel

Direction is orientation - rotation about Z

To move forward:

distance = speed * time dx = math.cos(direction) * distance dy = math.sin(direction) * distance x = x + dx y = y + dy

`atan2` converts from (X,Y) coordinates back to angles

Note: it takes arguments in the order Y, X

angle = math.degrees( math.atan2(y,x) )

Deriving a value for something from two pre-defined values (extremes)

e.g. Moving object from one position to another, over time

Interpolation expressed as fractional distance between the two extremes

Ranges from 0.0 to 1.0

0.0 = first point; 1.0 = second point

For a single value, with extremes `V0` & `V1` and interpolation fraction `A`:

V = (1 - A) * V0 + A * V1

For multiple values, such as XYZ position, use the same fraction `A` for all:

X = (1 - A) * X0 + A * X1 Y = (1 - A) * Y0 + A * Y1 Z = (1 - A) * Z0 + A * Z1

To interpolate over time, compute interpolation fraction based on the amount of time that has passed.

Example:

def startAnimation(): animating = True startTime = time.time() duration = 5 def computeAnimation(): if animating: t = time.time() - startTime if t <= duration: a = t / duration else: animating = False a = 1 x = (1-a)*startX + a*endX y = (1-a)*startY + a*endY z = (1-a)*startZ + a*endZ

Linear | Slow-in Slow-out |
---|---|

X = t | X = -2*t*t*t + 3*t*t |

A2 = -2*A*A*A + 3*A*A V = (1-A2) * V0 + A2 * V1

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