Math







Pythagorean Theorem


A*A + B*B = C*C





Euclidean Distance

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






Bounds

Simple representation of approximate area covered by an object

Always completely contains the object

Typically a box or a circle/sphere




Bounding Box

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]





Bounding Box

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)





Bounding Sphere

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





Bounding Sphere

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

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





Simple Collision Detection

Box-Box Collision

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)





Simple Collision Detection

Sphere-Sphere Collision

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)





Trigonometry

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

or

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





Trigonometry

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





Radians

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 math.radians(d) and math.degrees(r))




Making a Circle

    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()





Driving

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

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) )





Interpolation

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

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






Linear Interpolation

Interpolation expressed as fractional distance between the two extremes

Ranges from 0.0 to 1.0
0.0 = first point; 1.0 = second point






Linear Interpolation

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





Timing

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





Timing

Linear Slow-in Slow-out
X = tX = -2*t*t*t + 3*t*t
A2 = -2*A*A*A + 3*A*A
V = (1-A2) * V0 + A2 * V1


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