Source code for MLV_toolbox.lineIntersection
from .VecLD import VecLD
import numpy as np
[docs]def lineIntersection(
queryLine: np.ndarray,
refLine: np.ndarray,
RE: float = 0.3,
AE: float = 2,
) -> np.ndarray:
"""
Determine if two line segments intersect and, if so, where.
Args:
queryLine (np.ndarray): A 2x2 array representing the query line segment
with start and end coordinates: [X1,Y1,X2,Y2].
refLine (np.ndarray): A 2x2 array representing the reference line
segment with start and end coordinates: [X1,Y1,X2,Y2].
RE (float): The relative error threshold for the intersection point.
Default is 0.3.
AE (float): The absolute error threshold for the intersection point in
pixels. Default is 2.
Returns:
Position (np.ndarray): A 2x1 array representing the intersection point
with coordinates: [X,Y]. If the lines do not intersect, Position
will be empty [].
"""
eps = 1e-4
Ay = queryLine[2] - queryLine[0]
Ax = queryLine[3] - queryLine[1]
By = refLine[2] - refLine[0]
Bx = refLine[3] - refLine[1]
Cy = refLine[0] - queryLine[0]
Cx = refLine[1] - queryLine[1]
D = Ay * Bx - Ax * By
np.seterr(divide='ignore', invalid='ignore') # divide by zero is okay here
a = (Bx * Cy - By * Cx) / D
b = (Ax * Cy - Ay * Cx) / D
# calculate ratio thresholds
at = min(RE, AE / np.max(np.abs([Ax, Ay])))
bt = min(RE, AE / np.max(np.abs([Bx, By])))
if (-at <= a) and (a <= 1 + at) and (-bt <= b) and (b <= 1 + bt):
# special cases where a or b are 0 or 1
if np.abs(a) < eps:
Position = queryLine[0:2]
elif np.abs(a - 1) < eps:
Position = queryLine[2:4]
elif np.abs(b) < eps:
Position = refLine[0:2]
elif np.abs(b - 1) < eps:
Position = refLine[2:4]
else:
# general case
A1 = queryLine[1] - queryLine[3]
B1 = queryLine[2] - queryLine[0]
C1 = queryLine[0] * queryLine[3] - queryLine[1] * queryLine[2]
A2 = refLine[1] - refLine[3]
B2 = refLine[2] - refLine[0]
C2 = refLine[0] * refLine[3] - refLine[1] * refLine[2]
D = A1 * B2 - A2 * B1
Position = np.zeros(2)
Position[0] = (B1 * C2 - B2 * C1) / D
Position[1] = (A2 * C1 - A1 * C2) / D
##### ALTERNATIVELY:
# general case
""" A = np.array([[queryLine[1] - queryLine[3], queryLine[2] - queryLine[0]],
[refLine[1] - refLine[3], refLine[2] - refLine[0]]])
B = np.array([queryLine[0] * queryLine[3] - queryLine[1] * queryLine[2],
refLine[0] * refLine[3] - refLine[1] * refLine[2]])
Position = np.linalg.solve(A, B) """
if np.any(Position < 0):
Position = []
else:
Position = []
setattr(VecLD, 'lineIntersection', lineIntersection)