Notes

Thoughts, write-ups, and things worth remembering.

Dot product

#math#graphics Updated Sep 17, 2026

a·b = |a||b|cos(theta). Measures how aligned two vectors are, not distance, not area.

Math

a⃗⋅b⃗=∣a⃗∣∣b⃗∣cos⁡θ=axbx+ayby+azbz\vec{a} \cdot \vec{b} = |\vec{a}||\vec{b}|\cos\theta = a_x b_x + a_y b_y + a_z b_z

Geometric meaning: a⃗⋅b⃗\vec{a} \cdot \vec{b} is ∣a⃗∣|\vec{a}| times the signed length of b⃗\vec{b}‘s projection onto a⃗\vec{a}‘s direction (or symmetrically the other way). If a⃗\vec{a} is a unit vector, a⃗⋅b⃗\vec{a} \cdot \vec{b} IS that signed projection length directly.

What the result means:

  • Sign only, direction-agnostic magnitude aside: a⃗⋅b⃗>0⇒θ<90°\vec{a} \cdot \vec{b} > 0 \Rightarrow \theta < 90°, =0⇒= 0 \Rightarrow perpendicular, <0⇒θ>90°< 0 \Rightarrow \theta > 90°
  • Full angle if you need it (expensive, avoid unless necessary): θ=arccos⁡(a⃗⋅b⃗∣a⃗∣∣b⃗∣)\theta = \arccos\left(\frac{\vec{a}\cdot\vec{b}}{|\vec{a}||\vec{b}|}\right)
  • If both vectors are unit length, the dot product is bounded to [−1,1][-1, 1] and directly equals cos⁡θ\cos\theta

Code

float dot = glm::dot(a, b);
float projLength = glm::dot(a, glm::normalize(b));  // scalar projection of a onto b

Uses in graphics

  • Back-face culling — sign of N·V
  • Diffuse (Lambertian) lighting: intensity ∝ max(0, N·L)
  • Specular highlights (Blinn-Phong): N·H term
  • Which side of a plane a point is on: sign of planeNormal · (point - planePoint)
  • Camera frustum / visibility checks: dot(cameraForward, dirToObject) to reject anything behind the camera
  • Closest point on a line/ray to another point (scalar projection)

Gotchas

  • Dot product alone can’t tell you the exact angle, only which side of 90° you’re on — use the sign, don’t reach for acos unless you actually need the number.
  • Only equals cos(theta) directly when both vectors are normalized; otherwise it’s scaled by both magnitudes, don’t forget to divide if you need the pure angle relationship.