Representations
| Form | Good for |
|---|---|
| Two points | input format, cross product tests |
| Point + direction | parametric queries, sweeps |
| solving systems, half-planes |
Converting from two points to the implicit form:
Intersecting two lines
Solve
by Cramer’s rule with :
bool lineIntersect(double A1,double B1,double C1, double A2,double B2,double C2, PD& out) {
double D = A1 * B2 - A2 * B1;
if (fabs(D) < EPS) return false; // parallel or identical
out.x = (C1 * B2 - C2 * B1) / D;
out.y = (A1 * C2 - A2 * C1) / D;
return true;
}is exactly the cross product of the two direction vectors, so means parallel.
The vector form — usually cleaner
Line 1 through with direction ; line 2 through with direction :
bool lineInter(P a, P b, P c, P d, PD& out) {
P u = b - a, v = d - c;
long long den = cross(u, v);
if (den == 0) return false; // parallel
double t = (double)cross(c - a, v) / den;
out = {a.x + u.x * t, a.y + u.y * t};
return true;
}den is exact in integers, so the parallel test is exact even though the intersection point is floating point. That separation — exact predicate, approximate construction — is the right pattern throughout geometry.
Parallel vs identical
if (cross(u, v) == 0) {
if (cross(u, c - a) == 0) return IDENTICAL; // c lies on line ab
else return PARALLEL;
}Segment intersection is a different problem
Two lines almost always meet; two segments usually do not. After computing (and the corresponding on the other segment), require . See Segment Intersection for the full case analysis including collinear overlap.
Related constructions
// perpendicular from p to line ab (the foot)
PD foot(P p, P a, P b) {
double t = (double)dot(p - a, b - a) / norm2(b - a);
return {a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t};
}
// perpendicular bisector of ab, as a point and a direction
PD midpoint = {(a.x + b.x) / 2.0, (a.y + b.y) / 2.0};
P dir = perp(b - a); // {-(b.y-a.y), b.x-a.x}| Construction | Method |
|---|---|
| Circumcentre of a triangle | intersect two perpendicular bisectors |
| Incentre | intersect two angle bisectors, or the weighted average |
| Orthocentre | intersect two altitudes |
| Centroid | |
| Reflection of across line | |
| Angle bisector direction at | normalise and , then add |
Numerical care
Nearly parallel lines
When is tiny but non-zero, the intersection point is enormous and its relative error is huge. If the algorithm then feeds that point into further computations, the error compounds badly.
Mitigations: keep the exact
crossfor all decisions and only construct the point when it is genuinely needed; scale coordinates so they are comparable in magnitude; uselong double.
Lines through many points
Detecting collinear triples among points: for each point, sort the others by angle around it and group equal directions — . Canonicalise each direction by dividing by the gcd and fixing the sign, so (2,4) and (-1,-2) compare equal:
pair<long long,long long> canonical(P d) {
long long g = __gcd(llabs(d.x), llabs(d.y));
if (g) { d.x /= g; d.y /= g; }
if (d.x < 0 || (d.x == 0 && d.y < 0)) { d.x = -d.x; d.y = -d.y; }
return {d.x, d.y};
}See also: Segment Intersection · Cross Product · Half-Plane Intersection