File: test_632_bezier3p.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 (160 lines) | stat: -rw-r--r-- 3,894 bytes parent folder | download
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
#  Copyright (c) 2021, Manfred Moitzi
#  License: MIT License
import pytest
import pickle
from ezdxf.math import Vec3, Vec2, Matrix44, close_vectors

# Import from 'ezdxf.math._bezier3p' to test Python implementation
from ezdxf.math._bezier3p import Bezier3P
from ezdxf.acc import USE_C_EXT

curve_classes = [Bezier3P]
if USE_C_EXT:
    from ezdxf.acc.bezier3p import Bezier3P as CBezier3P

    curve_classes.append(CBezier3P)

DEFPOINTS2D = Vec2.list([(0.0, 0.0), (5.0, 5.0), (10.0, 0.0)])
DEFPOINTS3D = Vec3.list([(0.0, 0.0, 0.0), (50.0, 50.0, 50.0), (100.0, 0.0, 0.0)])


@pytest.fixture(params=curve_classes)
def bezier(request):
    return request.param


def test_accepts_2d_points(bezier):
    curve = bezier(DEFPOINTS2D)
    for index, chk in enumerate(Vec2.generate(POINTS2D)):
        assert curve.point(index * 0.1).isclose(chk)


def test_objects_are_immutable(bezier):
    curve = bezier(DEFPOINTS3D)
    with pytest.raises(TypeError):
        curve.control_points[0] = (1, 2, 3)


def test_approximate(bezier):
    curve = bezier(DEFPOINTS2D)
    with pytest.raises(ValueError):
        list(curve.approximate(0))
    assert list(curve.approximate(1)) == [DEFPOINTS2D[0], DEFPOINTS2D[-1]]
    assert list(curve.approximate(2)) == [
        POINTS2D[0],
        POINTS2D[5],
        POINTS2D[-1],
    ]


def test_first_derivative(bezier):
    dbcurve = bezier(DEFPOINTS2D)
    for index, chk in enumerate(Vec2.generate(TANGENTS2D)):
        assert dbcurve.tangent(index * 0.1).isclose(chk)


def test_reverse_points(bezier):
    curve = bezier(DEFPOINTS2D)
    vertices = list(curve.approximate(10))
    rev_curve = curve.reverse()
    rev_vertices = list(rev_curve.approximate(10))
    assert close_vectors(reversed(vertices), rev_vertices)


def test_transformation_interface(bezier):
    curve = bezier(DEFPOINTS3D)
    new = curve.transform(Matrix44.translate(1, 2, 3))
    assert new.control_points[0] == Vec3(DEFPOINTS3D[0]) + (1, 2, 3)
    assert (
        new.control_points[0] != curve.control_points[0]
    ), "expected a new object"


def test_transformation_returns_always_3d_curves(bezier):
    curve = bezier(DEFPOINTS2D)
    new = curve.transform(Matrix44.translate(1, 2, 3))
    assert len(new.control_points[0]) == 3


def test_flattening(bezier):
    curve = bezier(DEFPOINTS2D)
    assert len(list(curve.flattening(1.0, segments=4))) == 5
    assert len(list(curve.flattening(0.1, segments=4))) == 9


@pytest.mark.parametrize(
    "z",
    [
        1e99,
        1e79,
        1e59,
        1e39,
        1e19,
        1e9,
        1e6,
        1000,
        0,
        -1e99,
        -1e79,
        -1e59,
        -1e39,
        -1e19,
        -1e9,
        -1e6,
        -1000,
    ],
)
def test_flattening_big_z_coordinates(bezier, z):
    """Test based on issue #574"""
    cp = Vec3.list([
        (888, 770, z),
        (887, 623, z),
        (901, 478, z),
    ])
    curve = bezier(cp)
    points = list(curve.flattening(0.01))
    # Don't care about the result, it should just not break!
    assert len(points) > 0


def test_approximated_length(bezier):
    length = bezier(DEFPOINTS3D).approximated_length(64)
    assert length == pytest.approx(127.12269127455725)


def test_pickle_support(bezier):
    curve = bezier(DEFPOINTS3D)
    pickled_curve = pickle.loads(pickle.dumps(curve))
    for index in range(3):
        assert pickled_curve.control_points[index] == DEFPOINTS3D[index]


POINTS2D = [
    (0.0, 0.0),
    (1.0, 0.9),
    (2.0, 1.6),
    (3.0, 2.1),
    (4.0, 2.4),
    (5.0, 2.5),
    (6.0, 2.4),
    (7.0, 2.1),
    (8.0, 1.6),
    (9.00, 0.9),
    (10.0, 0.0),
]
TANGENTS2D = [
    (10.0, 10.0),
    (10.0, 8.0),
    (10.0, 6.0),
    (10.0, 4.0),
    (10.0, 2.0),
    (10.0, 0.0),
    (10.0, -2.0),
    (10.0, -4.0),
    (10.0, -6.0),
    (10.0, -8.0),
    (10.0, -10.0),
]

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