I was creating a Bezier curve with control points (1,0) (1,1) (0,1) and then calculated the length of the curve by calculating the mass by BRepGProp::LinearProperties . However, if I compare the analytical curve length with the numerical one, there is an error between the two of them.
You can see that this difference is quite big actually.
Can you give me some hints about how the length of the curve is calculated? I have used an own algorithm to calculate the curve length by integrating the length of the tangent vector along the parameter space of the curve, and it gave a more precise result.
I always used GCPnts_AbscissaPoint to compute the length of a curve. Maybe this class gives you more precise results.
Thanks Alexander, I will have a look!
So I had a look today and found out that the numerically calculated curve length is:
Which is the same as for the mass calculation.
I did some digging in the source code and found out that basically they also use the same idea in GCPnts_AbscissaPoint for the curve length calculation. What they do is that they take the absolute value of the tangent vector and integrate over the parameter space of the curve. For the numerical integration Gaussian quadrature is used.
I am not 100% sure if this causes the problem, but Gaussian quadrature is only exact for polynomials. However, the length of the tangent vector is somehow a square-root expression I guess, and this is why it makes the computation only a good approximation and not an exact calculation.
If someone from OpenCascade could confirm this, that would be really nice! :)
Anyways, this error around the 4th digit behind the decimal point might be not that bad for geometric modelling after all.
There are two methods of class GCPnts_AbscissaPoint for calculation curve length:
- Length(Adaptor3d_Curve& C)
- Length(Adaptor3d_Curve& C,const Standard_Real Tol)
The first method uses Gauss integration with predefined order depending on type of curve, particularly for Bezier curve order = Min(24, 2*degree), so for case degree=2, order = 4, which provides precision ~ 1.e-4.
The second method uses adaptive Gauss integration and allows getting needed precision for length.
It can be demonstrated by the next Draw commands:
Draw> 2dbeziercurve cc 3 1 0 1 1 0 1
Draw> length cc 1.e-3
The length cc is 1.6232247922762246
Draw> length cc 1.e-9
The length cc is 1.623225240139941
Draw> length cc 1.e-12
The length cc is 1.623225240140229
As you can see, the difference between last result and “analytical” length is 1.1102230246251565e-015
Method BRepGProp::LinearProperties uses only predefined order for Gauss integration,
but BRepGProp::SurfaceProperties and VolumeProperties use adaptive Gauss-Kronrod integration and allow to get result with necessary precision.