예제 #1
0
def intersection_line_line_3d(
    line1: Sequence[Vec3],
    line2: Sequence[Vec3],
    virtual: bool = True,
    abs_tol: float = 1e-10,
) -> Optional[Vec3]:
    """
    Returns the intersection point of two 3D lines, returns ``None`` if lines
    do not intersect.

    Args:
        line1: first line as tuple of two points as :class:`Vec3` objects
        line2: second line as tuple of two points as :class:`Vec3` objects
        virtual: ``True`` returns any intersection point, ``False`` returns only
            real intersection points
        abs_tol: absolute tolerance for comparisons

    .. versionadded:: 0.17.2

    """
    from ezdxf.math import intersection_ray_ray_3d, BoundingBox
    res = intersection_ray_ray_3d(line1, line2, abs_tol)
    if len(res) != 1:
        return None

    point = res[0]
    if virtual:
        return point
    if BoundingBox(line1).inside(point) and BoundingBox(line2).inside(point):
        return point
    return None
예제 #2
0
def test_intersection_ray_ray_3d_random():
    for _ in range(5):
        intersection_point = Vec3.random(5)
        ray1 = (intersection_point, intersection_point + Vec3.random())
        ray2 = (intersection_point, intersection_point - Vec3.random())

        result = intersection_ray_ray_3d(ray1, ray2)
        assert len(result) == 1
        assert result[0].isclose(intersection_point)
예제 #3
0
 def test_not_intersecting_and_not_parallel_rays_return_two_tuple(
         self, ray1, ray2):
     line3 = (Vec3(0, 0, 1), Vec3(0, 1, 1))
     result = intersection_ray_ray_3d(ray1, line3)
     assert len(result) == 2
     assert bool(result) is True
     # returns points of closest approach on each ray
     assert Vec3(0, 0, 1) in result
     assert Vec3(0, 0, 0) in result
예제 #4
0
def test_intersection_ray_ray_3d():
    ray1 = (Vector(0, 0, 0), Vector(1, 0, 0))
    ray2 = (Vector(0, 0, 0), Vector(0, 0, 1))

    # parallel rays return a 0-tuple
    result = intersection_ray_ray_3d(ray1, ray1)
    assert len(result) == 0
    assert bool(result) is False

    # intersecting rays return a 1-tuple
    result = intersection_ray_ray_3d(ray1, ray2)
    assert len(result) == 1
    assert bool(result) is True
    assert result == (Vector(0, 0, 0), )

    # not intersecting and not parallel rays return a 2-tuple
    line3 = (Vector(0, 0, 1), Vector(0, 1, 1))
    result = intersection_ray_ray_3d(ray1, line3)
    assert len(result) == 2
    assert bool(result) is True
    # returns points of closest approach on each ray
    assert Vector(0, 0, 1) in result
    assert Vector(0, 0, 0) in result
예제 #5
0
def test_intersection_ray_ray_3d_2():
    ray1 = (Vec3(1, 0, 0), Vec3(1, 1, 0))
    ray2 = (Vec3(0, 0.5, 0), Vec3(1, 0.5, 0))
    result = intersection_ray_ray_3d(ray1, ray2)
    assert len(result) == 1
예제 #6
0
 def test_intersecting_rays_return_one_tuple(self, ray1, ray2):
     result = intersection_ray_ray_3d(ray1, ray2)
     assert len(result) == 1
     assert bool(result) is True
     assert result == (Vec3(0, 0, 0), )
예제 #7
0
 def test_parallel_rays_return_empty_tuple(self, ray1, ray2):
     result = intersection_ray_ray_3d(ray1, ray1)
     assert len(result) == 0
     assert bool(result) is False