17.1 Points and Vectors
You need a mathematical representation for locations, directions, distances, and geometric relationships.
17.1 Points and Vectors
Problem
You need a mathematical representation for locations, directions, distances, and geometric relationships. Nearly every computational geometry algorithm depends on a small set of operations involving points and vectors. Before implementing line intersections, convex hulls, closest-pair searches, or polygon algorithms, you must understand how points and vectors are represented and manipulated.
Solution
Represent a point as a coordinate in space and represent a vector as a displacement between two points.
In two-dimensional geometry:
Point A = (2, 3)
Point B = (7, 5)
The vector from A to B is:
AB = B - A
= (7 - 2, 5 - 3)
= (5, 2)
A point represents a position.
A vector represents a direction and magnitude.
Although they may share the same coordinate representation in code, they serve different conceptual purposes.
A common implementation is:
from dataclasses import dataclass
from math import sqrt
@dataclass
class Point:
x: float
y: float
@dataclass
class Vector:
x: float
y: float
Basic vector operations:
def add(a: Vector, b: Vector) -> Vector:
return Vector(a.x + b.x, a.y + b.y)
def subtract(a: Vector, b: Vector) -> Vector:
return Vector(a.x - b.x, a.y - b.y)
def multiply(v: Vector, k: float) -> Vector:
return Vector(v.x * k, v.y * k)
Creating a vector from two points:
def vector_between(a: Point, b: Point) -> Vector:
return Vector(b.x - a.x, b.y - a.y)
Understanding Vector Length
The length of a vector measures its magnitude.
For vector:
v = (x, y)
the length is:
genui{"math_block_widget_always_prefetch_v2":{"content":"\sqrt{x^2+y^2}"}}
Example:
v = (3, 4)
Length:
sqrt(3² + 4²)
= sqrt(9 + 16)
= sqrt(25)
= 5
Implementation:
def length(v: Vector) -> float:
return sqrt(v.x * v.x + v.y * v.y)
Computing square roots is relatively expensive. Many algorithms compare squared distances instead.
def length_squared(v: Vector) -> float:
return v.x * v.x + v.y * v.y
This technique appears frequently in nearest-neighbor searches and closest-pair algorithms.
Dot Product
The dot product measures alignment between vectors.
For vectors:
a = (ax, ay)
b = (bx, by)
the dot product is:
a · b = axbx + ayby
Implementation:
def dot(a: Vector, b: Vector) -> float:
return a.x * b.x + a.y * b.y
Example:
a = (3, 4)
b = (5, 2)
a · b
= 3×5 + 4×2
= 15 + 8
= 23
Applications include:
- Angle computation
- Projection
- Orthogonality testing
- Distance to lines
- Closest-point problems
Two vectors are perpendicular when:
a · b = 0
Example:
(1, 0) · (0, 1) = 0
Cross Product in Two Dimensions
The three-dimensional cross product produces a vector.
In computational geometry, the two-dimensional cross product is commonly represented by a scalar:
cross(a, b)
=
axby − aybx
Implementation:
def cross(a: Vector, b: Vector) -> float:
return a.x * b.y - a.y * b.x
Example:
a = (4, 0)
b = (2, 3)
cross(a, b)
=
4×3 − 0×2
=
12
The sign of the result contains important geometric information.
| Result | Meaning |
|---|---|
| Positive | Counterclockwise turn |
| Negative | Clockwise turn |
| Zero | Collinear |
This operation forms the foundation of orientation testing, convex hull algorithms, segment intersection detection, polygon area computation, and many sweep-line algorithms.
Distance Between Points
Given points:
A = (x1, y1)
B = (x2, y2)
Distance is computed from the vector:
AB = (x2 − x1, y2 − y1)
and then:
def distance(a: Point, b: Point) -> float:
dx = b.x - a.x
dy = b.y - a.y
return sqrt(dx * dx + dy * dy)
For large-scale geometric algorithms, squared distance is often preferred:
def distance_squared(a: Point, b: Point) -> float:
dx = b.x - a.x
dy = b.y - a.y
return dx * dx + dy * dy
Vector Normalization
Many algorithms require a unit vector whose length equals one.
Given vector:
v = (x, y)
normalize by dividing each coordinate by the vector length:
def normalize(v: Vector) -> Vector:
l = length(v)
return Vector(v.x / l, v.y / l)
Example:
(3, 4)
becomes:
(0.6, 0.8)
Normalization is widely used in graphics, physics simulation, and motion planning.
Translation
Adding a vector to a point moves the point.
Example:
Point P = (2, 5)
Vector v = (4, -1)
Result:
(6, 4)
Implementation:
def translate(p: Point, v: Vector) -> Point:
return Point(
p.x + v.x,
p.y + v.y
)
Many geometric transformations are built from repeated applications of translation.
Common Pitfalls
Confusing Points and Vectors
The representation may be identical in memory, but their meanings differ.
Point = location
Vector = displacement
Keeping separate types often prevents logical errors.
Using Floating Point Equality
Avoid:
a == b
for geometric calculations.
Instead:
EPS = 1e-9
abs(a - b) < EPS
Computing Square Roots Unnecessarily
When only comparisons are needed:
d1 < d2
compare squared distances instead.
d1² < d2²
This avoids expensive square root operations.
Ignoring Overflow
When coordinates are large:
x² + y²
may overflow integer types.
Use sufficiently large numeric representations.
Discussion
Points and vectors form the alphabet of computational geometry. Every major algorithm in this chapter eventually reduces to a sequence of vector additions, dot products, cross products, and distance calculations. Convex hull construction depends on cross products. Closest-pair algorithms depend on distance computations. Polygon algorithms depend on orientation tests derived from vectors. Sweep-line methods repeatedly evaluate geometric predicates built from these primitive operations.
A strong understanding of points and vectors simplifies every subsequent topic. Once these operations become familiar, more advanced geometric algorithms often appear as elegant combinations of a surprisingly small set of basic tools.