Computing Intersection Point of Two Line Segments
1. Mathematical Foundation
Given two line segments defined by endpoints A(x1, y1), B(x2, y2) and C(x3, y3), D(x4, y4), we first treat each segment as an infinite line. The intersection of the two lines can be computed by solving the linear equations of the lines. If the intersection lies within the bounding ranges of both segments, the segments intersect.
Line Equation in Slope‑Intercept Form
y = m1 * x + b1 for AB
y = m2 * x + b2 for CD
where
m1 = (y2 - y1) / (x2 - x1) (if x2 ≠ x1)
b1 = y1 - m1 * x1
m2 = (y4 - y3) / (x4 - x3)
b2 = y3 - m2 * x3
If the lines are not parallel (m1 ≠ m2), the intersection coordinates are:
x0 = (b2 - b1) / (m1 - m2)
y0 = m1 * x0 + b1
For vertical lines (x constant), the slope is infinite and this approach fails. A more robust method uses the general line equation: a*x + b*y + c = 0.
General Linear Equation Approach
From two points (x1, y1) and (x2, y2), the coefficients are:
a = y2 - y1
b = x1 - x2
c = (x2 - x1) * y1 - (y2 - y1) * x1
The intersection (x0, y0) of two lines a1*x + b1*y + c1 = 0 and a2*x + b2*y + c2 = 0 is found using Cramer’s rule:
det = a1 * b2 - a2 * b1
x0 = (b1 * c2 - b2 * c1) / det
y0 = (c1 * a2 - c2 * a1) / det
If det = 0 the lines are parallel (including collinear).
2. Validating Segment Intersection
Once the intersection (x0, y0) is obtained, it lies on the segment if and only if:
(x0 - x1)*(x0 - x2) ≤ 0 AND (x0 - x3)*(x0 - x4) ≤ 0
(y0 - y1)*(y0 - y2) ≤ 0 AND (y0 - y3)*(y0 - y4) ≤ 0
Additionally, degenerate cases must be handled:
- If all four endpoints coincide → the segments are a single point.
- If one segment is a single point (start == end), check if that point lies on the other segment.
- If both segments are single points, they intersect only if they are the same point.
3. Java Implementation
The following Java class implements a clean, vector‑based method that avoids divition by zero and handles all common cases.
import java.awt.geom.Point2D;
public class SegmentIntersection {
/**
* Checks if two line segments intersect and computes the intersection point.
*
* @param p1 segment1 start
* @param p2 segment1 end
* @param p3 segment2 start
* @param p4 segment2 end
* @return IntersectionResult containing status and intersection point (if any)
*/
public static IntersectionResult compute(Point2D p1, Point2D p2,
Point2D p3, Point2D p4) {
double x1 = p1.getX(), y1 = p1.getY();
double x2 = p2.getX(), y2 = p2.getY();
double x3 = p3.getX(), y3 = p3.getY();
double x4 = p4.getX(), y4 = p4.getY();
// Check if any segment is a point
boolean seg1IsPoint = (x1 == x2 && y1 == y2);
boolean seg2IsPoint = (x3 == x4 && y3 == y4);
if (seg1IsPoint && seg2IsPoint) {
if (x1 == x3 && y1 == y3) {
return new IntersectionResult(true, new Point2D.Double(x1, y1),
"Both segments are the same point");
}
return new IntersectionResult(false, null, "Two different points");
}
// Compute coefficients of the infinite lines
double a1 = y2 - y1, b1 = x1 - x2, c1 = (x2 - x1) * y1 - (y2 - y1) * x1;
double a2 = y4 - y3, b2 = x3 - x4, c2 = (x4 - x3) * y3 - (y4 - y3) * x3;
double det = a1 * b2 - a2 * b1;
if (Math.abs(det) < 1e-12) { // parallel (including collinear)
// Additional check for collinear overlapping segments can be added
return new IntersectionResult(false, null, "Segments are parallel or collinear");
}
// Intersection of infinite lines
double x0 = (b1 * c2 - b2 * c1) / det;
double y0 = (c1 * a2 - c2 * a1) / det;
// Verify if intersection lies within both segments
boolean onSeg1 = isPointOnSegment(x0, y0, x1, y1, x2, y2);
boolean onSeg2 = isPointOnSegment(x0, y0, x3, y3, x4, y4);
if (onSeg1 && onSeg2) {
return new IntersectionResult(true, new Point2D.Double(x0, y0),
"Segments intersect");
} else {
return new IntersectionResult(false, null,
"Lines intersect but not within segments");
}
}
private static boolean isPointOnSegment(double px, double py,
double sx, double sy,
double ex, double ey) {
// Check bounding box (using tolerance for floating-point)
double eps = 1e-12;
boolean insideX = (px - sx) * (px - ex) <= eps;
boolean insideY = (py - sy) * (py - ey) <= eps;
return insideX && insideY;
}
// Helper class to hold result
public static class IntersectionResult {
private final boolean intersects;
private final Point2D point;
private final String description;
public IntersectionResult(boolean intersects, Point2D point, String desc) {
this.intersects = intersects;
this.point = point;
this.description = desc;
}
public boolean intersects() { return intersects; }
public Point2D getPoint() { return point; }
public String getDescription() { return description; }
}
// Example usage
public static void main(String[] args) {
Point2D a = new Point2D.Double(10, 20);
Point2D b = new Point2D.Double(100, 200);
Point2D c = new Point2D.Double(50, 20);
Point2D d = new Point2D.Double(20, 100);
IntersectionResult result = compute(a, b, c, d);
System.out.println(result.getDescription());
if (result.intersects()) {
System.out.printf("Intersection at (%.2f, %.2f)%n",
result.getPoint().getX(), result.getPoint().getY());
}
}
}
4. Output Verification
For the example points (10,20)–(100,200) and (50,20)–(20,100), the program outputs:
Segments intersect
Intersection at (32.86, 65.71)
The same result is obtained with the general equation method.