1
1
import platform
2
2
import re
3
+ from collections import namedtuple
3
4
4
5
import numpy as np
5
-
6
6
from numpy .testing import assert_array_equal
7
7
import pytest
8
8
@@ -88,25 +88,29 @@ def test_contains_points_negative_radius():
88
88
np .testing .assert_equal (result , [True , False , False ])
89
89
90
90
91
- _test_paths = [
91
+ _ExampleCurve = namedtuple ('_ExampleCurve' , ['path' , 'extents' , 'area' ])
92
+ _test_curves = [
92
93
# interior extrema determine extents and degenerate derivative
93
- Path ([[0 , 0 ], [1 , 0 ], [1 , 1 ], [0 , 1 ]],
94
- [Path .MOVETO , Path .CURVE4 , Path .CURVE4 , Path .CURVE4 ]),
95
- # a quadratic curve
96
- Path ([[0 , 0 ], [0 , 1 ], [1 , 0 ]], [Path .MOVETO , Path .CURVE3 , Path .CURVE3 ]),
94
+ _ExampleCurve (Path ([[0 , 0 ], [1 , 0 ], [1 , 1 ], [0 , 1 ]],
95
+ [Path .MOVETO , Path .CURVE4 , Path .CURVE4 , Path .CURVE4 ]),
96
+ extents = (0. , 0. , 0.75 , 1. ), area = 0.6 ),
97
+ # a quadratic curve, clockwise
98
+ _ExampleCurve (Path ([[0 , 0 ], [0 , 1 ], [1 , 0 ]],
99
+ [Path .MOVETO , Path .CURVE3 , Path .CURVE3 ]),
100
+ extents = (0. , 0. , 1. , 0.5 ), area = - 1 / 3 ),
97
101
# a linear curve, degenerate vertically
98
- Path ([[0 , 1 ], [1 , 1 ]], [Path .MOVETO , Path .LINETO ]),
102
+ _ExampleCurve (Path ([[0 , 1 ], [1 , 1 ]], [Path .MOVETO , Path .LINETO ]),
103
+ extents = (0. , 1. , 1. , 1. ), area = 0. ),
99
104
# a point
100
- Path ([[1 , 2 ]], [Path .MOVETO ]),
105
+ _ExampleCurve (Path ([[1 , 2 ]], [Path .MOVETO ]), extents = (1. , 2. , 1. , 2. ),
106
+ area = 0. ),
107
+ # non-curved triangle
108
+ _ExampleCurve (Path ([[1 , 1 ], [2 , 1 ], [1.5 , 2 ]]), extents = (1 , 1 , 2 , 2 ), area = 0.5 ),
101
109
]
102
110
103
111
104
- _test_path_extents = [(0. , 0. , 0.75 , 1. ), (0. , 0. , 1. , 0.5 ), (0. , 1. , 1. , 1. ),
105
- (1. , 2. , 1. , 2. )]
106
-
107
-
108
- @pytest .mark .parametrize ('path, extents' , zip (_test_paths , _test_path_extents ))
109
- def test_exact_extents (path , extents ):
112
+ @pytest .mark .parametrize ('precomputed_curve' , _test_curves )
113
+ def test_exact_extents (precomputed_curve ):
110
114
# notice that if we just looked at the control points to get the bounding
111
115
# box of each curve, we would get the wrong answers. For example, for
112
116
# hard_curve = Path([[0, 0], [1, 0], [1, 1], [0, 1]],
@@ -116,6 +120,7 @@ def test_exact_extents(path, extents):
116
120
# the way out to the control points.
117
121
# Note that counterintuitively, path.get_extents() returns a Bbox, so we
118
122
# have to get that Bbox's `.extents`.
123
+ path , extents = precomputed_curve .path , precomputed_curve .extents
119
124
assert np .all (path .get_extents ().extents == extents )
120
125
121
126
@@ -129,6 +134,28 @@ def test_extents_with_ignored_codes(ignored_code):
129
134
assert np .all (path .get_extents ().extents == (0. , 0. , 1. , 1. ))
130
135
131
136
137
+ @pytest .mark .parametrize ('precomputed_curve' , _test_curves )
138
+ def test_signed_area (precomputed_curve ):
139
+ path , area = precomputed_curve .path , precomputed_curve .area
140
+ np .testing .assert_allclose (path .signed_area (), area )
141
+ # now flip direction, sign of *signed_area* should flip
142
+ rcurve = Path (path .vertices [::- 1 ], path .codes )
143
+ np .testing .assert_allclose (rcurve .signed_area (), - area )
144
+
145
+
146
+ def test_signed_area_unit_rectangle ():
147
+ rect = Path .unit_rectangle ()
148
+ assert rect .signed_area () == 1
149
+
150
+
151
+ def test_signed_area_unit_circle ():
152
+ circ = Path .unit_circle ()
153
+ # Not a "real" circle, just an approximation of a circle made out of bezier
154
+ # curves. The actual value is 3.1415935732517166, which is close enough to
155
+ # pass here.
156
+ assert np .isclose (circ .signed_area (), np .pi )
157
+
158
+
132
159
def test_point_in_path_nan ():
133
160
box = np .array ([[0 , 0 ], [1 , 0 ], [1 , 1 ], [0 , 1 ], [0 , 0 ]])
134
161
p = Path (box )
0 commit comments