// this is the general case. Really really general public static Vector2[] GetLineSegLineSegIntersectionInterval(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2) { // PointEqualsEpsilon is needed, or this for example falsely returns true: // MathUtil.CheckLineSegLineSegIntersection(new Vector2(-7.642176f, -3.406708f), new Vector2(-7.642176f, -3.406707f), new Vector2(0f, -3f), new Vector2(1f, -4f))); if (a1.PointEqualEpsilon(a2) && b1.PointEqualEpsilon(b2)) { // both "segments" are points, return either point if (a1.PointEqualEpsilon(b1)) return new Vector2[] { a1 }; else // both "segments" are different points, return empty set return new Vector2[] { }; } else if (b1.PointEqualEpsilon(b2)) // b is a point, a is a segment { if (PointOnLine(b1, a1, a2)) return new Vector2[] { b1 }; else return new Vector2[] { }; } else if (a1.PointEqualEpsilon(a2)) // a is a point, b is a segment { if (PointOnLine(a1, b1, b2)) return new Vector2[] { a1 }; else return new Vector2[] { }; } // at this point we know both a and b are actual segments float ua_t = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x); float ub_t = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x); float u_b = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y); // Infinite lines intersect somewhere if (!(-MyEpsilon < u_b && u_b < MyEpsilon)) // e.g. u_b != 0.0 { float ua = ua_t / u_b; float ub = ub_t / u_b; if (0.0f <= ua && ua <= 1.0f && 0.0f <= ub && ub <= 1.0f) { // Intersection return new Vector2[] { new Vector2(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y)) }; } else { // No Intersection return new Vector2[] { }; } } else // lines (not just segments) are parallel or the same line { // Coincident // find the common overlapping section of the lines // first find the distance (squared) from one point (a1) to each point if ((-MyEpsilon < ua_t && ua_t < MyEpsilon) || (-MyEpsilon < ub_t && ub_t < MyEpsilon)) { if (a1.Equals(a2)) // danger! return OneDIntersection(b1, b2, a1, a2); else // safe return OneDIntersection(a1, a2, b1, b2); } else { // Parallel return new Vector2[] { }; } } }