Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 70f0136

Browse files
authored
Merge pull request #8994 from QuLogic/fix-full-arc
Ensure that Path.arc works for any full circle.
2 parents e030bcd + e41d033 commit 70f0136

File tree

5 files changed

+83
-67
lines changed

5 files changed

+83
-67
lines changed

lib/matplotlib/path.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,10 @@ def arc(cls, theta1, theta2, n=None, is_wedge=False):
856856
Return an arc on the unit circle from angle
857857
*theta1* to angle *theta2* (in degrees).
858858
859+
*theta2* is unwrapped to produce the shortest arc within 360 degrees.
860+
That is, if *theta2* > *theta1* + 360, the arc will be from *theta1* to
861+
*theta2* - 360 and not a full circle plus some extra overlap.
862+
859863
If *n* is provided, it is the number of spline segments to make.
860864
If *n* is not provided, the number of spline segments is
861865
determined based on the delta between *theta1* and *theta2*.
@@ -864,14 +868,15 @@ def arc(cls, theta1, theta2, n=None, is_wedge=False):
864868
polylines, quadratic or cubic Bezier curves
865869
<http://www.spaceroots.org/documents/ellipse/index.html>`_.
866870
"""
867-
theta1, theta2 = np.deg2rad([theta1, theta2])
868-
869-
twopi = np.pi * 2.0
870871
halfpi = np.pi * 0.5
871872

872-
eta1 = np.arctan2(np.sin(theta1), np.cos(theta1))
873-
eta2 = np.arctan2(np.sin(theta2), np.cos(theta2))
874-
eta2 -= twopi * np.floor((eta2 - eta1) / twopi)
873+
eta1 = theta1
874+
eta2 = theta2 - 360 * np.floor((theta2 - theta1) / 360)
875+
# Ensure 2pi range is not flattened to 0 due to floating-point errors,
876+
# but don't try to expand existing 0 range.
877+
if theta2 != theta1 and eta2 <= eta1:
878+
eta2 += 360
879+
eta1, eta2 = np.deg2rad([eta1, eta2])
875880

876881
# number of curve segments to make
877882
if n is None:
@@ -930,6 +935,10 @@ def wedge(cls, theta1, theta2, n=None):
930935
Return a wedge of the unit circle from angle
931936
*theta1* to angle *theta2* (in degrees).
932937
938+
*theta2* is unwrapped to produce the shortest wedge within 360 degrees.
939+
That is, if *theta2* > *theta1* + 360, the wedge will be from *theta1*
940+
to *theta2* - 360 and not a full circle plus some extra overlap.
941+
933942
If *n* is provided, it is the number of spline segments to make.
934943
If *n* is not provided, the number of spline segments is
935944
determined based on the delta between *theta1* and *theta2*.
Binary file not shown.

lib/matplotlib/tests/baseline_images/test_patches/wedge_range.svg

Lines changed: 56 additions & 61 deletions
Loading

lib/matplotlib/tests/test_path.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,15 @@ def test_path_deepcopy():
205205
path2 = Path(verts, codes)
206206
copy.deepcopy(path1)
207207
copy.deepcopy(path2)
208+
209+
210+
@pytest.mark.parametrize('offset', range(-720, 361, 45))
211+
def test_full_arc(offset):
212+
low = offset
213+
high = 360 + offset
214+
215+
path = Path.arc(low, high)
216+
mins = np.min(path.vertices, axis=0)
217+
maxs = np.max(path.vertices, axis=0)
218+
np.testing.assert_allclose(mins, -1)
219+
assert np.allclose(maxs, 1)

0 commit comments

Comments
 (0)