Learning

Trigonometry for Games and Graphics · Reference

Unit Circle Reference

Landmark angles, exact coordinates, quadrant signs, and the circular-motion recipes, on one printable page.

Keep this open while you code. Everything here follows from one fact: the point at angle θ on a circle of radius 1 is (cos θ, sin θ).

Drag to look up any angle. Green is cos θ (the x-coordinate), orange is sin θ (the y).

Conversions

From → To Multiply by Approximately
degrees → radians π / 180 × 0.01745
radians → degrees 180 / π × 57.2958
turns → radians × 6.28319

Anchors worth memorising: 1 rad ≈ 57.3°, π ≈ 3.1416, 2π ≈ 6.2832.

Landmark angles

Radians Degrees cos θ (x) sin θ (y)
0 1 0
π/6 30° √3/2 ≈ 0.866 1/2 = 0.500
π/4 45° √2/2 ≈ 0.707 √2/2 ≈ 0.707
π/3 60° 1/2 = 0.500 √3/2 ≈ 0.866
π/2 90° 0 1
2π/3 120° −1/2 √3/2
3π/4 135° −√2/2 √2/2
5π/6 150° −√3/2 1/2
π 180° −1 0
7π/6 210° −√3/2 −1/2
5π/4 225° −√2/2 −√2/2
4π/3 240° −1/2 −√3/2
3π/2 270° 0 −1
5π/3 300° 1/2 −√3/2
7π/4 315° √2/2 −√2/2
11π/6 330° √3/2 −1/2
360° 1 0

The first quadrant is the only part worth memorising. Everything below 90° repeats in the other three quadrants with signs flipped, which the next table gives you.

Quadrant signs

Counterclockwise from the positive x-axis, with +y upward:

Quadrant Range cos θ sin θ
I 0° – 90° + +
II 90° – 180° +
III 180° – 270°
IV 270° – 360° +

Cosine is positive on the right half of the circle; sine is positive on the top half. That is easier to reconstruct than any mnemonic.

Bounds and identities

Recipes

Direction from an angle (a unit vector — pure direction, no speed):

dx, dy = math.cos(angle), math.sin(angle)

Move forward at a speed, frame-rate independent:

x = x + math.cos(angle) * speed * dt
y = y + math.sin(angle) * speed * dt

Orbit a centre at a radius:

x = cx + math.cos(angle) * radius
y = cy + math.sin(angle) * radius

Place n objects evenly around a full circle:

for i = 0, n - 1 do
  local a = i * (2 * math.pi) / n
  place(cx + math.cos(a) * radius, cy + math.sin(a) * radius)
end

Fan n projectiles across a total spread, centred on aim:

for i = 0, n - 1 do
  local a = aim + (i - (n - 1) / 2) * (spread / math.max(n - 1, 1))
  fire(math.cos(a), math.sin(a))
end

Traps checklist

When circular motion looks wrong, walk this list before debugging anything else:

  1. Degrees where radians belong. sin/cos always take radians. Raylib’s drawing calls take degrees; LÖVE’s rotate takes radians. A 57× speed error is this.
  2. y grows downward. On screen, increasing θ sweeps clockwise, not counterclockwise. The formula is unchanged; only your expectation is.
  3. cos and sin swapped. Mirrors everything across the 45° diagonal. Looks plausible, reads as “the controls feel off”.
  4. Speed baked into the direction. Keep (cos θ, sin θ) at length 1 and multiply by speed separately, or diagonal movement drifts faster than straight movement.
  5. Angle never wrapped. Fine for sin/cos, which repeat every 2π — but it breaks the moment you start comparing or interpolating angles.