|
7 | 7 | import numpy as np
|
8 | 8 |
|
9 | 9 | import matplotlib.cbook as cbook
|
10 |
| -from matplotlib.path import Path |
11 | 10 |
|
12 | 11 |
|
13 | 12 | class NonIntersectingPathException(ValueError):
|
14 | 13 | pass
|
15 | 14 |
|
| 15 | + |
16 | 16 | # some functions
|
17 | 17 |
|
18 | 18 |
|
@@ -68,6 +68,54 @@ def get_normal_points(cx, cy, cos_t, sin_t, length):
|
68 | 68 | return x1, y1, x2, y2
|
69 | 69 |
|
70 | 70 |
|
| 71 | +# deprecated routines (moved to `.Path`) |
| 72 | + |
| 73 | + |
| 74 | +@cbook.deprecated("3.3") |
| 75 | +def inside_circle(cx, cy, r): |
| 76 | + """ |
| 77 | + Return a function that checks whether a point is in a circle with center |
| 78 | + (*cx*, *cy*) and radius *r*. |
| 79 | +
|
| 80 | + The returned function has the signature:: |
| 81 | +
|
| 82 | + f(xy: Tuple[float, float]) -> bool |
| 83 | + """ |
| 84 | + r2 = r ** 2 |
| 85 | + |
| 86 | + def _f(xy): |
| 87 | + x, y = xy |
| 88 | + return (x - cx) ** 2 + (y - cy) ** 2 < r2 |
| 89 | + return _f |
| 90 | + |
| 91 | + |
| 92 | +@cbook.deprecated("3.3", alternative="Path.make_compound_path()") |
| 93 | +def split_path_inout(path, inside, tolerance=0.01, reorder_inout=False): |
| 94 | + """ |
| 95 | + Divide a path into two segments at the point where ``inside(x, y)`` |
| 96 | + becomes False. |
| 97 | + """ |
| 98 | + return path.split_path_inout(inside, tolerance, reorder_inout) |
| 99 | + |
| 100 | + |
| 101 | +@cbook.deprecated( |
| 102 | + "3.3", alternative="Path.cleaned() and remove the final STOP if needed") |
| 103 | +def make_path_regular(path): |
| 104 | + """ |
| 105 | + If the ``codes`` attribute of `.Path` *p* is None, return a copy of *p* |
| 106 | + with ``codes`` set to (MOVETO, LINETO, LINETO, ..., LINETO); otherwise |
| 107 | + return *p* itself. |
| 108 | + """ |
| 109 | + return path.make_path_regular() |
| 110 | + |
| 111 | + |
| 112 | +@cbook.deprecated("3.3", alternative="Path.make_compound_path()") |
| 113 | +def concatenate_paths(paths): |
| 114 | + """Concatenate a list of paths into a single path.""" |
| 115 | + from .path import Path |
| 116 | + return Path.make_compound_path(*paths) |
| 117 | + |
| 118 | + |
71 | 119 | # BEZIER routines
|
72 | 120 |
|
73 | 121 | # subdividing bezier curve
|
@@ -177,12 +225,13 @@ class BezierSegment:
|
177 | 225 | """
|
178 | 226 |
|
179 | 227 | def __init__(self, control_points):
|
180 |
| - n = len(control_points) |
181 |
| - self._orders = np.arange(n) |
182 |
| - coeff = [math.factorial(n - 1) |
183 |
| - // (math.factorial(i) * math.factorial(n - 1 - i)) |
184 |
| - for i in range(n)] |
185 |
| - self._px = np.asarray(control_points).T * coeff |
| 228 | + self.cpoints = np.asarray(control_points) |
| 229 | + self.n, self.d = self.cpoints.shape |
| 230 | + self._orders = np.arange(self.n) |
| 231 | + coeff = [math.factorial(self.n - 1) |
| 232 | + // (math.factorial(i) * math.factorial(self.n - 1 - i)) |
| 233 | + for i in range(self.n)] |
| 234 | + self._px = self.cpoints.T * coeff |
186 | 235 |
|
187 | 236 | def point_at_t(self, t):
|
188 | 237 | """Return the point on the Bezier curve for parameter *t*."""
|
@@ -222,90 +271,9 @@ def split_bezier_intersecting_with_closedpath(
|
222 | 271 | return _left, _right
|
223 | 272 |
|
224 | 273 |
|
225 |
| -# matplotlib specific |
226 |
| - |
227 |
| - |
228 |
| -def split_path_inout(path, inside, tolerance=0.01, reorder_inout=False): |
229 |
| - """ |
230 |
| - Divide a path into two segments at the point where ``inside(x, y)`` becomes |
231 |
| - False. |
232 |
| - """ |
233 |
| - path_iter = path.iter_segments() |
234 |
| - |
235 |
| - ctl_points, command = next(path_iter) |
236 |
| - begin_inside = inside(ctl_points[-2:]) # true if begin point is inside |
237 |
| - |
238 |
| - ctl_points_old = ctl_points |
239 |
| - |
240 |
| - concat = np.concatenate |
241 |
| - |
242 |
| - iold = 0 |
243 |
| - i = 1 |
244 |
| - |
245 |
| - for ctl_points, command in path_iter: |
246 |
| - iold = i |
247 |
| - i += len(ctl_points) // 2 |
248 |
| - if inside(ctl_points[-2:]) != begin_inside: |
249 |
| - bezier_path = concat([ctl_points_old[-2:], ctl_points]) |
250 |
| - break |
251 |
| - ctl_points_old = ctl_points |
252 |
| - else: |
253 |
| - raise ValueError("The path does not intersect with the patch") |
254 |
| - |
255 |
| - bp = bezier_path.reshape((-1, 2)) |
256 |
| - left, right = split_bezier_intersecting_with_closedpath( |
257 |
| - bp, inside, tolerance) |
258 |
| - if len(left) == 2: |
259 |
| - codes_left = [Path.LINETO] |
260 |
| - codes_right = [Path.MOVETO, Path.LINETO] |
261 |
| - elif len(left) == 3: |
262 |
| - codes_left = [Path.CURVE3, Path.CURVE3] |
263 |
| - codes_right = [Path.MOVETO, Path.CURVE3, Path.CURVE3] |
264 |
| - elif len(left) == 4: |
265 |
| - codes_left = [Path.CURVE4, Path.CURVE4, Path.CURVE4] |
266 |
| - codes_right = [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4] |
267 |
| - else: |
268 |
| - raise AssertionError("This should never be reached") |
269 |
| - |
270 |
| - verts_left = left[1:] |
271 |
| - verts_right = right[:] |
272 |
| - |
273 |
| - if path.codes is None: |
274 |
| - path_in = Path(concat([path.vertices[:i], verts_left])) |
275 |
| - path_out = Path(concat([verts_right, path.vertices[i:]])) |
276 |
| - |
277 |
| - else: |
278 |
| - path_in = Path(concat([path.vertices[:iold], verts_left]), |
279 |
| - concat([path.codes[:iold], codes_left])) |
280 |
| - |
281 |
| - path_out = Path(concat([verts_right, path.vertices[i:]]), |
282 |
| - concat([codes_right, path.codes[i:]])) |
283 |
| - |
284 |
| - if reorder_inout and not begin_inside: |
285 |
| - path_in, path_out = path_out, path_in |
286 |
| - |
287 |
| - return path_in, path_out |
288 |
| - |
289 |
| - |
290 |
| -def inside_circle(cx, cy, r): |
291 |
| - """ |
292 |
| - Return a function that checks whether a point is in a circle with center |
293 |
| - (*cx*, *cy*) and radius *r*. |
294 |
| -
|
295 |
| - The returned function has the signature:: |
296 |
| -
|
297 |
| - f(xy: Tuple[float, float]) -> bool |
298 |
| - """ |
299 |
| - r2 = r ** 2 |
300 |
| - |
301 |
| - def _f(xy): |
302 |
| - x, y = xy |
303 |
| - return (x - cx) ** 2 + (y - cy) ** 2 < r2 |
304 |
| - return _f |
305 |
| - |
306 |
| - |
307 | 274 | # quadratic Bezier lines
|
308 | 275 |
|
| 276 | + |
309 | 277 | def get_cos_sin(x0, y0, x1, y1):
|
310 | 278 | dx, dy = x1 - x0, y1 - y0
|
311 | 279 | d = (dx * dx + dy * dy) ** .5
|
@@ -478,25 +446,3 @@ def make_wedged_bezier2(bezier2, width, w1=1., wm=0.5, w2=0.):
|
478 | 446 | c3x_right, c3y_right)
|
479 | 447 |
|
480 | 448 | return path_left, path_right
|
481 |
| - |
482 |
| - |
483 |
| -def make_path_regular(p): |
484 |
| - """ |
485 |
| - If the ``codes`` attribute of `.Path` *p* is None, return a copy of *p* |
486 |
| - with ``codes`` set to (MOVETO, LINETO, LINETO, ..., LINETO); otherwise |
487 |
| - return *p* itself. |
488 |
| - """ |
489 |
| - c = p.codes |
490 |
| - if c is None: |
491 |
| - c = np.full(len(p.vertices), Path.LINETO, dtype=Path.code_type) |
492 |
| - c[0] = Path.MOVETO |
493 |
| - return Path(p.vertices, c) |
494 |
| - else: |
495 |
| - return p |
496 |
| - |
497 |
| - |
498 |
| -def concatenate_paths(paths): |
499 |
| - """Concatenate a list of paths into a single path.""" |
500 |
| - vertices = np.concatenate([p.vertices for p in paths]) |
501 |
| - codes = np.concatenate([make_path_regular(p).codes for p in paths]) |
502 |
| - return Path(vertices, codes) |
0 commit comments