Where the cross product measures turning, the dot product measures alignment.
long long dot(const P& a, const P& b) { return a.x * b.x + a.y * b.y; }
long long dot(const P& o, const P& a, const P& b) { return dot(a - o, b - o); }
long long norm2(const P& a) { return dot(a, a); } // squared lengthWhat the sign means
| Task | Test |
|---|---|
| Is the angle at in triangle obtuse? | |
| Is the triangle right-angled? | some |
| Is point within the “slab” of segment ? | and |
| Are two lines perpendicular? | direction dot |
| Is on ray (given collinear)? |
Projection
// closest point on the LINE through a,b to point p
double t = (double)dot(p - a, b - a) / norm2(b - a);
P closest = a + (b - a) * t;
// closest point on the SEGMENT: clamp
t = max(0.0, min(1.0, t));The clamp is the whole difference between line and segment. Distance from a point to a segment:
double distToSegment(P p, P a, P b) {
if (a == b) return abs_(p - a);
double t = (double)dot(p - a, b - a) / norm2(b - a);
t = max(0.0, min(1.0, t));
return abs_(p - (a + (b - a) * t));
}Squared distance — use it
long long dist2(P a, P b) { return norm2(a - b); }Exact in integers, no square root, and order-preserving. Use it for:
- comparing distances,
- “is this within radius ”: ,
- nearest-neighbour searches,
- closest pair.
Only take the square root when the problem asks for an actual length in the output.
Law of cosines
which is where the dot product’s geometric meaning comes from. Rearranged, it gives the angle:
double angle(P a, P b) { // angle between vectors, in [0, pi]
return atan2(fabs((double)cross(a,b)), (double)dot(a,b));
}Using atan2(|cross|, dot) is more numerically stable than acos(dot / (|a||b|)), which loses precision for angles near 0 and and can feed acos a value slightly outside . Prefer the atan2 form.
Dot and cross together
| Want | Use |
|---|---|
| Angle magnitude | |
| Signed angle | — gives |
| Perpendicular? | |
| Parallel? | |
| Which side? | sign of |
| In front or behind? | sign of |
The pair is exactly the complex number , which is why complex arithmetic works so smoothly for 2D geometry — see Vectors.
3D
The dot product is unchanged: . It still gives perpendicularity, projection and the angle. Only the cross product changes character (from scalar to vector) when moving to 3D.
See also: Cross Product · Vectors · Distances