From 6d544f93f4e8f465e5ee6c5a7acac8e08bbe5c62 Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Thu, 19 Feb 2026 18:15:58 +0100 Subject: [PATCH] EgtGeomKernel : - miglioramento dell'approssimazione con curve di bezier. --- CurveAux.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/CurveAux.cpp b/CurveAux.cpp index 484367d..43c1f53 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -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 pCCApproxTot( CreateCurveComposite()) ; for ( INTINT iiSE : vConstCurv) { nFirst = iiSE.first ; nLast = iiSE.second ; - //definisco la bezier che vado a raffinare iterativamente - PtrOwner 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 pCApprox( LineToBezierCurve( &CL, 3, false)) ; + if ( ! pCCApproxTot->AddCurve( Release( pCApprox))) + return nullptr ; + } + else { + //definisco la bezier che vado a raffinare iterativamente + PtrOwner 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) ;