I have a list of 2d points which are the control vertices (Dx) for a closed uniform cubic B-spline. I am assuming a simple curve (non-self-intersecting, all control points are distinct).
I am trying to find the area enclosed by the curve:

If I calculate the knot points (Px), I can treat the curve as a polygon; then I “just” need to find the remaining delta areas, for each segment, between the actual curve and the straight line joining the knot points.
I understand that the shape (and therefore area) of a Bspline is invariant under rotation and translation – so for each segment, I can find a translation to put the t=0 knot at the origin and a rotation to put the t=1 knot on the +x axis:

I can find the equation for the curve by plugging the points in and re-grouping:
P(t) = (
(t**3)*(-Dm1 + 3*D0 - 3*D1 + D2)
+ (t**2)*(3*Dm1 - 6*D0 + 3*D1)
+ t*(-3*Dm1 + 3*D1)
+ (Dm1 + 4*D0 + D1)
) / 6.
but I’m tearing my hair out trying to integrate it – I can do
1
/
| Py(t) dt
/
t=0
but that doesn’t give me area. I think what I need is
Px(t=1)
/
| Py(t) (dPx(t) / dt) dt
/
x = Px(t=0)
but before I go further, I’d really like to know:
-
Is this the correct calculation for area? Ideally, an analytic solution would make my day!
-
Once I find this area, how can I tell whether I need to add or subtract it from the base poly (red vs green areas in the first diagram)?
-
Are there any Python modules which would do this calculation for me? Numpy has some methods for evaluating cubic Bsplines, but none which seem to deal with area.
-
Is there an easier way to do this? I am thinking about maybe evaluating P(t) at a bunch of points – something like
t = numpy.arange(0.0, 1.0, 0.05)– and treating the whole thing as a polygon. Any idea how many subdivisions are needed to guarantee a given level of accuracy (I’d like error < 1%)?
The result you get is the area for one segment of the whole curve. Some will be negative, as they face the opposite direction. If you sum up the areas for all segments, you get the area of the whole curve.
The result is:
If you convert it into matrix form, you get:
where P is
If the control points are
[(0,0) (1,0) (1,1) (0,1)], the resulting areas become:The sum is 488/720 = 61/90.