Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have:

points = {{0, 100}, {250, 0}, {0, 300}, {500, 500}}

And I want to know the area below the curve, so I came to:

f = BezierFunction[points]

NIntegrate[f, {x, 0, 1}]

But it failed to execute:

NIntegrate::inumr: The integrand BezierFunction[{{0.,1.}},<>] has evaluated to non-numerical values for all sampling points in the region with boundaries {{0,1}}. >>

So how do I numerically integrate a Bézier curve correctly?

share|improve this question
up vote 8 down vote accepted

Since f[t] yields in effect {x[t], y[t]} and the area under a curve (with y[t] > 0) is given by the integral of y[t] x'[t] (i.e., $\int y\;dx$), then the following should work, assuming x[t] is increasing.

dA[f_, t_?NumericQ] := Last[f[t]] First[f'[t]];
NIntegrate[dA[f, t], {t, 0, 1}]
(*  150000.  *)

One can extend this to other forms, e.g. to closed curves, via Green's Theorem, with dA[f_, x_?NumericQ] := f[x].Cross[f'[x]]/2.

share|improve this answer

You should note that NIntegrate normally consumes standard functions or InterpolatingFunction. A BezierFunction is a parametric function and will not work right away with the integrator.

You can do the following by the way.

mesh = DiscretizeGraphics[ParametricPlot[f[t], {t, 0, 1}]];
nf = Interpolation[MeshCoordinates[mesh]];
NIntegrate[nf[x], Evaluate@Flatten@{x, nf["Domain"]}]

150000.

I basically took the point-wise representation of your BezierFunction from a parametric plot using the DiscretizeGraphics functionality of MMA. You can see the sampled points along with your curve.

enter image description here

Show[Graphics[{Red, PointSize[Large], Point[points], Orange, Dashed, 
   Line[points]}, Axes -> True], 
 ParametricPlot[f[t], {t, 0, 1}, 
  PlotStyle -> {{LightBlue, Thickness@.01}}], mesh, Frame -> True]

P.S: Note that the above process will not work on arbitrary BezierFunction as 2D Bézier curves are by definition allowed to resolve into an one to many mapping which can't be integrated.

share|improve this answer

The nice thing about Mathematica is that it often allows you to do a thing in more than one fashion. For this answer, I will evaluate the exact integral, using a slight tweak of Michael's strategy.

The wrinkle here is that we fall back on the definition of the Bézier curve as an appropriate linear combination of Bernstein functions. This allows you to have the $x$ and $y$ components of the curve kept separately.

Thus,

pts = {{0, 100}, {250, 0}, {0, 300}, {500, 500}};
n = Length[pts] - 1;
{f[t_], g[t_]} = BernsteinBasis[n, Range[0, n], t].pts;
Integrate[g[t] f'[t], {t, 0, 1}]
   150000
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.