Small error in curve length calculation

Hello everyone.

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.

Analytical length: 1.62322524014023
Numerical length: 1.6232134893224

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.

Alexander Luger's picture

I always used GCPnts_AbscissaPoint to compute the length of a curve. Maybe this class gives you more precise results.

Alex

Laszlo Kudela's picture

Thanks Alexander, I will have a look!

Laszlo Kudela's picture

So I had a look today and found out that the numerically calculated curve length is:

1.6232134893224

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.

Forum supervisor's picture

Dear Laszlo,
There are two methods of class GCPnts_AbscissaPoint for calculation curve length:
- Length(Adaptor3d_Curve& C)
and
- 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[116]> 2dbeziercurve cc 3 1 0 1 1 0 1
Draw[117]> length cc 1.e-3
The length cc is 1.6232247922762246

Draw[118]> length cc 1.e-9
The length cc is 1.623225240139941

Draw[119]> 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.

Regards

Laszlo Kudela's picture

Dear Forum Supervisor,

thank you very much for the detailed explanation!

Now I know another new thing about OpenCascade :)