3b1b/manim · error · Exception
Lines do not intersect
Error message
Lines do not intersect
What it means
Raised by line_intersection (utils/space_ops.py:286) when the determinant of the direction differences (div) is zero, i.e. the two lines are parallel (or collinear) so there is no unique intersection point. The 2D cross-product formulation degenerates and the function refuses to divide by zero.
Source
Thrown at manimlib/utils/space_ops.py:286
def line_intersection(
line1: Tuple[Vect3, Vect3],
line2: Tuple[Vect3, Vect3]
) -> Vect3:
"""
return intersection point of two lines,
each defined with a pair of vectors determining
the end points
"""
x_diff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0])
y_diff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1])
def det(a, b):
return a[0] * b[1] - a[1] * b[0]
div = det(x_diff, y_diff)
if div == 0:
raise Exception("Lines do not intersect")
d = (det(*line1), det(*line2))
x = det(d, x_diff) / div
y = det(d, y_diff) / div
return np.array([x, y, 0])
def find_intersection(
p0: Vect3 | Vect3Array,
v0: Vect3 | Vect3Array,
p1: Vect3 | Vect3Array,
v1: Vect3 | Vect3Array,
threshold: float = 1e-5,
) -> Vect3:
"""
Return the intersection of a line passing through p0 in direction v0
with one passing through p1 in direction v1. (Or array of intersections
from arrays of such points/directions).
View on GitHub (pinned to dee01804d4)
Solutions
- Check direction vectors first: if np.cross(v0, v1) == 0 (or below a tolerance), handle the parallel case explicitly instead of calling line_intersection
- Nudge one line's direction by a tiny epsilon only if approximate behavior is acceptable
- Prefer find_intersection(p0, v0, p1, v1) which handles 3D/segment cases with a threshold, when appropriate to your inputs
Example fix
# before
pt = line_intersection([a, b], [c, d]) # parallel -> raises
# after
v0, v1 = b - a, d - c
if abs(v0[0] * v1[1] - v0[1] * v1[0]) < 1e-9:
pt = None # parallel: no intersection
else:
pt = line_intersection([a, b], [c, d]) Defensive patterns
Strategy: validation
Validate before calling
def lines_intersect(l1, l2, tol=1e-9) -> bool:
d0 = (l1[1][0] - l1[0][0], l1[1][1] - l1[0][1])
d1 = (l2[1][0] - l2[0][0], l2[1][1] - l2[0][1])
return abs(d0[0] * d1[1] - d0[1] * d1[0]) > tol Try / catch
try:
pt = line_intersection(l1, l2)
except Exception:
pt = None # parallel or collinear lines Prevention
- Check the 2D cross product of direction vectors before calling line_intersection
- Handle parallel/collinear as an explicit case in geometry code
- Prefer find_intersection for 3D/segment workflows where applicable
When it happens
Trigger: line_intersection([p0, p0 + RIGHT], [p1, p1 + RIGHT]) with two horizontal lines; two segments sharing the same direction vector; numerically near-parallel lines where floating point rounds div to exactly 0.0.
Common situations: Computing intersections of grid lines or axes-aligned edges; geometry code assuming lines always cross; animations placing labels at line crossings that happen to be parallel in edge cases.
Related errors
- Unsupported: {path_verb}
- tip not found
- Cannot position endpoints of closed loop
- bezier cannot be calld on an empty list
- At least 2 mobjects needed for Union.
AI-assisted analysis of 3b1b/manim@dee01804d4 (2026-08-14).
Data as JSON: /api/errors/5ee178e0e25afe17.
Report an issue: GitHub.