garmentiq.landmark.derivation.line_intersect

 1import numpy as np
 2from typing import Tuple, Optional
 3
 4
 5def _find_line_line_intersection(
 6    p1: Tuple[float, float],
 7    v1: Tuple[float, float],
 8    p2: Tuple[float, float],
 9    v2: Tuple[float, float],
10) -> Optional[Tuple[float, float]]:
11    """
12    Calculates the intersection point of two lines, each defined by a point and a direction vector.
13
14    Args:
15        p1 (Tuple[float, float]): A point (x1, y1) on the first line.
16        v1 (Tuple[float, float]): The direction vector (dx1, dy1) of the first line.
17        p2 (Tuple[float, float]): A point (x2, y2) on the second line.
18        v2 (Tuple[float, float]): The direction vector (dx2, dy2) of the second line.
19
20    Returns:
21        Optional[Tuple[float, float]]: The (x, y) coordinates of the intersection point,
22                                       or None if the lines are parallel or collinear (no unique intersection).
23    """
24    x1, y1 = p1
25    dx1, dy1 = v1
26    x2, y2 = p2
27    dx2, dy2 = v2
28
29    denominator = dx2 * dy1 - dy2 * dx1
30    if np.isclose(denominator, 0):  # Lines are parallel or collinear
31        return None
32
33    qp_x = x1 - x2
34    qp_y = y1 - y2
35    t = (qp_x * dy1 - qp_y * dx1) / denominator
36    ix = x2 + t * dx2
37    iy = y2 + t * dy2
38
39    return ix, iy