Skip to main content

Basic Geometry

Analytical geometry treats each point r as the vector from the origin to that point. We stop distinguishing “point” from “vector” and build everything from a few linear operations.

This lesson follows CP-Algorithms — Basic Geometry.

Linear operations​

2D and 3D points form a vector space: you can add points and scale by a scalar. Coordinate type ftype is usually int, long long, or double.

using ftype = double;

struct point2d {
ftype x, y;
point2d() {}
point2d(ftype x, ftype y): x(x), y(y) {}
point2d& operator+=(const point2d &t) {
x += t.x; y += t.y; return *this;
}
point2d& operator-=(const point2d &t) {
x -= t.x; y -= t.y; return *this;
}
point2d& operator*=(ftype t) {
x *= t; y *= t; return *this;
}
point2d& operator/=(ftype t) {
x /= t; y /= t; return *this;
}
point2d operator+(const point2d &t) const { return point2d(*this) += t; }
point2d operator-(const point2d &t) const { return point2d(*this) -= t; }
point2d operator*(ftype t) const { return point2d(*this) *= t; }
point2d operator/(ftype t) const { return point2d(*this) /= t; }
};
point2d operator*(ftype a, point2d b) { return b * a; }

3D is the same idea with a z coordinate:

struct point3d {
ftype x, y, z;
point3d() {}
point3d(ftype x, ftype y, ftype z): x(x), y(y), z(z) {}
point3d& operator+=(const point3d &t) {
x += t.x; y += t.y; z += t.z; return *this;
}
point3d& operator-=(const point3d &t) {
x -= t.x; y -= t.y; z -= t.z; return *this;
}
point3d& operator*=(ftype t) {
x *= t; y *= t; z *= t; return *this;
}
point3d& operator/=(ftype t) {
x /= t; y /= t; z /= t; return *this;
}
point3d operator+(const point3d &t) const { return point3d(*this) += t; }
point3d operator-(const point3d &t) const { return point3d(*this) -= t; }
point3d operator*(ftype t) const { return point3d(*this) *= t; }
point3d operator/(ftype t) const { return point3d(*this) /= t; }
};
point3d operator*(ftype a, point3d b) { return b * a; }
🧪 Point arithmetic in C++

Dot product​

Definition​

The dot (scalar) product a · b has two matching stories:

  • Geometry: |a| · |b| · cos θ — length of a times the signed projection of b onto a.
  • Algebra: for a = (x₁, y₁, z₁) and b = (x₂, y₂, z₂),
a · b = x₁x₂ + y₁y₂ + z₁z₂

It is commutative and linear in each argument.

ftype dot(point2d a, point2d b) {
return a.x * b.x + a.y * b.y;
}
ftype dot(point3d a, point3d b) {
return a.x * b.x + a.y * b.y + a.z * b.z;
}

Compute with the algebraic formula; reason with the geometric one.

🧪 Dot product: angle & projection

Properties​

IdeaFormula
Squared length (norm)|a|² = a · a
Length|a| = √(a · a)
Projection of a onto b(a · b) / |b|
Angleacos((a · b) / (|a| |b|))
Sign> 0 acute, = 0 orthogonal, < 0 obtuse
ftype norm(point2d a) { return dot(a, a); }
double abs(point2d a) { return sqrt(norm(a)); }
double proj(point2d a, point2d b) { return dot(a, b) / abs(b); }
double angle(point2d a, point2d b) {
return acos(dot(a, b) / abs(a) / abs(b));
}

The level set { r | r · a = C } is a line in 2D (a plane in 3D) orthogonal to a. So a 2D line can be written r · n = C or (r − r₀) · n = 0 with normal n.

Interactive: see the products​

Drag nothing — pick presets. Dot mode draws the projection of b onto a. Cross mode shades the parallelogram whose signed area is the 2D cross product.

Check: dot product​

Quiz

Dot product

1 / 4

a · b equals zero when…

Pick an answer to see if you are right.

Cross product​

3D cross and triple product​

b × c is the vector orthogonal to both b and c, with length equal to the parallelogram area they span, oriented so that the turn from b to c looks counter-clockwise when viewed along b × c.

The triple product |a · (b × c)| is the parallelepiped volume. Coordinate form:

a × b = (a.y b.z − a.z b.y,
a.z b.x − a.x b.z,
a.x b.y − a.y b.x)

Notable facts:

  • a × b = −(b × a) (anti-commutative)
  • |a × b| = |a| |b| sin θ
  • a × b = 0 ⇔ a and b are collinear
  • a · (b × c) = 0 ⇔ a, b, c are coplanar
point3d cross(point3d a, point3d b) {
return point3d(a.y * b.z - a.z * b.y,
a.z * b.x - a.x * b.z,
a.x * b.y - a.y * b.x);
}
ftype triple(point3d a, point3d b, point3d c) {
return dot(a, cross(b, c));
}

2D pseudo-scalar (oriented area)​

In 2D we keep only the z-component of the 3D cross:

cross(a, b) = a.x * b.y − a.y * b.x

This equals |a| |b| sin θ with θ measured counter-clockwise from a to b. Sign:

  • > 0 → turn a → b is counter-clockwise (LEFT)
  • < 0 → clockwise (RIGHT)
  • = 0 → collinear (TOUCH)
ftype cross(point2d a, point2d b) {
return a.x * b.y - a.y * b.x;
}

Same primitive checks orientation of three points A → B → C:

cross(B − A, C − A)
🧪 Orientation & line intersection

Lines and planes​

ObjectEquation
Line through r₀ with direction d(r − r₀) × d = 0
Line through a and b(r − a) × (b − a) = 0
Plane through a,b,c(r − a) · ((b − a) × (c − a)) = 0

Line & plane intersection​

Two lines in 2D​

Parametrize the first line: r = a₁ + t · d₁. Require the second-line condition (r − a₂) × d₂ = 0:

t = cross(a₂ − a₁, d₂) / cross(d₁, d₂)
point2d intersect(point2d a1, point2d d1, point2d a2, point2d d2) {
return a1 + cross(a2 - a1, d2) / cross(d1, d2) * d1;
}

(Parallel lines → denominator 0; handle separately.)

Three planes in 3D​

Planes r · nᵢ = aᵢ · nᵢ. Solve with Cramer’s rule; the triple product is the determinant of the columns:

point3d intersect(point3d a1, point3d n1,
point3d a2, point3d n2,
point3d a3, point3d n3) {
point3d x(n1.x, n2.x, n3.x);
point3d y(n1.y, n2.y, n3.y);
point3d z(n1.z, n2.z, n3.z);
point3d d(dot(a1, n1), dot(a2, n2), dot(a3, n3));
return point3d(triple(d, y, z),
triple(x, d, z),
triple(x, y, d)) / triple(n1, n2, n3);
}

Check: cross product & orientation​

Quiz

Cross product

1 / 5

In 2D, cross(a, b) = a.x*b.y − a.y*b.x is…

Pick an answer to see if you are right.

Practice drills​

Implement the primitives. Starters compile but fail the tests until the formulas are correct.

Activity: Dot product

dot(ax, ay, bx, by) returns the 2D scalar product. Print one integer.

Contest problems​

Apply orientation and cross products on a real judge.

Point Location Test​

Judge: CSES — Point Location Test

A directed line through p1 → p2. For each query point p3, print whether it is LEFT, RIGHT, or TOUCH.

Up to 10⁵ tests with coordinates up to 10⁹ — use 64-bit integers for the cross product.

Sample

Input
3
1 1 5 3 2 3
1 1 5 3 4 1
1 1 5 3 3 2

Output
LEFT
RIGHT
TOUCH
Why this lesson?

Exactly the orientation drill: sign(cross(p2 − p1, p3 − p1)).

When to reach for which product​

QuestionTool
Length, angle, orthogonality, projectionDot
Oriented turn, parallelogram / polygon area2D cross
Normal to a plane, parallelepiped volume3D cross / triple
Line as “through point + direction”Cross equation
Line as “normal + offset”Dot equation

Previous: 0-1 BFS

Source: CP-Algorithms — Basic Geometry