Create a gist now

Instantly share code, notes, and snippets.

@xem /readme.md
Last active Nov 8, 2017

What would you like to do?
Maths & trigonometry cheat sheet for 2D & 3D games

Conventions

  • A = [xA, yA] is a point on the 2D plane. Same for B, C, ...
  • lengths are in any unit (ex: pixels)
  • code snippets are in JavaScript

Degrees to radians

angleRad = angleDeg * Math.PI / 180;

Radians to degrees

angleDeg = angleRad * 180 / Math.PI;

Unit circle

unit circle

2D

Distance between two points (Pythagore)

  • dist = function(A,B){ return Math.sqrt((xB - xA)*(xB - xA) + (yB - yA)*(yB - yA)) } // ES5
  • dist = (A, B) => Math.hypot(xB - xA, yB - yA) // ES6

Line passing through 2 points

  • line equation: y = ax + b
  • a = (yB - yA) / (xB - xA) = tan θ
  • θ = angle between line and x axis
  • b = yA - a * xA (because yA = a * xA + b)

Intersection of 2 secant lines

  • line 1: y = a * x + b
  • line 2: y' = a' * x + b'
  • intersection point P:
    • xP = (a - a')/(b' - b);
    • yP = a * xP + b;
  • Ex with y = 5 * x + 1 and y' = 2 * x + 8:
    • xP = 7/3;
    • yP = 12.666;

Angle in radians between the x axis at the origin and a point on the plane

angle = Math.atan2(Ax, Ay)

Angle in radians between two points and the origin

angle = Math.atan2(By - Ay, Bx - Ax);

Rotate a point of the plane around the origin (angle in radians)

  • Anew_x = Ax * Math.cos(angle) - Ay * Math.sin(angle)
  • Anew_y = Ax * Math.sin(angle) + Ay * Math.cos(angle)
  • It's the same as applying the following rotation matrix:
vec2 (
    +cos(a), -sin(a)
    +sin(a), +cos(a)
)

Normalize a vector

a.k.a Project any point of the plane on the trigonometric circle (center: origin, radius: 1)

ES5:

Anew_x = Math.cos(atan2(Ax, Ay));
Anew_y = Math.sin(atan2(Ax, Ay));

ES6:

tmp = Math.hypot(Ax, Ay);
Ax = Ax / tmp;
Ay = Ay / tmp;

Intersections between a line and the grid (a.k.a 2D raycasting)

Projection of a plane on a sphere

2D jumps / gravity (ex: for side-view platform games)

  • let x, y the position of the object (ex: 0, 0)
  • let vx, vy the horizontal and vertical speed of the object (ex: 0, 0)
  • let g, the gravity (which is a downwards acceleration, ex: -10)
  • during the frame at the start of the jump: set vy to a high value, ex: 50
  • during all the frames of the jump:
    • Add g to vy (ex: 40, 30, 20, 10, 0, -10, ...)
    • Add vy to y (ex: 40, 70, 90, 100, 100, 90, ...)
    • place the object at [x,y]

Also applicable to all kind of accelerations in x or y directions.

Framerate-independant 2D jumps

Use time instead of frames to make the animation. Demo: https://jsfiddle.net/subzey/p1ftrar0/

Minimal distance between a point and a line

  • line: a * x + b * y + c = 0
  • point: xA, yA
  • distance: d = Math.abs(a * xA + b * yA + c) / Math.sqrt(a * a + b * b)

Lerp (Blend / shortest path between two angles)

lerpDeg = function(start,end,amt){
	ver dif=end-start;
	dif = dif%360;
	if(dif>180.0)	{
		dif-=360.0;
	}
	else if (dif<-180.0)	{
		dif+=360.0;
	}
	return start+dif*amt;
}

3D

3D rotations

In order to create a 3d rotation, just take the idenity matrix:

vec3 (
    1, 0, 0,
    0, 1, 0,
    0, 0, 1
)

And fill in the sines and cosines:

vec3 (
    +cos(a), -sin(a), 0,
    +sin(a), +cos(a), 0,
     0     ,  0     , 1
) // Rotation in XY plane

vec3 (
    +cos(a), 0, -sin(a),
     0     , 1, 0      ,
    +sin(a), 0, +cos(a)
) // Rotation in XZ plane

vec3 (
    1,  0     ,  0     ,
    0, +cos(a), -sin(a),
    0, +sin(a), +cos(a)
) // Rotation in YZ plane

Rotation along X:

y' = y*cos(a) - z*sin(a)
z' = y*sin(a) + z*cos(a)
x' = x

Rotation along Y:

z' = z*cos(a) - x*sin(a)
x' = z*sin(a) + x*cos(a)
y' = y

Rotation along Z:

x' = x*cos(a) - y*sin(a)
y' = x*sin(a) + y*cos(a)
z' = z

3D Perspective Projection (draw a 3D point on a 2D canvas)

x' = x * fov / (z + viewer_distance) + half_screen_width
y' = -y * fov / (z + viewer_distance) + half_screen_height
(no z) 

Sphere trigonometry

http://bit.ly/bm1ftU

Great videos about linear algebra and matrices:

https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab

comp.graphics.algorithms's FAQ

ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers/graphics/algorithms-faq

Sweet! Thanks a ton!

zsumair commented Jul 18, 2016

Awesome... Thanks

Siorki commented Jul 19, 2016

Line thru 2 points should be a = (yB - yA) / (xB - xA) , not (yB - yA) / (yB - yA)

Owner

xem commented Aug 13, 2016

thanks @Siorki!

https://jsperf.com/hypotvstrigonometric/1
best perf using hypot than trigonometric to normalize vector

terkelg commented Oct 23, 2017

Nice gist!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment