@@ -255,67 +255,76 @@ def point_at_t(self, t):
255
255
return tuple (self (t ))
256
256
257
257
def arc_area (self ):
258
- r"""(Signed) area swept out by ray from origin to curve.
258
+ r"""
259
+ (Signed) area swept out by ray from origin to curve.
259
260
260
261
Notes
261
262
-----
262
- Exact formula used for Bezier curves.
263
-
264
- Now for an arbitrary bezier curve B(t), the area of the arc swept
265
- out by the ray from the origin to the curve, we simply need to compute
266
- :math:`\frac{1}{2}\int_0^1 B(t) \cdot n(t) dt`, where :math:`n(t) =
267
- u^{(1)}(t) \hat{x}_0 - u{(0)}(t) \hat{x}_1` is the normal vector
268
- oriented away from the origin and :math:`u^{(i)}(t) = \frac{d}{dt}
269
- B^{(i)}(t)` is the :math:`i`th component of the curve's tangent vector.
270
- (This formula can be found by applying the divergence theorem to
271
- :math:`F(x,y) = [x, y]/2`.
263
+ A simple, analytical formula is possible for arbitrary bezier curves.
264
+
265
+ Given a bezier curve B(t), in order to calculate the area of the arc
266
+ swept out by the ray from the origin to the curve, we simply need to
267
+ compute :math:`\frac{1}{2}\int_0^1 B(t) \cdot n(t) dt`, where
268
+ :math:`n(t) = u^{(1)}(t) \hat{x}_0 - u{(0)}(t) \hat{x}_1` is the normal
269
+ vector oriented away from the origin and :math:`u^{(i)}(t) =
270
+ \frac{d}{dt} B^{(i)}(t)` is the :math:`i`th component of the curve's
271
+ tangent vector. (This formula can be found by applying the divergence
272
+ theorem to :math:`F(x,y) = [x, y]/2`, and calculates the *signed* area
273
+ for a counter-clockwise curve, by the right hand rule).
272
274
273
275
The control points of the curve are just its coefficients in a
274
- Bernstein expansion, so if we let :math:`P_i = [x_i, y_i]` be the
275
- :math:`i`th control point, then
276
+ Bernstein expansion, so if we let :math:`P_i = [P^{(0)}_i, P^{(1)}_i]`
277
+ be the :math:`i`' th control point, then
276
278
277
279
.. math::
278
280
279
- \frac{1}{2}\int_0^1 B(t) \cdot n(t) dt \\
280
- = \frac{1}{2}\int_0^1 B^{(0)}(t) \frac{d}{dt} B^{(1)}(t)
281
+ \frac{1}{2}\int_0^1 B(t) \cdot n(t) dt
282
+ & = \frac{1}{2}\int_0^1 B^{(0)}(t) \frac{d}{dt} B^{(1)}(t)
281
283
- B^{(1)}(t) \frac{d}{dt} B^{(0)}(t)
282
284
dt \\
283
- = \frac{1}{2}\int_0^1
285
+ & = \frac{1}{2}\int_0^1
284
286
\left( \sum_{j=0}^n P_j^{(0)} b_{j,n} \right)
285
287
\left( n \sum_{k=0}^{n-1} (P_{k+1}^{(1)} -
286
288
P_{k}^{(1)}) b_{j,n} \right)
287
- - \left( \sum_{j=0}^n P_j^{(1)} b_{j,n} \right)
289
+ \\
290
+ &\hspace{1em}- \left( \sum_{j=0}^n P_j^{(1)} b_{j,n} \right)
288
291
\left( n \sum_{k=0}^{n-1} (P_{k+1}^{(0)} -
289
292
P_{k}^{(0)}) b_{j,n} \right)
290
<
10000
td data-grid-cell-id="diff-e7d9993abed80ae82ede8d51dc0830aa5f9a4465cdbb8e04397f75f46a55b1a7-290-293-1" data-selected="false" role="gridcell" style="background-color:var(--bgColor-default);text-align:center" tabindex="-1" valign="top" class="focusable-grid-cell diff-line-number position-relative diff-line-number-neutral left-side">293
dt
291
294
292
- Where :math:`b_{\nu,n}(t)` is the :math:`\nu`'th Bernstein polynomial
293
- of degree :math:`n`, :math:`b_{\nu, n}(t) = {n \choose \nu} t^\nu {(1 -
294
- t)}^{n-\nu}`.
295
+ Where :math:`b_{\nu, n}(t) = {n \choose \nu} t^\nu {(1 - t)}^{n-\nu}`
296
+ is the :math:`\nu`'th Bernstein polynomial of degree :math:`n`.
295
297
296
- grouping :math:`t^l(1-t)^m` terms together for each :math:`l`,
298
+ Grouping :math:`t^l(1-t)^m` terms together for each :math:`l`,
297
299
:math:`m`, we get that the integrand becomes
298
300
299
301
.. math::
300
302
301
- \frac{n}{2}\int_0^1 \sum_{j=0}^n \sum_{k=0}^{n-1}
302
- \frac{{n \choose j} {{n - 1} \choose k}}
303
- {{{2n - 1} \choose {j+k}}}
304
- [P_j^{(0)} (P_{k+1}^{(1)} - P_{k}^{(1)})
305
- - P_j^{(1)} (P_{k+1}^{(0)} - P_{k}^{(0)})]
306
- b_{j+k,2n-1}(t) dt
303
+ &\sum_{j=0}^n \sum_{k=0}^{n-1}
304
+ {n \choose j} {{n - 1} \choose k}
305
+ [P_j^{(0)} (P_{k+1}^{(1)} - P_{k}^{(1)})
306
+ - P_j^{(1)} (P_{k+1}^{(0)} - P_{k}^{(0)})]
307
+ t^{j + k} {(1 - t)}^{2n - 1 - j - k}
308
+ \\
309
+ &= \sum_{j=0}^n \sum_{k=0}^{n-1}
310
+ \frac{{n \choose j} {{n - 1} \choose k}}
311
+ {{{2n - 1} \choose {j+k}}}
312
+ [P_j^{(0)} (P_{k+1}^{(1)} - P_{k}^{(1)})
313
+ - P_j^{(1)} (P_{k+1}^{(0)} - P_{k}^{(0)})]
314
+ b_{j+k,2n-1}(t)
307
315
308
- Interchanging sum and integral, we notice that :math:`\int_0^1 b_{\nu,
309
- n}(t) dt = \frac{1}{n + 1}`, so we conclude that
316
+ Interchanging sum and integral, and using the fact that :math:`\int_0^1
317
+ b_{\nu, n}(t) dt = \frac{1}{n + 1}`, we conclude that the
318
+ original integral (:math:`\frac{1}{2}\int_0^1 B(t) \cdot n(t) dt`) can
319
+ simply be written as
310
320
311
321
.. math::
312
322
313
- \frac{1}{2}\int_0^1 B(t) \cdot n(t) dt
314
- = \frac{1}{4}\sum_{j=0}^n \sum_{k=0}^{n-1}
315
- \frac{{n \choose j} {{n - 1} \choose k}}
316
- {{{2n - 1} \choose {j+k}}}
317
- [P_j^{(0)} (P_{k+1}^{(1)} - P_{k}^{(1)})
318
- - P_j^{(1)} (P_{k+1}^{(0)} - P_{k}^{(0)})]
323
+ \frac{1}{4}\sum_{j=0}^n \sum_{k=0}^{n-1}
324
+ \frac{{n \choose j} {{n - 1} \choose k}}
325
+ {{{2n - 1} \choose {j+k}}}
326
+ [P_j^{(0)} (P_{k+1}^{(1)} - P_{k}^{(1)})
327
+ - P_j^{(1)} (P_{k+1}^{(0)} - P_{k}^{(0)})]
319
328
"""
320
329
n = self .degree
321
330
area = 0
@@ -329,6 +338,7 @@ def arc_area(self):
329
338
330
339
@classmethod
331
340
def differentiate (cls , B ):
341
+ """Return the derivative of a BezierSegment, itself a BezierSegment"""
332
342
dcontrol_points = B .degree * np .diff (B .control_points , axis = 0 )
333
343
return cls (dcontrol_points )
334
344
@@ -401,6 +411,7 @@ def axis_aligned_extrema(self):
401
411
"""
402
412
n = self .degree
403
413
Cj = self .polynomial_coefficients
414
+ # much faster than .differentiate(self).polynomial_coefficients
404
415
dCj = np .atleast_2d (np .arange (1 , n + 1 )).T * Cj [1 :]
405
416
if len (dCj ) == 0 :
406
417
return np .array ([]), np .array ([])
0 commit comments