+//=======================================================================
+//function : compensateError
+//purpose : adjust theParams so that the last segment length == an
+//=======================================================================
+
+static void compensateError(double a1, double an,
+ double U1, double Un,
+ double length,
+ GeomAdaptor_Curve& C3d,
+ list<double> & theParams)
+{
+ int i, nPar = theParams.size();
+ if ( a1 + an < length && nPar > 1 )
+ {
+ list<double>::reverse_iterator itU = theParams.rbegin();
+ double Ul = *itU++;
+ // dist from the last point to the edge end <Un>, it should be equal <an>
+ double Ln = GCPnts_AbscissaPoint::Length( C3d, Ul, Un );
+ double dLn = an - Ln; // error of <an>
+ if ( Abs( dLn ) <= Precision::Confusion() )
+ return;
+ double dU = Ul - *itU; // parametric length of the last but one segment
+ double dUn = dLn * ( Un - U1 ) / length; // modificator of the last parameter
+ if ( dUn < 0.5 * dU ) { // last segment is a bit shorter than dU
+ dUn = -dUn; // move the last parameter to the edge beginning
+ }
+ else { // last segment is much shorter than dU -> remove the last param and
+ theParams.pop_back(); // move the rest points toward the edge end
+ Ln = GCPnts_AbscissaPoint::Length( C3d, theParams.back(), Un );
+ dUn = ( an - Ln ) * ( Un - U1 ) / length;
+ if ( dUn < 0.5 * dU )
+ dUn = -dUn;
+ }
+ double q = dUn / ( nPar - 1 );
+ for ( itU = theParams.rbegin(), i = 1; i < nPar; itU++, i++ ) {
+ (*itU) += dUn;
+ dUn -= q;
+ }
+ }
+}
+