Merge branch 'master' into MoreBezier
This commit is contained in:
+16
-10
@@ -895,7 +895,8 @@ ApproxBezierWithCubics(const ICurveBezier* pCrvBezier, double dTol)
|
||||
PtrOwner<ICurveComposite> pCC( CreateBasicCurveComposite()) ;
|
||||
|
||||
// approssimo l'ultimo tratto
|
||||
while ( dErr > dTol) {
|
||||
int nCount = 0 ;
|
||||
while ( dErr > dTol && nCount < 100) {
|
||||
PtrOwner<ICurveBezier> pCrvPart( pCrvBezier->Clone()) ;
|
||||
pCrvPart->TrimStartEndAtParam( double( nParts - 1) / nParts, 1) ;
|
||||
PtrOwner<ICurveBezier> pCrvCubic ;
|
||||
@@ -920,18 +921,23 @@ ApproxBezierWithCubics(const ICurveBezier* pCrvBezier, double dTol)
|
||||
if( bOneIsEnough)
|
||||
break ;
|
||||
}
|
||||
++ nCount ;
|
||||
}
|
||||
|
||||
// approssimo annche tutti gli altri tratti con una cubica
|
||||
for ( int i = nParts - 1 ; i > 0 ; --i) {
|
||||
PtrOwner<ICurveBezier> pCrvPart( pCrvBezier->Clone()) ;
|
||||
pCrvPart->TrimStartEndAtParam( double( i - 1) / nParts, double(i) / nParts) ;
|
||||
PtrOwner<ICurveBezier> pCrvCubic( ApproxCurveBezierWithSingleCubic( pCrvPart)) ;
|
||||
if ( ! pCC->AddCurve( Release( pCrvCubic), false))
|
||||
return nullptr ;
|
||||
}
|
||||
if( nCount < 100) {
|
||||
// approssimo annche tutti gli altri tratti con una cubica
|
||||
for ( int i = nParts - 1 ; i > 0 ; --i) {
|
||||
PtrOwner<ICurveBezier> pCrvPart( pCrvBezier->Clone()) ;
|
||||
pCrvPart->TrimStartEndAtParam( double( i - 1) / nParts, double(i) / nParts) ;
|
||||
PtrOwner<ICurveBezier> pCrvCubic( ApproxCurveBezierWithSingleCubic( pCrvPart)) ;
|
||||
if ( ! pCC->AddCurve( Release( pCrvCubic), false))
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
return Release( pCC) ;
|
||||
return Release( pCC) ;
|
||||
}
|
||||
else
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
+52
-43
@@ -2297,12 +2297,16 @@ CurveBezier::MakeNonRational( double dTol)
|
||||
return true ;
|
||||
|
||||
// controllo se i pesi sono tutti == 1 allora è una finta razionale e mi basta fare una copia dei punti di controllo
|
||||
bool bIsActualRat = true ;
|
||||
for ( int i = 0 ; i < m_nDeg && bIsActualRat ; ++i)
|
||||
bIsActualRat = bIsActualRat && abs(m_vWeCtrl[i] - 1) > EPS_SMALL ;
|
||||
bool bIsActualRat = false ;
|
||||
for ( int i = 0 ; i < m_nDeg ; ++i) {
|
||||
if ( abs(m_vWeCtrl[i] - 1) > EPS_SMALL) {
|
||||
bIsActualRat = true ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
bool bOk = true ;
|
||||
if ( ! bIsActualRat ) {
|
||||
if ( ! bIsActualRat) {
|
||||
PtrOwner<CurveBezier> pNewBez( CreateBasicCurveBezier()) ;
|
||||
for ( int p = 0 ; p < m_nDeg ; ++p) {
|
||||
Point3d pt = GetControlPoint( p) ;
|
||||
@@ -2311,49 +2315,54 @@ CurveBezier::MakeNonRational( double dTol)
|
||||
}
|
||||
else {
|
||||
// provo ad approssimare la curva di bezier con una controparte non razionale
|
||||
PtrOwner<CurveBezier> pNewBez( CreateBasicCurveBezier()) ;
|
||||
int nDeg = m_nDeg + 2 ;
|
||||
pNewBez->Init( nDeg, false) ;
|
||||
PNTVECTOR vPntCtrl ;
|
||||
PNTVECTOR vPntSampling ;
|
||||
for ( int p = 0 ; p < nDeg + 1; ++p) {
|
||||
Point3d pt ; GetPointD1D2( double(p) / nDeg, pt) ;
|
||||
pNewBez->SetControlPoint( p, pt) ;
|
||||
vPntCtrl.push_back( pt) ;
|
||||
}
|
||||
vPntSampling = vPntCtrl ;
|
||||
int c = 0 ;
|
||||
double dErr = INFINITO ;
|
||||
while ( dErr > dTol && c < 100) {
|
||||
double dErrMax = 0 ;
|
||||
// calcolo le differenze tra i punti di sampling sulla nuova curva e quelli sulla curva originale
|
||||
int nDeg = m_nDeg ;
|
||||
// punto di rientro in caso fallisca il primo tentativo
|
||||
retry :
|
||||
nDeg += 2 ;
|
||||
PtrOwner<CurveBezier> pNewBez( CreateBasicCurveBezier()) ;
|
||||
pNewBez->Init( nDeg, false) ;
|
||||
PNTVECTOR vPntCtrl ;
|
||||
PNTVECTOR vPntSampling ;
|
||||
for ( int p = 0 ; p < nDeg + 1; ++p) {
|
||||
Point3d pt ; pNewBez->GetPointD1D2( double(p) / nDeg, pt) ;
|
||||
Vector3d vDiff = vPntSampling[p] - pt ;
|
||||
double dErrLoc = vDiff.Len() ;
|
||||
if( dErrLoc > dErrMax)
|
||||
dErrMax = dErrLoc ;
|
||||
// aggiorno il vettore dei punti di controllo della nuova curva
|
||||
vPntCtrl[p] += vDiff ;
|
||||
Point3d pt ; GetPointD1D2( double(p) / nDeg, pt) ;
|
||||
pNewBez->SetControlPoint( p, pt) ;
|
||||
vPntCtrl.push_back( pt) ;
|
||||
}
|
||||
vPntSampling = vPntCtrl ;
|
||||
int c = 0 ;
|
||||
double dErr = INFINITO ;
|
||||
while ( dErr > dTol && c < 100) {
|
||||
double dErrMax = 0 ;
|
||||
// calcolo le differenze tra i punti di sampling sulla nuova curva e quelli sulla curva originale
|
||||
for ( int p = 0 ; p < nDeg + 1; ++p) {
|
||||
Point3d pt ; pNewBez->GetPointD1D2( double(p) / nDeg, pt) ;
|
||||
Vector3d vDiff = vPntSampling[p] - pt ;
|
||||
double dErrLoc = vDiff.Len() ;
|
||||
if( dErrLoc > dErrMax)
|
||||
dErrMax = dErrLoc ;
|
||||
// aggiorno il vettore dei punti di controllo della nuova curva
|
||||
vPntCtrl[p] += vDiff ;
|
||||
}
|
||||
dErr = dErrMax ;
|
||||
// aggiorno i punti di controllo della nuova curva
|
||||
for ( int i = 0 ; i < nDeg + 1 ; ++i)
|
||||
pNewBez->SetControlPoint( i, vPntCtrl[i]) ;
|
||||
++c ;
|
||||
}
|
||||
dErr = dErrMax ;
|
||||
// aggiorno i punti di controllo della nuova curva
|
||||
for ( int i = 0 ; i < nDeg + 1 ; ++i)
|
||||
pNewBez->SetControlPoint( i, vPntCtrl[i]) ;
|
||||
++c ;
|
||||
}
|
||||
|
||||
// calcolo l'errore di approssimazione sulla curva
|
||||
CalcBezierApproxError( this, pNewBez, dErr) ;
|
||||
bOk = dErr < dTol ;
|
||||
if( bOk) {
|
||||
// aggiorno la curva di bezier originale con quella approssimata
|
||||
Init( nDeg, false) ;
|
||||
for( int i = 0 ; i < nDeg + 1 ; ++i) {
|
||||
SetControlPoint( i, pNewBez->GetControlPoint( i)) ;
|
||||
SetControlWeight( i, pNewBez->GetControlWeight( i)) ;
|
||||
// calcolo l'errore di approssimazione sulla curva
|
||||
CalcBezierApproxError( this, pNewBez, dErr) ;
|
||||
bOk = dErr < dTol ;
|
||||
if( bOk) {
|
||||
// aggiorno la curva di bezier originale con quella approssimata
|
||||
Init( nDeg, false) ;
|
||||
for( int i = 0 ; i < nDeg + 1 ; ++i) {
|
||||
SetControlPoint( i, pNewBez->GetControlPoint( i)) ;
|
||||
SetControlWeight( i, pNewBez->GetControlWeight( i)) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( nDeg < m_nDeg + 4)
|
||||
goto retry ;
|
||||
}
|
||||
|
||||
return bOk ;
|
||||
|
||||
Reference in New Issue
Block a user