File: test_653_polyline_intersection.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 (151 lines) | stat: -rw-r--r-- 5,655 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
#  Copyright (c) 2022, Manfred Moitzi
#  License: MIT License

import pytest
from ezdxf.math import (
    intersect_polylines_2d,
    intersect_polylines_3d,
    Vec2,
    Vec3,
    ConstructionEllipse,
    BSpline,
)
from ezdxf.render import forms


class TestIntersectPolylines2d:
    def test_intersecting_single_segments(self):
        pline1 = Vec2.list([(0, 1), (2, 1)])
        pline2 = Vec2.list([(1, 0), (1, 2)])
        res = intersect_polylines_2d(pline1, pline2)
        assert len(res) == 1
        assert res[0].isclose(Vec2(1, 1))

    def test_none_intersecting_single_segments(self):
        pline1 = Vec2.list([(0, 0), (2, 0)])
        pline2 = Vec2.list([(0, 1), (2, 1)])
        res = intersect_polylines_2d(pline1, pline2)
        assert len(res) == 0

    def test_intersecting_cross(self):
        pline1 = Vec2.list([(0, 1), (1, 1), (2, 1)])
        pline2 = Vec2.list([(1, 0), (1, 1), (1, 2)])
        res = intersect_polylines_2d(pline1, pline2)
        assert len(res) == 1
        assert res[0].isclose(Vec2(1, 1))

    def test_intersecting_x_cross(self):
        pline1 = Vec2.list([(0, 0), (1, 1), (2, 2)])
        pline2 = Vec2.list([(2, 0), (1, 1), (0, 2)])
        res = intersect_polylines_2d(pline1, pline2)
        assert len(res) == 1
        assert res[0].isclose(Vec2(1, 1))

    def test_intersecting_zig_zag_lines(self):
        pline1 = Vec2.list([(0, 0), (2, 2), (4, 0), (6, 2), (8, 0)])
        pline2 = Vec2.list([(0, 2), (2, 0), (4, 2), (6, 0), (8, 2)])
        res = intersect_polylines_2d(pline1, pline2)
        assert len(res) == 4
        res.sort()  # do not rely on any order
        assert res[0].isclose(Vec2(1, 1))
        assert res[1].isclose(Vec2(3, 1))
        assert res[2].isclose(Vec2(5, 1))
        assert res[3].isclose(Vec2(7, 1))

    def test_zig_zag_lines_with_common_vertices(self):
        pline1 = Vec2.list([(0, 0), (2, 2), (4, 0), (6, 2), (8, 0)])
        pline2 = Vec2.list([(0, 4), (2, 2), (4, 4), (6, 2), (8, 4)])
        res = intersect_polylines_2d(pline1, pline2)
        assert len(res) == 2
        res.sort()  # do not rely on any order
        assert res[0].isclose(Vec2(2, 2))
        assert res[1].isclose(Vec2(6, 2))

    def test_complex_ellipse_with_spline_intersection(self):
        ellipse = ConstructionEllipse(center=(0, 0), major_axis=(3, 0), ratio=0.5)
        bspline = BSpline([(-4, -4), (-2, -1), (2, 1), (4, 4)])
        p1 = ellipse.flattening(distance=0.01)
        p2 = bspline.flattening(distance=0.01)
        res = intersect_polylines_2d(Vec2.list(p1), Vec2.list(p2))
        assert len(res) == 2

    def test_intersecting_squares(self):
        square1 = forms.close_polygon(forms.square(2.0))
        square2 = forms.translate(square1, (1, 1))
        res = intersect_polylines_2d(Vec2.list(square1), Vec2.list(square2))
        assert len(res) == 2
        res.sort()
        assert res[0].isclose(Vec2(1, 2))
        assert res[1].isclose(Vec2(2, 1))

    def test_squares_with_common_corner_vertex(self):
        square1 = forms.close_polygon(forms.square(2.0))
        square2 = forms.translate(square1, (2, 2))
        res = intersect_polylines_2d(Vec2.list(square1), Vec2.list(square2))
        assert len(res) == 1
        assert res[0].isclose(Vec2(2, 2))

    def test_coincident_common_segment(self):
        """ The common segment does not create intersection points.
        Same as intersection of coincident lines!
        """
        pline1 = Vec2.list([(1, 1), (2, 1)])
        pline2 = Vec2.list([(1, 1), (2, 1)])
        res = intersect_polylines_2d(pline1, pline2)
        assert len(res) == 0

    def test_coincident_common_last_segment(self):
        """ The common segment does not create intersection points, but the
        preceding segment does.
        """
        pline1 = Vec2.list([(0, 0), (1, 1), (2, 1)])
        pline2 = Vec2.list([(0, 2), (1, 1), (2, 1)])
        res = intersect_polylines_2d(pline1, pline2)
        assert len(res) == 1
        assert res[0].isclose(Vec2(1, 1))

    def test_coincident_common_intermediate_segment(self):
        """ The common segment does not create intersection points, but the
        preceding and the following segment does.
        """
        pline1 = Vec2.list([(0, 0), (1, 1), (2, 1), (3, 0)])
        pline2 = Vec2.list([(0, 2), (1, 1), (2, 1), (3, 2)])
        res = intersect_polylines_2d(pline1, pline2)
        assert len(res) == 2
        res.sort()
        assert res[0].isclose(Vec2(1, 1))
        assert res[1].isclose(Vec2(2, 1))


class TestIntersectPolylines3d:
    """
    The 3D line intersection function is tested in test suite 614.

    The basic polyline intersection algorithm is tested in class TestIntersectPolylines2d.

    This class tests only if the function intersect_polylines_3d() is implemented.

    """
    def test_intersecting_single_segments(self):
        pline1 = Vec3.list([(0, 1), (2, 1)])
        pline2 = Vec3.list([(1, 0), (1, 2)])
        res = intersect_polylines_3d(pline1, pline2)
        assert len(res) == 1
        assert res[0].isclose(Vec3(1, 1))

    def test_intersecting_single_vertical_segment(self):
        pline1 = Vec3.list([(0, 0, 0), (2, 0, 0)])
        pline2 = Vec3.list([(1, 0, 0), (1, 0, 1)])
        res = intersect_polylines_3d(pline1, pline2)
        assert len(res) == 1
        assert res[0].isclose(Vec3(1, 0))

    def test_none_intersecting_single_segments(self):
        pline1 = Vec3.list([(0, 0), (2, 0)])
        pline2 = Vec3.list([(0, 1), (2, 1)])
        res = intersect_polylines_3d(pline1, pline2)
        assert len(res) == 0


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