@@ -22,6 +22,20 @@ def _comb(n, k):
2222 return np .prod ((n + 1 - i )/ i ).astype (int )
2323
2424
25+ # Precomputed matrices for converting Bézier control points to polynomial
26+ # coefficients. _COEFF_MATRICES[n] @ control_points gives coefficients.
27+ # These avoid the slow _comb vectorized function for common cases.
28+ _COEFF_MATRICES = {
29+ 1 : np .array ([[1. , 0. ], [- 1. , 1. ]]),
30+ 2 : np .array ([[1. , 0. , 0. ], [- 2. , 2. , 0. ], [1. , - 2. , 1. ]]),
31+ 3 : np .array ([[1. , 0. , 0. , 0. ], [- 3. , 3. , 0. , 0. ],
32+ [3. , - 6. , 3. , 0. ], [- 1. , 3. , - 3. , 1. ]]),
33+ 4 : np .array ([[1. , 0. , 0. , 0. , 0. ], [- 4. , 4. , 0. , 0. , 0. ],
34+ [6. , - 12. , 6. , 0. , 0. ], [- 4. , 12. , - 12. , 4. , 0. ],
35+ [1. , - 4. , 6. , - 4. , 1. ]]),
36+ }
37+
38+
2539class NonIntersectingPathException (ValueError ):
2640 pass
2741
@@ -275,11 +289,14 @@ def polynomial_coefficients(self):
275289 where :math:`P_i` are the control points of the curve.
276290 """
277291 n = self .degree
278- # matplotlib uses n <= 4. overflow plausible starting around n = 15.
292+ P = self .control_points
293+ # matplotlib uses n <= 4
294+ if n in _COEFF_MATRICES :
295+ return _COEFF_MATRICES [n ] @ P
296+ # Fallback for higher degrees. overflow plausible starting around n = 15.
279297 if n > 10 :
280298 warnings .warn ("Polynomial coefficients formula unstable for high "
281299 "order Bezier curves!" , RuntimeWarning )
282- P = self .control_points
283300 j = np .arange (n + 1 )[:, None ]
284301 i = np .arange (n + 1 )[None , :] # _comb is non-zero for i <= j
285302 prefactor = (- 1 )** (i + j ) * _comb (j , i ) # j on axis 0, i on axis 1
0 commit comments