1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
# Copyright (c) 2010-2020, Manfred Moitzi
# License: MIT License
import pytest
import math
from ezdxf.math import ConstructionRay, ParallelRaysError, Vec3
HALF_PI = math.pi / 2.0
class TestConstructionRay:
def test_init_with_angle(self):
point = (10, 10)
ray = ConstructionRay(point, angle=0)
ray_normal = ray.orthogonal(point)
assert ray_normal._is_vertical is True
ray = ConstructionRay(point, angle=-HALF_PI)
assert ray._is_horizontal is False
assert ray._is_vertical is True
def test_Ray2D_get_x_y(self):
ray1 = ConstructionRay((10, 1), (20, 10))
y = ray1.yof(15)
assert math.isclose(y, 5.5)
assert math.isclose(ray1.xof(y), 15.0)
def test_ray2d_intersect(self):
ray1 = ConstructionRay((10, 1), (20, 10))
ray2 = ConstructionRay((17, -7), (-10, 3))
point = ray1.intersect(ray2)
assert point.isclose(Vec3(5.7434, -2.8309), abs_tol=1e-4)
assert ray1.is_parallel(ray2) is False
def test_ray2d_parallel(self):
ray1 = ConstructionRay((17, -8), (-10, 2))
ray2 = ConstructionRay((-10, 3), (17, -7))
ray3 = ConstructionRay((-10, 4), (17, -6))
assert ray2.is_parallel(ray3) is True
assert ray1.is_parallel(ray3) is True
with pytest.raises(ParallelRaysError):
_ = ray2.intersect(ray3)
def test_ray2d_intersect_with_vertical(self):
ray1 = ConstructionRay((10, 1), (10, -7))
ray2 = ConstructionRay((-10, 3), (17, -7))
point = ray1.intersect(ray2)
assert point.x == 10
assert point.isclose(Vec3(10.0, -4.4074), abs_tol=1e-4)
with pytest.raises(ArithmeticError):
_ = ray1.yof(1)
def test_ray2d_intersect_with_horizontal(self):
ray1 = ConstructionRay((-10, 10), (10, 10))
ray2 = ConstructionRay((-10, 20), (10, 0))
point = ray1.intersect(ray2)
assert point.y == 10
assert point.isclose(Vec3(0.0, 10.0), abs_tol=1e-4)
def test_ray2d_intersect_with_vertical_and_horizontal(self):
ray1 = ConstructionRay((-10, 10), (10, 10))
ray2 = ConstructionRay((5, 0), (5, 20))
point = ray1.intersect(ray2)
assert point.y == 10
assert point.x == 5
assert point.isclose(Vec3(5.0, 10.0), abs_tol=1e-4)
def test_ray2d_parallel_vertical(self):
ray1 = ConstructionRay((10, 1), (10, -7))
ray2 = ConstructionRay((11, 0), angle=HALF_PI)
ray3 = ConstructionRay((12, -10), (12, 7))
ray4 = ConstructionRay((0, 0), (1, 1))
ray5 = ConstructionRay((0, 0), angle=0)
with pytest.raises(ParallelRaysError):
_ = ray1.intersect(ray3)
assert ray1.is_parallel(ray3) is True
assert ray1.is_parallel(ray2) is True
assert ray2.is_parallel(ray2) is True
assert ray1.is_parallel(ray4) is False
assert ray2.is_parallel(ray4) is False
assert ray3.is_parallel(ray4) is False
assert ray1.is_parallel(ray5) is False
assert ray2.is_parallel(ray5) is False
assert ray3.is_parallel(ray5) is False
# vertical rays can't calc a y-value
with pytest.raises(ArithmeticError):
_ = ray1.yof(-1.0)
def test_ray2d_normal_vertical(self):
ray = ConstructionRay((10, 1), (10, -7)) # vertical line
ortho = ray.orthogonal((3, 3))
point = ray.intersect(ortho)
assert point.isclose(Vec3(10, 3))
def test_ray2d_normal(self):
ray = ConstructionRay((-10, 3), (17, -7))
ortho = ray.orthogonal((3, 3))
point = ray.intersect(ortho)
assert point.isclose(Vec3(1.4318, -1.234), abs_tol=1e-4)
def test_ray2d_normal_horizontal(self):
ray = ConstructionRay((10, 10), (20, 10)) # horizontal line
ortho = ray.orthogonal((3, 3))
point = ray.intersect(ortho)
assert point.isclose(Vec3(3, 10))
def test_ray2d_angle(self):
ray = ConstructionRay((10, 10), angle=HALF_PI)
assert ray._is_vertical is True
ray = ConstructionRay((10, 10), angle=0)
assert ray._is_horizontal is True
ray = ConstructionRay((10, 10), angle=math.pi / 4)
assert math.isclose(ray._slope, 1.0)
def test_bisectrix(self):
ray1 = ConstructionRay((10, 10), angle=math.pi / 3)
ray2 = ConstructionRay((3, -5), angle=math.pi / 2)
ray3 = ConstructionRay((1, 1), angle=math.pi / 3)
a = ray1.bisectrix(ray2)
assert math.isclose(a._angle, 1.309, abs_tol=1e-4)
assert math.isclose(a.yof(7), 12.80385, abs_tol=1e-4)
with pytest.raises(ParallelRaysError):
_ = ray1.bisectrix(ray3)
def test_two_close_horizontal_rays(self):
p1 = (39340.75302672016, 32489.73349764998)
p2 = (39037.75302672119, 32489.73349764978)
p3 = (38490.75302672015, 32489.73349764997)
ray1 = ConstructionRay(p1, p2)
ray2 = ConstructionRay(p2, p3)
assert ray1.is_horizontal is True
assert ray2.is_horizontal is True
assert ray1.is_parallel(ray2) is True
assert (
math.isclose(ray1.slope, ray2.slope) is False
), "Only slope testing is not sufficient"
|