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 length

What the sign means

TaskTest
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

WantUse
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