File: test_616_plane.py

package info (click to toggle)
ezdxf 1.4.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 104,528 kB
  • sloc: python: 182,341; makefile: 116; lisp: 20; ansic: 4
file content (166 lines) | stat: -rw-r--r-- 5,049 bytes parent folder | download | duplicates (2)
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# Copyright (c) 2020, Manfred Moitzi
# License: MIT License
import pytest
from ezdxf.math import (
    Plane,
    Vec3,
    X_AXIS,
    BoundingBox,
    Z_AXIS,
    split_polygon_by_plane,
)
from ezdxf.render import forms


def test_init():
    p = Plane(Vec3(1, 0, 0), 5)
    assert p.normal == (1, 0, 0)
    assert p.distance_from_origin == 5


def test_init_form_3_colinear_points():
    with pytest.raises(ValueError):
        Plane.from_3p(Vec3(1, 0, 0), Vec3(1, 0, 0), Vec3(1, 0, 0))


def test_init_form_3p():
    p = Plane.from_3p(Vec3(5, 0, 0), Vec3(5, 1, 5), Vec3(5, 0, 1))


def test_equal():
    p1 = Plane.from_vector((5, 0, 0))
    p2 = Plane.from_vector((5, 0, 0))
    assert p1 is not p2
    assert p1 == p1


def test_init_form_vector():
    p = Plane.from_vector((5, 0, 0))
    assert p.normal == (1, 0, 0)
    assert p.distance_from_origin == 5

    with pytest.raises(ValueError):
        Plane.from_vector((0, 0, 0))


def test_signed_distance_to():
    p = Plane.from_vector((5, 0, 0))
    assert p.signed_distance_to(Vec3(10, 0, 0)) == 5
    assert p.signed_distance_to(Vec3(0, 0, 0)) == -5


def test_distance_to():
    p = Plane.from_vector((5, 0, 0))
    assert p.distance_to(Vec3(10, 0, 0)) == 5
    assert p.distance_to(Vec3(0, 0, 0)) == 5


def test_is_coplanar():
    p = Plane.from_vector((5, 0, 0))
    assert p.is_coplanar_vertex(Vec3(5, 5, 0)) is True
    assert p.is_coplanar_vertex(Vec3(5, 0, 5)) is True


def test_is_coplanar_plane():
    p1 = Plane.from_vector((5, 0, 0))
    p2 = Plane.from_vector((-1, 0, 0))
    assert p1.is_coplanar_plane(p2) is True


class TestSplitConvexPolygon:
    def test_spit_horizontal_square(self):
        polygon = forms.square(center=True)
        plane = Plane(X_AXIS, 0)
        front, back = split_polygon_by_plane(polygon, plane)
        assert len(front) == 4
        assert len(back) == 4
        front_bbox = BoundingBox(front)
        assert front_bbox.extmin == (0, -0.5)
        assert front_bbox.extmax == (0.5, 0.5)
        back_bbox = BoundingBox(back)
        assert back_bbox.extmin == (-0.5, -0.5)
        assert back_bbox.extmax == (0, 0.5)

    def test_ignore_coplanar_square(self):
        polygon = forms.square(center=True)
        plane = Plane(Z_AXIS, 0)
        front, back = split_polygon_by_plane(polygon, plane, coplanar=False)
        assert len(front) == 0
        assert len(back) == 0

    def test_return_coplanar_square_front(self):
        polygon = forms.square(center=True)
        plane = Plane(Z_AXIS, 0)
        front, back = split_polygon_by_plane(polygon, plane, coplanar=True)
        assert len(front) == 4
        assert len(back) == 0

    def test_return_coplanar_square_back(self):
        polygon = forms.square(center=True)
        plane = Plane(-Z_AXIS, 0)
        front, back = split_polygon_by_plane(polygon, plane, coplanar=True)
        assert len(front) == 0
        assert len(back) == 4


class TestIntersectLine:
    @pytest.fixture(scope="class")
    def plane(self):
        return Plane(Z_AXIS, 5)

    def test_intersection_line(self, plane):
        ip = plane.intersect_line(Vec3(0, 0, 0), Vec3(0, 0, 10))
        assert ip.isclose((0, 0, 5))

    def test_line_above_plane(self, plane):
        ip = plane.intersect_line(Vec3(0, 0, 6), Vec3(0, 0, 10))
        assert ip is None

    def test_line_below_plane(self, plane):
        ip = plane.intersect_line(Vec3(0, 0, 0), Vec3(0, 0, 4))
        assert ip is None

    def test_colinear_start_point_intersection(self, plane):
        ip = plane.intersect_line(Vec3(0, 0, 5), Vec3(0, 0, 10))
        assert ip.isclose((0, 0, 5))

    def test_ignore_coplanar_start_point_intersection(self, plane):
        ip = plane.intersect_line(Vec3(0, 0, 5), Vec3(0, 0, 10), coplanar=False)
        assert ip is None

    def test_colinear_end_point_intersection(self, plane):
        ip = plane.intersect_line(Vec3(0, 0, 0), Vec3(0, 0, 5))
        assert ip.isclose((0, 0, 5))

    def test_ignore_coplanar_end_point_intersection(self, plane):
        ip = plane.intersect_line(Vec3(0, 0, 0), Vec3(0, 0, 5), coplanar=False)
        assert ip is None

    def test_coplanar_line_has_no_intersection(self, plane):
        ip = plane.intersect_line(Vec3(0, 0, 5), Vec3(1, 0, 5), coplanar=True)
        assert ip is None
        ip = plane.intersect_line(Vec3(0, 0, 5), Vec3(1, 0, 5), coplanar=False)
        assert ip is None


class TestIntersectRay:
    @pytest.fixture(scope="class")
    def plane(self):
        return Plane(Z_AXIS, 5)

    def test_intersection_line(self, plane):
        ip = plane.intersect_ray(Vec3(0, 0, 0), Vec3(0, 0, 10))
        assert ip.isclose((0, 0, 5))

    def test_coplanar_ray_has_no_intersection(self, plane):
        ip = plane.intersect_ray(Vec3(0, 0, 0), Vec3(1, 0, 0))
        assert ip is None

    def test_plane_parallel_to_yz(self):
        plane = Plane(Vec3(1, 0, 0), 3)
        ip = plane.intersect_ray(Vec3(0, 0, 2), Vec3(1, 0, 0))
        assert ip.isclose((3, 0, 2))


if __name__ == "__main__":
    pytest.main([__file__])