EgtGeomKernel :

- miglioramento dell'approssimazione con curve di bezier.
This commit is contained in:
Daniele Bariletti
2026-02-19 18:15:58 +01:00
parent 3c1a7ff1bb
commit 6d544f93f4
+20 -6
View File
@@ -1642,8 +1642,11 @@ ApproxCurveWithBezier( const ICurve* pCrv , double dTol)
double dRadPrec = vRad[0] ;
int nStart = 0 ;
int nEnd = 1 ;
double dRatio = 1.5 ;
while ( nStart < ssize( vPnt) - 1) {
double dRadTol = max( max( vRad[nEnd], dRadPrec) / 10 , 1.) ;
if ( dRadPrec > dRatio * vRad[nEnd] || dRatio * dRadPrec < vRad[nEnd])
dRadTol = 0 ;
while ( nEnd < ssize( vPnt) - 1 && abs( vRad[nEnd] - dRadPrec) < dRadTol) {
dRadPrec = vRad[nEnd] ;
++nEnd ;
@@ -1678,16 +1681,27 @@ ApproxCurveWithBezier( const ICurve* pCrv , double dTol)
vNextDer[i].Normalize() ;
}
// potrei verificare prima se un tratto è retto e aggiustare le tangenti del tratto precedente e successivo prima di approssimare
PtrOwner<ICurveComposite> pCCApproxTot( CreateCurveComposite()) ;
for ( INTINT iiSE : vConstCurv) {
nFirst = iiSE.first ;
nLast = iiSE.second ;
//definisco la bezier che vado a raffinare iterativamente
PtrOwner<ICurve> pCApprox( FitWithBezier( pCrv, vPntOverSampling, vParam, nFirst, nLast, vPrevDer, vNextDer, dTol, true)) ;
if ( IsNull( pCApprox) || ! pCApprox->IsValid())
return nullptr ;
if ( ! pCCApproxTot->AddCurve( Release( pCApprox)))
return nullptr ;
// riconosco se ho un tratto retto
int nPnt = nFirst / 3 ;
if ( nLast - nFirst == 3 && ( nPnt > 0 && vRad[nPnt] > dRatio * vRad[nPnt - 1]) && ( nPnt < ssize( vRad) && vRad[nPnt]> dRatio * vRad[nPnt + 1])) {
CurveLine CL ; CL.Set( vPntOverSampling[nFirst], vPntOverSampling[nLast]) ;
PtrOwner<ICurveBezier> pCApprox( LineToBezierCurve( &CL, 3, false)) ;
if ( ! pCCApproxTot->AddCurve( Release( pCApprox)))
return nullptr ;
}
else {
//definisco la bezier che vado a raffinare iterativamente
PtrOwner<ICurve> pCApprox( FitWithBezier( pCrv, vPntOverSampling, vParam, nFirst, nLast, vPrevDer, vNextDer, dTol, true)) ;
if ( IsNull( pCApprox) || ! pCApprox->IsValid())
return nullptr ;
if ( ! pCCApproxTot->AddCurve( Release( pCApprox)))
return nullptr ;
}
}
return Release( pCCApproxTot) ;