# -*- coding: utf-8 -*-
#
# This file is subject to the terms and conditions defined in
# file 'LICENSE.txt', which is part of this source code package.
#
from typing import Tuple
import numpy as np
from Muscat.Types import ArrayLike
[docs]def SegmentIntersection(P0: ArrayLike, P1: ArrayLike, Px: ArrayLike, Py: ArrayLike)-> Tuple[np.ndarray]:
"""function to compute the intersection of 2 lines
if no intersection then an empty tuple is returned
if the second line is colinear to the first, return the point of the second line inside the first line
Parameters
----------
P0 : ArrayLike
first point defining the first line
P1 : ArrayLike
second point defining the first line
Px : ArrayLike
first point defining the second line
Py : ArrayLike
second point defining the second line
Returns
-------
tuple[np.ndarray]
a tuple containing the intersection points
"""
P0 = np.asarray(P0)
P1 = np.asarray(P1)
Px = np.asarray(Px)
Py = np.asarray(Py)
p = P0
r = P1 - p
q = Px
s = Py - q
cross1 = np.cross(r, s)
cross2 = np.cross(p - q, r)
if cross1 == 0 and cross2 == 0:
t0 = (q - p).dot(r) / r.dot(r)
t1 = (q + s - p).dot(r) / r.dot(r)
if t0 > 0 and t0 < 1:
if t1 >= 0 and t1 <= 1:
return (p + t0 * r, p + t1 * r)
else:
return (p + t0 * r,)
else:
if t1 >= 0 and t1 <= 1:
return (p + t1 * r,)
else:
return tuple()
elif cross1 == 0 and cross2 != 0:
return tuple()
t = np.cross(q - p, s) / cross1
u = cross2 / np.cross(s, r)
if cross1 != 0 and t >= 0 and t <= 1 and u >= 0 and u <= 1:
return (p + t * r,)
else:
return tuple()
[docs]def CheckIntegrity(GUI: bool = False):
P0 = [0, 0] # No intersect
P1 = [2, 8]
Px = [8, 0]
Py = [0, 20]
np.testing.assert_equal(SegmentIntersection(P0, P1, Px, Py), ())
P0 = [0, 10] # Intersect
P1 = [2, 0]
Px = [10, 0]
Py = [0, 5]
np.testing.assert_equal(SegmentIntersection(P0, P1, Px, Py), ((np.array([10 / 9, 40 / 9]),)))
P0 = [0, 0] # Parallel, vertical
P1 = [0, 10]
Px = [2, 0]
Py = [2, 10]
np.testing.assert_equal(SegmentIntersection(P0, P1, Px, Py), ())
P0 = [0, 0] # Parallel, diagonal
P1 = [5, 5]
Px = [2, 0]
Py = [7, 5]
np.testing.assert_equal(SegmentIntersection(P0, P1, Px, Py), ())
P0 = [0, 0] # Collinear, overlap
P1 = [5, 5]
Px = [2, 2]
Py = [7, 7]
np.testing.assert_equal(SegmentIntersection(P0, P1, Px, Py), (np.array([2, 2]),))
P0 = [0, 0] # Collinear, full overlap
P1 = [5, 5]
Px = [2, 2]
Py = [4, 4]
np.testing.assert_equal(SegmentIntersection(P0, P1, Px, Py), (np.array([2, 2]), np.array([4, 4])))
P0 = [0, 0] # Collinear, overlap (opposite directions)
P1 = [5, 5]
Px = [7, 7]
Py = [2, 2]
np.testing.assert_equal(SegmentIntersection(P0, P1, Px, Py), (np.array([2, 2]),))
P0 = [0, 0] # Collinear, no overlap
P1 = [5, 5]
Px = [7, 7]
Py = [10, 10]
np.testing.assert_equal(SegmentIntersection(P0, P1, Px, Py), ())
return "ok"
if __name__ == "__main__": # pragma: no cover
print(CheckIntegrity(GUI=True))