Monthly Archives: August 2020

Game Programmer’s handy math formulas

A collection of useful and common math formulas for game developers.

Fast 90 degrees vector rotation clockwise

Vector2 rotated = new Vector2(-original.y, original.x);

Fast 90 degrees vector rotation counterclockwise

Vector2 rotated = new Vector2(original.y, -original.x);

Fast 180 degrees vector rotation

Vector2 rotated = new Vector2(-original.x, -original.y);

2D Vector Rotation Formula

Vector2 Rotate2D(Vector2 v, float angle) {
  Vector2 rotated = new Vector2();
  rotated.x = (v.x * Cos(angle)) − (v.y * Sin(angle));
  rotated.y = (v.x * Sin(angle)) + (v.y * Cos(angle));
  return rotated;
}

3D Vector Rotation Formulas

Rotation around the Y axis:

Vector3 Rotate3D_YAxis(Vector3 v, float angle) {
  Vector3 rotated = new Vector3();
  rotated.x = (v.x * Cos(angle)) + (v.z * Sin(angle));
  rotated.y = v.y;
  rotated.z = -(v.x * Sin(angle)) + (v.z * Cos(angle));
  return rotated;
}

Rotation around the Z axis:

Vector3 Rotate3D_ZAxis(Vector3 v, float angle) {
  Vector3 rotated = new Vector3();
  rotated.x = (v.x * Cos(angle)) - (v.y * Sin(angle));
  rotated.y = (v.x * Sin(angle)) + (v.y * Cos(angle));
  rotated.z = v.z;
  return rotated;
}

Rotation around the X axis:

Vector3 Rotate3D_XAxis(Vector3 v, float angle) {
  Vector3 rotated = new Vector3();
  rotated.x = v.x;
  rotated.y = (v.y * Cos(angle)) - (v.z * Sin(angle));
  rotated.z = (v.y * Sin(angle)) + (v.z * Cos(angle));
  return rotated;
}

Relationship between speed, distance and time

speed = distance / time
distance = speed * time
time = distance / speed

Dot Product

The dot product takes two equal length vectors and returns a number within the range [-1, 1]. When the two vectors are perfectly aligned the result is 1, when they are perfectly opposed the result is -1, when they are perpendicular the result is 0.

This can be used to determine if two vectors are pointing towards the same direction.

Cross Product

Given two vectors a and b, the cross product returns a vector that is perpendicular to both a and b, it describes the normal of the plane containing both a and b.
If the two vectors have the same direction or if one of them is zero, then their cross product is zero.

Lerp Formula (Linear Interpolation)

float Lerp(float a, float b, float t) {
  t = Clamp01(t); // Clamp01 makes sure t is between [0, 1]
  return (1.0f - t) * a + t * b;
}

Inverse Lerp Formula

The inverse lerp is the function that returns a linear value between [0, 1] by linearly interpolating between the first two values with the third.

float InverseLerp(float a, float b, float v) {
  return Clamp01((v - a) / (b - a)); // Clamp01 makes sure the result is between [0, 1]
}

Examples:

a = 10; b = 20; v = 15;  ->  result = 0.5
a = 10; b = 20; v = 10;  ->  result = 0
a = 10; b = 20; v = 60;  ->  result = 1

Clamp Formula / Truncate Formula

Makes sure the given parameter v is between min and max (included).

float Clamp(float v, float min, float max) {
  return Min(Max(v, min), max);
}

Clamp01 Formula

Makes sure the given parameter v is between 0 and 1 (included).

float Clamp01(float v) {
  return Min(Max(v, 0.0f), 1.0f);
}

Distance between two points

float Distance(Vector p1, Vector p2) {
  float squaredDistance = ((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
  return sqrt(squaredDistance);
}

Signed distance between two circles

We take the distance between the two circle centers and substract the radius of both circles from that distance.
When the two circles are far from each other the distance is positive. When the two circles touch each other the distance is zero. And when the two circles overlap each other the distance is negative.

float SignedDistance(Vector c1Center, float c1Radius, Vector c2Center, float c2Radius) {
  return Distance(c1Center, c2Center) - (c1Radius + c2Radius);
}

Signed distance between circle and point

We take the distance between the circle center and the point and subtract the radius of the circle. When the point is inside the circle the distance is negative. When the point is on the edge of the circle, the distance is zero.
This function also works to calculate the signed distance between a sphere and a 3d point.

float SignedDistance(Vector circleCenter, float radius, Vector point) {
  return Distance(point - circleCenter) - radius;
}

The following function returns the distance between a circle and a point. When the point is inside or on the edge of the circle the distance is zero.

float Distance(Vector circleCenter, float radius, Vector point) {
  float distance = Distance(point - circleCenter) - radius;
  return (distance < 0.0f) ? 0.0f : distance;
}

Distance between segment and point

The following function returns the distance between a segment and a point. The segment is defined between the points v and w.
First we try to find the projection of the point p onto the line described by the segment (v, w). We then return the distance between that projection and the given point p.

float Distance(Vector v, Vector w, Vector p) {
  float dist2 = DistanceSquared(v, w); // Squared distance between point v and w
  if (dist2 == 0.0f) // if v == w
    return Distance(p, v);
  float t = Clamp01(Dot(p - v, w - v) / dist2); // Dot Product
  Vector projection = v + t * (w - v);
  return Distance(p, projection);
}

Source: StackOverflow

Circle Circumference / Circle Perimeter

float CircleCircumference(float circleRadius) {
  return 2.0f * PI * circleRadius; // PI is a constant value of 3.14159265359
}

Circle Arc Length

float CircleArcLength(float circleRadius, float arcAngleInRadians) {
  return circleRadius * arcAngleInRadians;
}

Angle in radians between two vectors

float AngleRad(Vector v1, Vector v2) {
  float cosAngle = DotProduct(v1, v2) / (v1.magnitude * v2.magnitude);
  return ArcCos(cosAngle);
}

Continue reading ...