Point to point
long long dist2(P a, P b) { return norm2(a - b); } // exact, use for comparisons
double dist(P a, P b) { return sqrt((double)dist2(a, b)); }Point to line
double distToLine(P p, P a, P b) {
return fabs((double)cross(b - a, p - a)) / abs_(b - a);
}Point to segment
Project, clamp, measure:
double distToSegment(P p, P a, P b) {
if (a == b) return dist(p, a);
double t = (double)dot(p - a, b - a) / norm2(b - a);
t = max(0.0, min(1.0, t));
P proj{a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t};
return dist(p, proj);
}The clamp handles the case where the perpendicular foot falls outside the segment, in which case the nearest point is an endpoint.
Segment to segment
If they intersect, the distance is 0. Otherwise it is achieved at an endpoint:
double segToSeg(P a, P b, P c, P d) {
if (segmentsIntersect(a, b, c, d)) return 0;
return min({distToSegment(a, c, d), distToSegment(b, c, d),
distToSegment(c, a, b), distToSegment(d, a, b)});
}The intersection check first is essential — otherwise crossing segments report a positive distance.
Point to polygon
- Inside (test first) → distance 0, or the distance to the nearest edge if the problem wants the boundary.
- Outside → the minimum over all edges of
distToSegment. . - Convex polygon, many queries → binary search the angular sector, per query.
Circles
| Pair | Distance |
|---|---|
| Point to circle | (0 if on the circle) |
| Circle to circle (external) | , or 0 if |
| Circle inside circle | if nested |
| Line to circle | |
| Segment to circle |
Convex polygon to convex polygon
with rotating calipers, or via the Minkowski difference: the distance between two convex polygons equals the distance from the origin to , which is itself convex.
Other metrics
| Metric | Formula | Note |
|---|---|---|
| Euclidean () | the default | |
| Manhattan () | grid movement | |
| Chebyshev () | king moves | |
| Minkowski | interpolates |
The rotation trick
Rotating by 45° converts Manhattan distance into Chebyshev distance, which decouples the coordinates — so “maximum Manhattan distance among points” becomes in . See Manhattan Geometry.
In dimensions, the same idea gives over transformed coordinates.
Nearest-neighbour queries
| Situation | Method |
|---|---|
| One query, points | linear scan, |
| Many queries, static points | KD-tree, expected |
| Closest pair among | divide and conquer, |
| Nearest among points on a convex hull | rotating calipers |
| Nearest with insertions | Delaunay / Voronoi, or a rebuilt KD-tree |
| High dimensions | LSH / approximate |
Precision reminder
Compare squared distances wherever possible. Take the square root only for output, and print with enough precision (printf("%.10f") or cout << fixed << setprecision(10)).
See also: Geometry Basics · Manhattan Geometry · Closest Pair