diff --git a/Bernstein.h b/Bernstein.h new file mode 100644 index 0000000..85bf2f2 --- /dev/null +++ b/Bernstein.h @@ -0,0 +1,53 @@ +//---------------------------------------------------------------------------- +// EgalTech 2020-2020 +//---------------------------------------------------------------------------- +// File : Bernstein.h Data : 22.03.20 Versione : 2.2c2 +// Contenuto : Implementazione delle funzioni sui polinomi di Bernstein. +// +// +// +// Modifiche : 22.03.20 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +#pragma once + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "/EgtDev/Include/EgtNumCollection.h" + +//---------------------------------------------------------------------------- +inline bool +GetAllBernstein( double dU, int nDeg, DBLVECTOR& vBern) +{ + if ( nDeg >= int( vBern.size())) + return false ; + vBern[0] = 1 ; + for ( int i = 1 ; i <= nDeg ; ++ i) { + double dTot = 0 ; + for ( int j = 0 ; j < i ; ++ j) { + double dTmp = vBern[j] ; + vBern[j] = dTot + ( 1 - dU) * dTmp ; + dTot = dU * dTmp ; + } + vBern[i] = dTot ; + } + return true ; +} + +//---------------------------------------------------------------------------- +inline bool +IncreaseAllBernsteinOneDegree( double dU, int nDeg, DBLVECTOR& vBern) +{ + if ( nDeg >= int( vBern.size())) + return false ; + double dTot = 0 ; + for ( int j = 0 ; j < nDeg ; ++ j) { + double dTmp = vBern[j] ; + vBern[j] = dTot + ( 1 - dU) * dTmp ; + dTot = dU * dTmp ; + } + vBern[nDeg] = ( nDeg > 0 ? dTot : 1) ; + return true ; +} diff --git a/CurveBezier.cpp b/CurveBezier.cpp index 1abba71..60eeb7d 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -24,12 +24,14 @@ #include "NgeWriter.h" #include "NgeReader.h" #include "PolynomialPoint3d.h" +#include "Bernstein.h" #include "/EgtDev/Include/EGkCurveArc.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkUiUnits.h" #include "/EgtDev/Include/ENkPolynomial.h" +#include "/EgtDev/Include/EgtNumUtils.h" #include "/EgtDev/Include/EgtPointerOwner.h" -#include +#include using namespace std ; @@ -42,18 +44,13 @@ GEOOBJ_REGISTER( CRV_BEZ, NGE_C_BEZ, CurveBezier) ; //---------------------------------------------------------------------------- CurveBezier::CurveBezier( void) : m_nStatus( TO_VERIFY), m_nDeg(), m_bRat( false), m_dParSing( -2), - m_nDimArr(), m_aPtCtrl( nullptr), m_aWeCtrl( nullptr), m_VtExtr(), m_dThick(), m_nTempProp() + m_VtExtr(), m_dThick(), m_nTempProp() { } //---------------------------------------------------------------------------- CurveBezier::~CurveBezier( void) { - if ( m_nDimArr > 0) { - delete [] m_aPtCtrl ; - delete [] m_aWeCtrl ; - } - m_nDimArr = 0 ; } //---------------------------------------------------------------------------- @@ -64,53 +61,17 @@ CurveBezier::Init( int nDeg, bool bIsRational) if ( nDeg < 1 || nDeg > MAXDEG) return false ; - // se spazio dinamico sufficiente - if ( ( nDeg + 1) <= m_nDimArr) - ; - // se altrimenti spazio statico sufficiente - else if ( ( nDeg + 1) <= ST_PTC) { - m_aPtCtrl = m_aStPtCtrl ; - if ( bIsRational) - m_aWeCtrl = m_aStWeCtrl ; - } - // altrimenti - else { - // se necessaria, pulizia - if ( m_nDimArr > 0) { - delete [] m_aPtCtrl ; - delete [] m_aWeCtrl ; - } - // alloco punti - m_aPtCtrl = new( nothrow) Point3d [ nDeg + 1] ; - if ( m_aPtCtrl == nullptr) - return false ; - // se razionale, alloco pesi - if ( bIsRational) { - m_aWeCtrl = new( nothrow) double [ nDeg + 1] ; - if ( m_aWeCtrl == nullptr) { - delete [] m_aPtCtrl ; - return false ; - } - } - // salvo dimensione array allocati - m_nDimArr = nDeg + 1 ; - } - - // salvo il grado + // imposto grado, flag di razionale e singolarità non studiata m_nDeg = nDeg ; - - // salvo flag di razionale m_bRat = bIsRational ; - - // dichiaro non si è ancora fatta analisi presenza singolarità m_dParSing = - 2 ; - // pulisco, assegnando 0 ai punti e 1 ai pesi - memset( m_aPtCtrl, 0, sizeof( Point3d) * ( m_nDeg + 1)) ; - if ( m_bRat) { - for ( int i = 0 ; i <= m_nDeg ; ++ i) - m_aWeCtrl[i] = 1 ; - } + // dimensiono i vettori dei punti e dei pesi + m_vPtCtrl.assign( nDeg + 1, ORIG) ; + if ( bIsRational) + m_vWeCtrl.assign( nDeg + 1, 1) ; + else + m_vWeCtrl.clear() ; m_nStatus = TO_VERIFY ; // imposto ricalcolo della grafica @@ -128,11 +89,11 @@ CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl) return false ; // assegno il valore - m_aPtCtrl[nInd] = ptCtrl ; + m_vPtCtrl[nInd] = ptCtrl ; // se razionale, metto il peso a 1 if ( m_bRat) - m_aWeCtrl[nInd] = 1 ; + m_vWeCtrl[nInd] = 1 ; // annullo analisi presenza singolarità m_dParSing = - 2 ; @@ -156,8 +117,8 @@ CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) return false ; // assegno il valore e il peso - m_aPtCtrl[nInd] = ptCtrl ; - m_aWeCtrl[nInd] = dW ; + m_vPtCtrl[nInd] = ptCtrl ; + m_vWeCtrl[nInd] = dW ; // annullo analisi presenza singolarità m_dParSing = - 2 ; @@ -173,38 +134,27 @@ bool CurveBezier::FromArc( const ICurveArc& crArc) { const double MAX_ANG_CEN_DEG = 120 ; - double dAngCen ; - double dCosAhalf ; - double dW ; - Point3d ptStart ; - Point3d ptEnd ; - Point3d ptEndNoDN ; - Point3d ptMed ; - Point3d ptNew ; - Point3d ptNew1 ; - Point3d ptNew2 ; - Vector3d vtDeltaN ; - Vector3d vtDir ; - if ( ! crArc.IsValid()) return false ; - dAngCen = crArc.GetAngCenter() ; + double dAngCen = crArc.GetAngCenter() ; if ( abs( dAngCen) > MAX_ANG_CEN_DEG) return false ; - dCosAhalf = cos( 0.5 * dAngCen * DEGTORAD) ; + double dCosAhalf = cos( 0.5 * dAngCen * DEGTORAD) ; // se arco piatto, basta quadrica razionale // algoritmo di Sederberg (BYU) CAGD cap. 2 pag. 33 if ( abs( crArc.GetDeltaN()) < EPS_ZERO) { // peso del punto di controllo intermedio - dW = dCosAhalf ; + double dW = dCosAhalf ; // calcolo dei punti di controllo + Point3d ptStart ; crArc.GetStartPoint( ptStart) ; + Point3d ptEnd ; crArc.GetEndPoint( ptEnd) ; - ptMed = Media( ptStart, ptEnd, 0.5) ; - vtDir = ptMed - crArc.GetCenter() ; - ptNew = crArc.GetCenter() + vtDir / ( dCosAhalf * dCosAhalf) ; + Point3d ptMed = Media( ptStart, ptEnd, 0.5) ; + Vector3d vtDir = ptMed - crArc.GetCenter() ; + Point3d ptNew = crArc.GetCenter() + vtDir / ( dCosAhalf * dCosAhalf) ; // inserimento nella curva dei punti di controllo con i pesi Init( 2, true) ; SetControlPoint( 0, ptStart, 1) ; @@ -215,19 +165,21 @@ CurveBezier::FromArc( const ICurveArc& crArc) // algoritmo di Juhasz HelixApproxByCubicBezier CAD 1995 else { // peso dei punti di controllo intermedi - dW = ( 1 + 2 * dCosAhalf) / 3 ; + double dW = ( 1 + 2 * dCosAhalf) / 3 ; // calcolo dei punti di controllo + Point3d ptStart ; crArc.GetStartPoint( ptStart) ; + Point3d ptEnd ; crArc.GetEndPoint( ptEnd) ; - vtDeltaN = crArc.GetDeltaN() * crArc.GetNormVersor() ; - ptEndNoDN = ptEnd - vtDeltaN ; - ptMed = Media( ptStart, ptEndNoDN, 0.5) ; - vtDir = ptMed - crArc.GetCenter() ; - ptNew = crArc.GetCenter() + vtDir / ( dCosAhalf * dCosAhalf) ; - ptNew1 = ( ptStart + 2 * dCosAhalf * ptNew) / ( 1 + 2 * dCosAhalf) + - 0.5 * ( 1 - dCosAhalf / ( 2 + dCosAhalf)) * vtDeltaN ; - ptNew2 = ( ptEndNoDN + 2 * dCosAhalf * ptNew) / ( 1 + 2 * dCosAhalf) + - 0.5 * ( 1 + ( dCosAhalf / ( 2 + dCosAhalf))) * vtDeltaN ; + Vector3d vtDeltaN = crArc.GetDeltaN() * crArc.GetNormVersor() ; + Point3d ptEndNoDN = ptEnd - vtDeltaN ; + Point3d ptMed = Media( ptStart, ptEndNoDN, 0.5) ; + Vector3d vtDir = ptMed - crArc.GetCenter() ; + Point3d ptNew = crArc.GetCenter() + vtDir / ( dCosAhalf * dCosAhalf) ; + Point3d ptNew1 = ( ptStart + 2 * dCosAhalf * ptNew) / ( 1 + 2 * dCosAhalf) + + 0.5 * ( 1 - dCosAhalf / ( 2 + dCosAhalf)) * vtDeltaN ; + Point3d ptNew2 = ( ptEndNoDN + 2 * dCosAhalf * ptNew) / ( 1 + 2 * dCosAhalf) + + 0.5 * ( 1 + ( dCosAhalf / ( 2 + dCosAhalf))) * vtDeltaN ; // inserimento nella curva dei punti di controllo con i pesi Init( 3, true) ; SetControlPoint( 0, ptStart, 1) ; @@ -252,7 +204,7 @@ CurveBezier::IsAPoint( void) const return false ; // ciclo sui punti for ( int i = 1 ; i <= m_nDeg ; ++ i) { - if ( ! AreSamePointApprox( m_aPtCtrl[0], m_aPtCtrl[i])) + if ( ! AreSamePointApprox( m_vPtCtrl[0], m_vPtCtrl[i])) return false ; } @@ -272,7 +224,7 @@ CurveBezier::GetControlPoint( int nInd, bool* pbOk) const // ritorno i dati if ( pbOk != NULL) *pbOk = true ; - return m_aPtCtrl[nInd] ; + return m_vPtCtrl[nInd] ; } //---------------------------------------------------------------------------- @@ -288,7 +240,7 @@ CurveBezier::GetControlWeight( int nInd, bool* pbOk) const // ritorno i dati if ( pbOk != NULL) *pbOk = true ; - return m_aWeCtrl[nInd] ; + return m_vWeCtrl[nInd] ; } //---------------------------------------------------------------------------- @@ -328,11 +280,9 @@ CurveBezier::CopyFrom( const CurveBezier& cbSrc) m_VtExtr = cbSrc.m_VtExtr ; m_dThick = cbSrc.m_dThick ; m_nTempProp = cbSrc.m_nTempProp ; - for ( int i = 0 ; i <= m_nDeg ; ++ i) { - m_aPtCtrl[i] = cbSrc.m_aPtCtrl[i] ; - if ( cbSrc.m_bRat) - m_aWeCtrl[i] = cbSrc.m_aWeCtrl[i] ; - } + m_vPtCtrl = cbSrc.m_vPtCtrl ; + if ( cbSrc.m_bRat) + m_vWeCtrl = cbSrc.m_vWeCtrl ; return true ; } @@ -364,9 +314,9 @@ CurveBezier::Dump( string& sOut, bool bMM, const char* szNewLine) const sOut += "Deg=" + ToString( m_nDeg) + szNewLine ; // ciclo sui punti di controllo ( con pesi se razionale) for ( int i = 0 ; i <= m_nDeg ; ++ i) { - sOut += "PC(" + ToString( GetInUiUnits( m_aPtCtrl[i], bMM), 3) ; + sOut += "PC(" + ToString( GetInUiUnits( m_vPtCtrl[i], bMM), 3) ; if ( m_bRat) - sOut += "," + ToString( m_aWeCtrl[i], 3) ; + sOut += "," + ToString( m_vWeCtrl[i], 3) ; sOut += string( ")") + szNewLine ; } @@ -393,11 +343,11 @@ CurveBezier::Save( NgeWriter& ngeOut) const // ciclo sui punti di controllo ( con pesi se razionale) for ( int i = 0 ; i <= m_nDeg ; ++ i) { if ( ! m_bRat) { - if ( ! ngeOut.WritePoint( m_aPtCtrl[i], ";", true)) + if ( ! ngeOut.WritePoint( m_vPtCtrl[i], ";", true)) return false ; } else { - if ( ! ngeOut.WritePointW( m_aPtCtrl[i], m_aWeCtrl[i], ";", true)) + if ( ! ngeOut.WritePointW( m_vPtCtrl[i], m_vWeCtrl[i], ";", true)) return false ; } } @@ -473,7 +423,7 @@ bool CurveBezier::Validate( void) { if ( m_nStatus == TO_VERIFY) - m_nStatus = ( ( m_nDeg > 0 && m_aPtCtrl != nullptr) ? OK : ERR) ; + m_nStatus = ( ( m_nDeg > 0 && m_vPtCtrl.size() > 0) ? OK : ERR) ; return ( m_nStatus == OK) ; } @@ -490,7 +440,7 @@ CurveBezier::GetLocalBBox( BBox3d& b3Loc, int nFlag) const // basta approssimato if ( ( nFlag & BBF_EXACT) == 0) { for ( int i = 0 ; i <= m_nDeg ; ++ i) - b3Loc.Add( m_aPtCtrl[i]) ; + b3Loc.Add( m_vPtCtrl[i]) ; } // deve essere preciso else { @@ -530,7 +480,7 @@ CurveBezier::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const // basta approssimato if ( ( nFlag & BBF_EXACT) == 0) { for ( int i = 0 ; i <= m_nDeg ; ++ i) { - Point3d ptTemp = m_aPtCtrl[i] ; + Point3d ptTemp = m_vPtCtrl[i] ; ptTemp.ToGlob( frRef) ; b3Ref.Add( ptTemp) ; } @@ -623,7 +573,7 @@ CurveBezier::GetStartPoint( Point3d& ptStart) const return false ; // assegno il punto - ptStart = m_aPtCtrl[0] ; + ptStart = m_vPtCtrl[0] ; return true ; } @@ -637,7 +587,7 @@ CurveBezier::GetEndPoint( Point3d& ptEnd) const return false ; // assegno il punto - ptEnd = m_aPtCtrl[m_nDeg] ; + ptEnd = m_vPtCtrl[m_nDeg] ; return true ; } @@ -703,10 +653,7 @@ CurveBezier::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1 return false ; // il parametro U deve essere compreso tra 0 e 1 - if ( dU < 0) - dU = 0 ; - else if ( dU > 1) - dU = 1 ; + dU = Clamp( dU, 0., 1.) ; // verifico se punto singolare double dSingU ; @@ -726,116 +673,105 @@ CurveBezier::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1 bool CurveBezier::GetPointD1D2( double dU, Point3d& ptPos, Vector3d* pvtDer1, Vector3d* pvtDer2) const { - int i ; - double dBern[MAXDEG] ; - - // la curva deve essere validata if ( m_nStatus != OK) return false ; // il parametro U deve essere compreso tra 0 e 1 - if ( dU < 0) - dU = 0 ; - else if ( dU > 1) - dU = 1 ; + dU = Clamp( dU, 0., 1.) ; // se forma polinomiale (o integrale) if ( ! m_bRat) { // calcolo dei polinomi di Bernstein di grado opportuno - dBern[0] = 1 ; - for ( i = 1 ; i <= m_nDeg - 2 ; ++ i) - IncreaseBernsteinOneDegree( dU, i, dBern) ; + DBLVECTOR vBern( m_nDeg + 1) ; + GetAllBernstein( dU, m_nDeg - 2, vBern) ; // se richiesto, calcolo della derivata seconda if ( pvtDer2 != nullptr && pvtDer1 != nullptr) { - pvtDer2->Set( 0, 0, 0) ; - for ( i = 0 ; i <= m_nDeg - 2 ; ++ i) { - *pvtDer2 += dBern[i] * ( m_aPtCtrl[i+2] + m_aPtCtrl[i] - 2 * m_aPtCtrl[i+1]) ; + *pvtDer2 = V_NULL ; + for ( int i = 0 ; i <= m_nDeg - 2 ; ++ i) { + *pvtDer2 += vBern[i] * ( m_vPtCtrl[i+2] + m_vPtCtrl[i] - 2 * m_vPtCtrl[i+1]) ; } *pvtDer2 *= m_nDeg * ( m_nDeg - 1) ; } // aumento il grado - IncreaseBernsteinOneDegree( dU, m_nDeg - 1, dBern) ; + IncreaseAllBernsteinOneDegree( dU, m_nDeg - 1, vBern) ; // se richiesto, calcolo della derivata prima if ( pvtDer1 != nullptr) { - pvtDer1->Set( 0, 0, 0) ; - for ( i = 0 ; i <= m_nDeg - 1 ; ++ i) { - *pvtDer1 += dBern[i] * ( m_aPtCtrl[i+1] - m_aPtCtrl[i]) ; + *pvtDer1 = V_NULL ; + for ( int i = 0 ; i <= m_nDeg - 1 ; ++ i) { + *pvtDer1 += vBern[i] * ( m_vPtCtrl[i+1] - m_vPtCtrl[i]) ; } *pvtDer1 *= m_nDeg ; } // aumento il grado - IncreaseBernsteinOneDegree( dU, m_nDeg, dBern) ; + IncreaseAllBernsteinOneDegree( dU, m_nDeg, vBern) ; // calcolo del punto - ptPos.Set( 0, 0, 0) ; - for ( i = 0 ; i <= m_nDeg ; ++ i) - ptPos += dBern[i] * m_aPtCtrl[i] ; + ptPos = ORIG ; + for ( int i = 0 ; i <= m_nDeg ; ++ i) + ptPos += vBern[i] * m_vPtCtrl[i] ; } // altrimenti forma razionale else { - double dW ; - double dW1 ; - double dW2 ; - double dInvW ; - Point3d aPtWCtrl[MAXDEG] ; - Vector3d vtPos ; // porto i punti in forma omogenea moltiplicandoli per i pesi - for ( i = 0 ; i <= m_nDeg ; ++ i) - aPtWCtrl[i] = m_aWeCtrl[i] * m_aPtCtrl[i] ; + PNTVECTOR vPtWCtrl( m_nDeg + 1) ; + for ( int i = 0 ; i <= m_nDeg ; ++ i) + vPtWCtrl[i] = m_vWeCtrl[i] * m_vPtCtrl[i] ; // calcolo dei polinomi di Bernstein di grado opportuno - dBern[0] = 1 ; - for ( i = 1 ; i <= m_nDeg - 2 ; ++ i) - IncreaseBernsteinOneDegree( dU, i, dBern) ; + DBLVECTOR vBern( m_nDeg + 1) ; + GetAllBernstein( dU, m_nDeg - 2, vBern) ; // se richiesto, calcolo della derivata seconda + double dW2 = 0 ; if ( pvtDer2 != nullptr && pvtDer1 != nullptr) { - pvtDer2->Set( 0, 0, 0) ; dW2 = 0 ; - for ( i = 0 ; i <= m_nDeg - 2 ; ++ i) { - *pvtDer2 += dBern[i] * ( aPtWCtrl[i+2] + aPtWCtrl[i] - 2 * aPtWCtrl[i+1]) ; - dW2 += dBern[i] * ( m_aWeCtrl[i+2] + m_aWeCtrl[i] - 2 * m_aWeCtrl[i+1]) ; + *pvtDer2 = V_NULL ; + for ( int i = 0 ; i <= m_nDeg - 2 ; ++ i) { + *pvtDer2 += vBern[i] * ( vPtWCtrl[i+2] + vPtWCtrl[i] - 2 * vPtWCtrl[i+1]) ; + dW2 += vBern[i] * ( m_vWeCtrl[i+2] + m_vWeCtrl[i] - 2 * m_vWeCtrl[i+1]) ; } *pvtDer2 *= m_nDeg * ( m_nDeg - 1) ; dW2 *= m_nDeg * ( m_nDeg - 1) ; } // aumento il grado - IncreaseBernsteinOneDegree( dU, m_nDeg - 1, dBern) ; + IncreaseAllBernsteinOneDegree( dU, m_nDeg - 1, vBern) ; // se richiesto, calcolo della derivata prima + double dW1 = 0 ; if ( pvtDer1 != nullptr) { - pvtDer1->Set( 0, 0, 0) ; dW1 = 0 ; - for ( i = 0 ; i <= m_nDeg - 1 ; ++ i) { - *pvtDer1 += dBern[i] * ( aPtWCtrl[i+1] - aPtWCtrl[i]) ; - dW1 += dBern[i] * ( m_aWeCtrl[i+1] - m_aWeCtrl[i]) ; + *pvtDer1 = V_NULL ; + for ( int i = 0 ; i <= m_nDeg - 1 ; ++ i) { + *pvtDer1 += vBern[i] * ( vPtWCtrl[i+1] - vPtWCtrl[i]) ; + dW1 += vBern[i] * ( m_vWeCtrl[i+1] - m_vWeCtrl[i]) ; } *pvtDer1 *= m_nDeg ; dW1 *= m_nDeg ; } // aumento il grado - IncreaseBernsteinOneDegree( dU, m_nDeg, dBern) ; + IncreaseAllBernsteinOneDegree( dU, m_nDeg, vBern) ; // calcolo del punto - ptPos.Set( 0, 0, 0) ; dW = 0 ; - for ( i = 0 ; i <= m_nDeg ; ++ i) { - ptPos += dBern[i] * aPtWCtrl[i] ; - dW += dBern[i] * m_aWeCtrl[i] ; + double dW = 0 ; + ptPos = ORIG ; + for ( int i = 0 ; i <= m_nDeg ; ++ i) { + ptPos += vBern[i] * vPtWCtrl[i] ; + dW += vBern[i] * m_vWeCtrl[i] ; } // ritrasformo da forma omogenea a forma standard - dInvW = 1 / ( ( dW > EPS_ZERO) ? dW : EPS_ZERO) ; + double dInvW = 1 / ( ( dW > EPS_ZERO) ? dW : EPS_ZERO) ; ptPos *= dInvW ; if ( pvtDer1 != nullptr) { - vtPos.Set( ptPos.x, ptPos.y, ptPos.z) ; + Vector3d vtPos( ptPos.x, ptPos.y, ptPos.z) ; *pvtDer1 = ( *pvtDer1 - dW1 * vtPos) * dInvW ; if ( pvtDer2 != nullptr) *pvtDer2 = ( *pvtDer2 - 2 * dW1 * *pvtDer1 - dW2 * vtPos) * dInvW ; @@ -845,27 +781,6 @@ CurveBezier::GetPointD1D2( double dU, Point3d& ptPos, Vector3d* pvtDer1, Vector3 return true ; } -//---------------------------------------------------------------------------- -void -CurveBezier::IncreaseBernsteinOneDegree( double dU, int nDeg, double dBern[]) const -{ - int j ; - double dU1 ; - double dTot ; - double dTmp ; - - - dU1 = 1 - dU ; - dTot = 0 ; - for ( j = 0 ; j < nDeg ; ++ j) { - dTmp = dBern[j] ; - dBern[j] = dTot + dU1 * dTmp ; - dTot = dU * dTmp ; - } - dBern[nDeg] = ( nDeg > 0 ? dTot : 1) ; - -} - //---------------------------------------------------------------------------- int CurveBezier::GetSingularParam( double& dPar) const @@ -898,8 +813,8 @@ CurveBezier::CalcSingularParam( void) const // le curve di grado 2 possono avere singolarità solo se i punti sono allineati con ordine P0 P2 P1 if ( m_nDeg == 2) { - Vector3d vtV1 = m_aPtCtrl[1] - m_aPtCtrl[0] ; - Vector3d vtV2 = m_aPtCtrl[2] - m_aPtCtrl[1] ; + Vector3d vtV1 = m_vPtCtrl[1] - m_vPtCtrl[0] ; + Vector3d vtV2 = m_vPtCtrl[2] - m_vPtCtrl[1] ; if ( ( vtV1 * vtV2) > - EPS_ZERO) { m_dParSing = -1 ; return true ; @@ -915,7 +830,7 @@ CurveBezier::CalcSingularParam( void) const CurveBezier cbDeriv ; cbDeriv.Init( m_nDeg - 1, false) ; for ( int i = 0 ; i < m_nDeg ; ++ i) - cbDeriv.SetControlPoint( i, m_nDeg * ( m_aPtCtrl[i+1] + ( - m_aPtCtrl[i]))) ; + cbDeriv.SetControlPoint( i, m_nDeg * ( m_vPtCtrl[i+1] + ( - m_vPtCtrl[i]))) ; // trasformo nella forma monomia cbDeriv.ToPowerBase( pol3P) ; } @@ -943,9 +858,9 @@ CurveBezier::CalcSingularParam( void) const nZ = FilterMultipleAndOutOfRangeRoots( vdRoot, 0 + EPS_PARAM, 1 - EPS_PARAM, EPS_PARAM) ; // verifico se in corrispondenza di qualche zero si annulla la derivata - Point3d ptPos ; - Vector3d vtDer1 ; for ( int i = 0 ; i < nZ ; ++ i) { + Point3d ptPos ; + Vector3d vtDer1 ; GetPointD1D2( vdRoot[i], ptPos, &vtDer1) ; if ( vtDer1.IsZero()) { m_dParSing = vdRoot[i] ; @@ -966,19 +881,13 @@ CurveBezier::CalcSingularParam( void) const bool CurveBezier::ToPowerBase( PolynomialPoint3d& pol3P) const { - // creo un vettore di punti ausiliario (pulito e di dimensioni adeguate) - PNTVECTOR vPow ; - vPow.clear() ; - vPow.reserve( m_nDeg + 1) ; - // algoritmo di Sederberg (BYU) CAGD cap. 3 // copio i punti di controllo - for ( int i = 0 ; i <= m_nDeg ; ++ i) - vPow.push_back( m_aPtCtrl[i]) ; + PNTVECTOR vPow( m_vPtCtrl.begin(), m_vPtCtrl.end()) ; // se razionale, li moltiplico per i relativi pesi if ( m_bRat) { for ( int i = 0 ; i <= m_nDeg ; ++ i) - vPow[i] *= m_aWeCtrl[i] ; + vPow[i] *= m_vWeCtrl[i] ; } // applico differenze successive, lasciando sul posto il risultato for ( int i = 1 ; i <= m_nDeg ; ++ i) { @@ -986,10 +895,8 @@ CurveBezier::ToPowerBase( PolynomialPoint3d& pol3P) const vPow[j] += - vPow[j-1] ; } // calcolo i coefficienti binomiali - double dBinom[ MAXDEG+1] ; + DBLVECTOR dBinom( m_nDeg + 1, 0) ; dBinom[0] = 1 ; - for ( int i = 1 ; i <= m_nDeg ; ++ i) - dBinom[i] = 0 ; for ( int i = 1 ; i <= m_nDeg ; ++ i) { for ( int j = i ; j > 0 ; -- j) dBinom[j] += dBinom[j-1] ; @@ -1011,26 +918,17 @@ CurveBezier::ToPowerBase( PolynomialPoint3d& pol3P) const bool CurveBezier::ToPowerBase( PolynomialPoint3d& pol3Num, Polynomial& polDen) const { - // creo un vettore di punti ausiliario (pulito e di dimensioni adeguate) - PNTVECTOR vPow ; - vPow.reserve( m_nDeg + 1) ; - // creo un vettore di double ausiliario (pulito e di dimensioni adeguate) - DBLVECTOR dPow ; - if ( m_bRat) - dPow.reserve( m_nDeg + 1) ; - // algoritmo di Sederberg (BYU) CAGD cap. 3 // copio i punti di controllo - for ( int i = 0 ; i <= m_nDeg ; ++ i) - vPow.push_back( m_aPtCtrl[i]) ; - // se razionale + PNTVECTOR vPow( m_vPtCtrl.begin(), m_vPtCtrl.end()) ; + // sistemo i pesi + DBLVECTOR dPow( m_nDeg + 1, 1) ; if ( m_bRat) { // moltiplico i punti per i relativi pesi for ( int i = 0 ; i <= m_nDeg ; ++ i) - vPow[i] *= m_aWeCtrl[i] ; + vPow[i] *= m_vWeCtrl[i] ; // copio i pesi - for ( int i = 0 ; i <= m_nDeg ; ++ i) - dPow.push_back( m_aWeCtrl[i]) ; + dPow = m_vWeCtrl ; } // applico differenze successive, lasciando sul posto il risultato for ( int i = 1 ; i <= m_nDeg ; ++ i) { @@ -1041,10 +939,8 @@ CurveBezier::ToPowerBase( PolynomialPoint3d& pol3Num, Polynomial& polDen) const } } // calcolo i coefficienti binomiali - double dBinom[ MAXDEG+1] ; + DBLVECTOR dBinom( m_nDeg + 1, 0) ; dBinom[0] = 1 ; - for ( int i = 1 ; i <= m_nDeg ; ++ i) - dBinom[i] = 0 ; for ( int i = 1 ; i <= m_nDeg ; ++ i) { for ( int j = i ; j > 0 ; -- j) dBinom[j] += dBinom[j-1] ; @@ -1077,7 +973,7 @@ CurveBezier::GetControlPolygonLength( double& dLen) const // ciclo sui punti di controllo dLen = 0 ; for ( int i = 1 ; i <= m_nDeg ; ++ i) - dLen += Dist( m_aPtCtrl[i], m_aPtCtrl[i-1]) ; + dLen += Dist( m_vPtCtrl[i], m_vPtCtrl[i-1]) ; return true ; } @@ -1094,26 +990,21 @@ double CurveBezier::GetSegmentLength( int nLev, double dU0, double dU1, double dU2, const Point3d& ptP0, const Point3d& ptP1, const Point3d& ptP2) const { + // algoritmo dell'approssimazione con arco per tre punti di S. Vincent e D. Forsey + const int MAX_LEV = 10 ; const double MAX_ARC = 1.05 ; const double LEN_RATIO = 1.2 ; - double dD1 ; - double dDa ; - double dDb ; - double dD2 ; - - - // algoritmo dell'approssimazione con arco per tre punti di S. Vincent e D. Forsey // verifica superamento del massimo livello di recursione per debug if ( nLev >= MAX_LEV) LOG_DBG_ERR( GetEGkLogger(), "ERROR : Exceeded recursions") // calcolo delle distanze - dD1 = Dist( ptP0, ptP2) ; - dDa = Dist( ptP0, ptP1) ; - dDb = Dist( ptP1, ptP2) ; - dD2 = dDa + dDb ; + double dD1 = Dist( ptP0, ptP2) ; + double dDa = Dist( ptP0, ptP1) ; + double dDb = Dist( ptP1, ptP2) ; + double dD2 = dDa + dDb ; // distanza piccola o massimo livello di recursione, approx arco ok if ( dD2 < EPS_SMALL || nLev >= MAX_LEV) @@ -1150,15 +1041,6 @@ CurveBezier::GetSegmentLength( int nLev, double dU0, double dU1, double dU2, bool CurveBezier::GetLengthAtParam( double dU, double& dLen) const { - const int NUM_SEG = 16 ; - double dUIni ; - double dUMid ; - double dUFin ; - Point3d ptIni ; - Point3d ptMid ; - Point3d ptFin ; - - // la curva deve essere validata if ( m_nStatus != OK) return false ; @@ -1177,11 +1059,16 @@ CurveBezier::GetLengthAtParam( double dU, double& dLen) const // parto con un numero fisso di punti e poi affino dove serve dLen = 0 ; - dUIni = 0 ; + double dUIni = 0 ; + Point3d ptIni ; GetPointD1D2( 0, ptIni) ; + double dUMid ; + Point3d ptMid ; + const int NUM_SEG = 16 ; for ( int i = 1 ; i <= NUM_SEG ; ++ i) { // ricavo il punto - dUFin = i / (double) NUM_SEG * dU ; + double dUFin = i / (double) NUM_SEG * dU ; + Point3d ptFin ; GetPointD1D2( dUFin, ptFin) ; // se punto dispari if ( ( i % 2) == 1) { @@ -1206,19 +1093,17 @@ bool CurveBezier::GetSegmentParam( double dLen, double& dCurrLen, double& dSegLen, double& dUIni, double& dUFin) const { - const int NUM_SEG = 16 ; - double dUMid ; - Point3d ptIni ; - Point3d ptMid ; - Point3d ptFin ; - - double dUStart = dUIni ; double dUEnd = dUFin ; + Point3d ptIni ; GetPointD1D2( dUIni, ptIni) ; + double dUMid ; + Point3d ptMid ; + const int NUM_SEG = 16 ; for ( int i = 1 ; i <= NUM_SEG ; ++ i) { // ricavo il punto dUFin = dUStart + i / (double) NUM_SEG * ( dUEnd - dUStart) ; + Point3d ptFin ; GetPointD1D2( dUFin, ptFin) ; // se punto dispari if ( ( i % 2) == 1) { @@ -1247,8 +1132,6 @@ CurveBezier::GetSegmentParam( double dLen, double& dCurrLen, double& dSegLen, bool CurveBezier::GetParamAtLength( double dLen, double& dU) const { - const double MIN_SEG_LEN = 0.2 ; - // la curva deve essere validata if ( m_nStatus != OK) return false ; @@ -1269,6 +1152,7 @@ CurveBezier::GetParamAtLength( double dLen, double& dU) const double dCurrLen = 0 ; double dUIni = 0 ; double dUFin = 1 ; + const double MIN_SEG_LEN = 0.2 ; while ( ( bOk = GetSegmentParam( dLen, dCurrLen, dSegLen, dUIni, dUFin)) && dSegLen > MIN_SEG_LEN) { // allungo di un poco l'intervallo di ricerca per compensare l'approssimazione della lunghezza dUFin = min( dUFin + ( dUFin - dUIni) * 0.05, 1.) ; @@ -1322,7 +1206,7 @@ CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, Poly // se di primo grado, basta inserire gli estremi if ( m_nDeg == 1) { - return ( PL.AddUPoint( 0, m_aPtCtrl[0]) && PL.AddUPoint( 1, m_aPtCtrl[m_nDeg])) ; + return ( PL.AddUPoint( 0, m_vPtCtrl[0]) && PL.AddUPoint( 1, m_vPtCtrl[m_nDeg])) ; } // limiti minimi su tolleranza e deviazione angolare @@ -1348,7 +1232,7 @@ CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, Poly } // inserisco il punto iniziale - if ( ! PL.AddUPoint( 0, m_aPtCtrl[0])) + if ( ! PL.AddUPoint( 0, m_vPtCtrl[0])) return false ; // verifico se va divisa @@ -1357,14 +1241,14 @@ CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, Poly // se è stato inserito un solo punto, aggiungo il finale if ( PL.GetPointNbr() == 1) - return PL.AddUPoint( 1, m_aPtCtrl[m_nDeg]) ; + return PL.AddUPoint( 1, m_vPtCtrl[m_nDeg]) ; // altrimenti, se l'ultimo punto non coincide con il finale lo sostituisco (distano al max di dLinTol) else { Point3d ptLast ; PL.GetLastPoint( ptLast) ; - if ( ! AreSamePointApprox( ptLast, m_aPtCtrl[m_nDeg])) { + if ( ! AreSamePointApprox( ptLast, m_vPtCtrl[m_nDeg])) { PL.EraseLastUPoint() ; - return PL.AddUPoint( 1, m_aPtCtrl[m_nDeg]) ; + return PL.AddUPoint( 1, m_vPtCtrl[m_nDeg]) ; } } @@ -1384,8 +1268,8 @@ CurveBezier::FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart, // considero la curva piatta (inserisco il punto se abbastanza lontano dal precedente) ed esco Point3d ptLast ; PL.GetLastPoint( ptLast) ; - if ( SqDist( ptLast, crvBez.m_aPtCtrl[m_nDeg]) > ( dLinTol * dLinTol)) - PL.AddUPoint( dParEnd, crvBez.m_aPtCtrl[m_nDeg]) ; + if ( SqDist( ptLast, crvBez.m_vPtCtrl[m_nDeg]) > ( dLinTol * dLinTol)) + PL.AddUPoint( dParEnd, crvBez.m_vPtCtrl[m_nDeg]) ; return true ; } @@ -1393,9 +1277,9 @@ CurveBezier::FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart, double dMaxSqDist = 0 ; double dLen ; Vector3d vtDir ; - DirDist( crvBez.m_aPtCtrl[0], crvBez.m_aPtCtrl[m_nDeg], vtDir, dLen) ; + DirDist( crvBez.m_vPtCtrl[0], crvBez.m_vPtCtrl[m_nDeg], vtDir, dLen) ; for ( int i = 1 ; i < m_nDeg ; i ++) { - DistPointLine dstPL( crvBez.m_aPtCtrl[i], crvBez.m_aPtCtrl[0], vtDir, dLen) ; + DistPointLine dstPL( crvBez.m_vPtCtrl[i], crvBez.m_vPtCtrl[0], vtDir, dLen) ; double dSqDist ; if ( dstPL.GetSqDist( dSqDist) && dSqDist > dMaxSqDist) dMaxSqDist = dSqDist ; @@ -1404,8 +1288,8 @@ CurveBezier::FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart, // se distanza entro tolleranza if ( dMaxSqDist <= ( dLinTol * dLinTol)) { // deviazione angolare tra primo e ultimo tratto del poligono di controllo (grado >= 1) - Vector3d vtDirI = crvBez.m_aPtCtrl[1] - crvBez.m_aPtCtrl[0] ; - Vector3d vtDirF = crvBez.m_aPtCtrl[m_nDeg] - crvBez.m_aPtCtrl[m_nDeg-1] ; + Vector3d vtDirI = crvBez.m_vPtCtrl[1] - crvBez.m_vPtCtrl[0] ; + Vector3d vtDirF = crvBez.m_vPtCtrl[m_nDeg] - crvBez.m_vPtCtrl[m_nDeg-1] ; double dAngDeg ; vtDirI.GetAngle( vtDirF, dAngDeg) ; // se deviazione angolare entro tolleranza oppure lunghezza poligono controllo entro tolleranza @@ -1415,8 +1299,8 @@ CurveBezier::FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart, // considero la curva piatta (inserisco il punto se abbastanza lontano dal precedente) ed esco Point3d ptLast ; PL.GetLastPoint( ptLast) ; - if ( SqDist( ptLast, crvBez.m_aPtCtrl[m_nDeg]) > ( dLinTol * dLinTol)) - PL.AddUPoint( dParEnd, crvBez.m_aPtCtrl[m_nDeg]) ; + if ( SqDist( ptLast, crvBez.m_vPtCtrl[m_nDeg]) > ( dLinTol * dLinTol)) + PL.AddUPoint( dParEnd, crvBez.m_vPtCtrl[m_nDeg]) ; return true ; } } @@ -1642,11 +1526,8 @@ CurveBezier::Invert( void) // inverto i punti di controllo int nMid = ( m_nDeg + 1) / 2 ; - for ( int i = 0 ; i < nMid ; ++ i) { - Point3d ptTemp = m_aPtCtrl[i] ; - m_aPtCtrl[i] = m_aPtCtrl[m_nDeg-i] ; - m_aPtCtrl[m_nDeg-i] = ptTemp ; - } + for ( int i = 0 ; i < nMid ; ++ i) + swap( m_vPtCtrl[i], m_vPtCtrl[m_nDeg-i]) ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; @@ -1663,7 +1544,7 @@ CurveBezier::ModifyStart( const Point3d& ptNewStart) return false ; // modifico il primo punto di controllo - m_aPtCtrl[0] = ptNewStart ; + m_vPtCtrl[0] = ptNewStart ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; @@ -1680,7 +1561,7 @@ CurveBezier::ModifyEnd( const Point3d& ptNewEnd) return false ; // modifico l'ultimo punto di controllo - m_aPtCtrl[m_nDeg] = ptNewEnd ; + m_vPtCtrl[m_nDeg] = ptNewEnd ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; @@ -1706,12 +1587,12 @@ CurveBezier::TrimStartAtParam( double dUTrim) for ( int k = 1 ; k <= m_nDeg ; k ++) { for ( int i = 0 ; i <= m_nDeg - k ; i ++) { if ( ! m_bRat) { - m_aPtCtrl[i] = ( 1 - dUTrim) * m_aPtCtrl[i] + dUTrim * m_aPtCtrl[i+1] ; + m_vPtCtrl[i] = ( 1 - dUTrim) * m_vPtCtrl[i] + dUTrim * m_vPtCtrl[i+1] ; } else { - m_aPtCtrl[i] = ( 1 - dUTrim) * m_aWeCtrl[i] * m_aPtCtrl[i] + dUTrim * m_aWeCtrl[i+1] * m_aPtCtrl[i+1] ; - m_aWeCtrl[i] = ( 1 - dUTrim) * m_aWeCtrl[i] + dUTrim * m_aWeCtrl[i+1] ; - m_aPtCtrl[i] = m_aPtCtrl[i] * ( 1 / m_aWeCtrl[i]) ; + m_vPtCtrl[i] = ( 1 - dUTrim) * m_vWeCtrl[i] * m_vPtCtrl[i] + dUTrim * m_vWeCtrl[i+1] * m_vPtCtrl[i+1] ; + m_vWeCtrl[i] = ( 1 - dUTrim) * m_vWeCtrl[i] + dUTrim * m_vWeCtrl[i+1] ; + m_vPtCtrl[i] = m_vPtCtrl[i] * ( 1 / m_vWeCtrl[i]) ; } } } @@ -1740,12 +1621,12 @@ CurveBezier::TrimEndAtParam( double dUTrim) for ( int k = 1 ; k <= m_nDeg ; k ++) { for ( int i = m_nDeg ; i >= k ; i --) { if ( ! m_bRat) { - m_aPtCtrl[i] = ( 1 - dUTrim) * m_aPtCtrl[i-1] + dUTrim * m_aPtCtrl[ i] ; + m_vPtCtrl[i] = ( 1 - dUTrim) * m_vPtCtrl[i-1] + dUTrim * m_vPtCtrl[ i] ; } else { - m_aPtCtrl[i] = ( 1 - dUTrim) * m_aWeCtrl[i-1] * m_aPtCtrl[i-1] + dUTrim * m_aWeCtrl[ i] * m_aPtCtrl[ i] ; - m_aWeCtrl[i] = ( 1 - dUTrim) * m_aWeCtrl[i-1] + dUTrim * m_aWeCtrl[ i] ; - m_aPtCtrl[i] = m_aPtCtrl[i] * ( 1 / m_aWeCtrl[i]) ; + m_vPtCtrl[i] = ( 1 - dUTrim) * m_vWeCtrl[i-1] * m_vPtCtrl[i-1] + dUTrim * m_vWeCtrl[ i] * m_vPtCtrl[ i] ; + m_vWeCtrl[i] = ( 1 - dUTrim) * m_vWeCtrl[i-1] + dUTrim * m_vWeCtrl[ i] ; + m_vPtCtrl[i] = m_vPtCtrl[i] * ( 1 / m_vWeCtrl[i]) ; } } } @@ -1825,29 +1706,29 @@ CurveBezier::ExtendStartByLen( double dLenExt) if ( ! m_bRat) { for ( int k = 1 ; k <= m_nDeg ; k ++) { for ( int i = 0 ; i <= m_nDeg - k ; i ++) - m_aPtCtrl[i] = ( 1 - dUTrim) * m_aPtCtrl[i] + dUTrim * m_aPtCtrl[i+1] ; + m_vPtCtrl[i] = ( 1 - dUTrim) * m_vPtCtrl[i] + dUTrim * m_vPtCtrl[i+1] ; } } // se razionale, devo verificare che i pesi non diventino negativi else { - Point3d aPtCtrl[MAXDEG+1] ; - double aWeCtrl[MAXDEG+1] ; + Point3d vPtCtrl[MAXDEG+1] ; + double vWeCtrl[MAXDEG+1] ; for ( int i = 0 ; i <= m_nDeg ; i ++) { - aPtCtrl[i] = m_aPtCtrl[i] ; - aWeCtrl[i] = m_aWeCtrl[i] ; + vPtCtrl[i] = m_vPtCtrl[i] ; + vWeCtrl[i] = m_vWeCtrl[i] ; } for ( int k = 1 ; k <= m_nDeg ; k ++) { for ( int i = 0 ; i <= m_nDeg - k ; i ++) { - aPtCtrl[i] = ( 1 - dUTrim) * aWeCtrl[i] * aPtCtrl[i] + dUTrim * aWeCtrl[i+1] * aPtCtrl[i+1] ; - aWeCtrl[i] = ( 1 - dUTrim) * aWeCtrl[i] + dUTrim * aWeCtrl[i+1] ; - if ( aWeCtrl[i] < MIN_EXT_WEIGHT) + vPtCtrl[i] = ( 1 - dUTrim) * vWeCtrl[i] * vPtCtrl[i] + dUTrim * vWeCtrl[i+1] * vPtCtrl[i+1] ; + vWeCtrl[i] = ( 1 - dUTrim) * vWeCtrl[i] + dUTrim * vWeCtrl[i+1] ; + if ( vWeCtrl[i] < MIN_EXT_WEIGHT) return false ; - aPtCtrl[i] = aPtCtrl[i] * ( 1 / aWeCtrl[i]) ; + vPtCtrl[i] = vPtCtrl[i] * ( 1 / vWeCtrl[i]) ; } } for ( int i = 0 ; i <= m_nDeg ; i ++) { - m_aPtCtrl[i] = aPtCtrl[i] ; - m_aWeCtrl[i] = aWeCtrl[i] ; + m_vPtCtrl[i] = vPtCtrl[i] ; + m_vWeCtrl[i] = vWeCtrl[i] ; } } // con i controlli sopra fatti rimane validata, ma la grafica va ricalcolata @@ -1873,29 +1754,29 @@ CurveBezier::ExtendEndByLen( double dLenExt) if ( ! m_bRat) { for ( int k = 1 ; k <= m_nDeg ; k ++) { for ( int i = m_nDeg ; i >= k ; i --) - m_aPtCtrl[i] = ( 1 - dUTrim) * m_aPtCtrl[i-1] + dUTrim * m_aPtCtrl[ i] ; + m_vPtCtrl[i] = ( 1 - dUTrim) * m_vPtCtrl[i-1] + dUTrim * m_vPtCtrl[ i] ; } } // se razionale, devo verificare che i pesi non diventino negativi else { - Point3d aPtCtrl[MAXDEG+1] ; - double aWeCtrl[MAXDEG+1] ; + Point3d vPtCtrl[MAXDEG+1] ; + double vWeCtrl[MAXDEG+1] ; for ( int i = 0 ; i <= m_nDeg ; i ++) { - aPtCtrl[i] = m_aPtCtrl[i] ; - aWeCtrl[i] = m_aWeCtrl[i] ; + vPtCtrl[i] = m_vPtCtrl[i] ; + vWeCtrl[i] = m_vWeCtrl[i] ; } for ( int k = 1 ; k <= m_nDeg ; k ++) { for ( int i = m_nDeg ; i >= k ; i --) { - aPtCtrl[i] = ( 1 - dUTrim) * aWeCtrl[i-1] * aPtCtrl[i-1] + dUTrim * aWeCtrl[ i] * aPtCtrl[ i] ; - aWeCtrl[i] = ( 1 - dUTrim) * aWeCtrl[i-1] + dUTrim * aWeCtrl[ i] ; - if ( aWeCtrl[i] < MIN_EXT_WEIGHT) + vPtCtrl[i] = ( 1 - dUTrim) * vWeCtrl[i-1] * vPtCtrl[i-1] + dUTrim * vWeCtrl[ i] * vPtCtrl[ i] ; + vWeCtrl[i] = ( 1 - dUTrim) * vWeCtrl[i-1] + dUTrim * vWeCtrl[ i] ; + if ( vWeCtrl[i] < MIN_EXT_WEIGHT) return false ; - aPtCtrl[i] = aPtCtrl[i] * ( 1 / aWeCtrl[i]) ; + vPtCtrl[i] = vPtCtrl[i] * ( 1 / vWeCtrl[i]) ; } } for ( int i = 0 ; i <= m_nDeg ; i ++) { - m_aPtCtrl[i] = aPtCtrl[i] ; - m_aWeCtrl[i] = aWeCtrl[i] ; + m_vPtCtrl[i] = vPtCtrl[i] ; + m_vWeCtrl[i] = vWeCtrl[i] ; } } // con i controlli sopra fatti rimane validata, ma la grafica va ricalcolata @@ -1916,7 +1797,7 @@ CurveBezier::Translate( const Vector3d& vtMove) // traslo i punti di controllo for ( int i = 0 ; i <= m_nDeg ; ++ i) - m_aPtCtrl[i].Translate( vtMove) ; + m_vPtCtrl[i].Translate( vtMove) ; return true ; } @@ -1938,7 +1819,7 @@ CurveBezier::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, // ruoto i punti di controllo for ( int i = 0 ; i <= m_nDeg ; ++ i) - m_aPtCtrl[i].Rotate( ptAx, vtAx, dCosAng, dSinAng) ; + m_vPtCtrl[i].Rotate( ptAx, vtAx, dCosAng, dSinAng) ; // ruoto il vettore estrusione m_VtExtr.Rotate( vtAx, dCosAng, dSinAng) ; @@ -1961,7 +1842,7 @@ CurveBezier::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double PNTVECTOR vPnt ; vPnt.reserve( m_nDeg + 1) ; for ( int i = 0 ; i <= m_nDeg ; ++ i) { - Point3d ptTmp = m_aPtCtrl[i] ; + Point3d ptTmp = m_vPtCtrl[i] ; ptTmp.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; vPnt.push_back( ptTmp) ; } @@ -1980,7 +1861,7 @@ CurveBezier::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double // scalo i punti di controllo for ( int i = 0 ; i <= m_nDeg ; ++ i) - m_aPtCtrl[i] = vPnt[i] ; + m_vPtCtrl[i] = vPnt[i] ; // scalo vettore estrusione, lo normalizzo e aggiusto spessore m_VtExtr.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; double dLen = m_VtExtr.Len() ; @@ -2009,7 +1890,7 @@ CurveBezier::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) // specchio i punti di controllo for ( int i = 0 ; i <= m_nDeg ; ++ i) - m_aPtCtrl[i].Mirror( ptOn, vtNorm) ; + m_vPtCtrl[i].Mirror( ptOn, vtNorm) ; // specchio il vettore estrusione m_VtExtr.Mirror( vtNorm) ; @@ -2033,7 +1914,7 @@ CurveBezier::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& // eseguo scorrimento dei punti di controllo for ( int i = 0 ; i <= m_nDeg ; ++ i) - m_aPtCtrl[i].Shear( ptOn, vtNorm, vtDir, dCoeff) ; + m_vPtCtrl[i].Shear( ptOn, vtNorm, vtDir, dCoeff) ; // eseguo scorrimento del vettore estrusione, lo normalizzo e aggiusto spessore m_VtExtr.Shear( vtNorm, vtDir, dCoeff) ; double dLen = m_VtExtr.Len() ; @@ -2062,7 +1943,7 @@ CurveBezier::ToGlob( const Frame3d& frRef) // trasformo i punti di controllo for ( int i = 0 ; i <= m_nDeg ; ++ i) - m_aPtCtrl[i].ToGlob( frRef) ; + m_vPtCtrl[i].ToGlob( frRef) ; // trasformo il vettore estrusione m_VtExtr.ToGlob( frRef) ; @@ -2086,7 +1967,7 @@ CurveBezier::ToLoc( const Frame3d& frRef) // trasformo i punti di controllo for ( int i = 0 ; i <= m_nDeg ; ++ i) - m_aPtCtrl[i].ToLoc( frRef) ; + m_vPtCtrl[i].ToLoc( frRef) ; // trasformo il vettore estrusione m_VtExtr.ToLoc( frRef) ; @@ -2110,7 +1991,7 @@ CurveBezier::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) // trasformo i punti di controllo for ( int i = 0 ; i <= m_nDeg ; ++ i) - m_aPtCtrl[i].LocToLoc( frOri, frDest) ; + m_vPtCtrl[i].LocToLoc( frOri, frDest) ; // trasformo il vettore estrusione m_VtExtr.LocToLoc( frOri, frDest) ; diff --git a/CurveBezier.h b/CurveBezier.h index 102fe93..3542ea0 100644 --- a/CurveBezier.h +++ b/CurveBezier.h @@ -161,7 +161,6 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW bool Validate( void) ; bool GetPointD1D2( double dU, Point3d& ptPos, Vector3d* pvtDer1 = nullptr, Vector3d* pvtDer2 = nullptr) const ; - void IncreaseBernsteinOneDegree( double dU, int nDeg, double dBern[]) const ; bool CalcSingularParam( void) const ; double GetSegmentLength( int nLev, double dU0, double dU1, double dU2, const Point3d& ptP0, const Point3d& ptP1, const Point3d& ptP2) const ; @@ -181,18 +180,15 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW private : ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto - Status m_nStatus ; // stato - int m_nDeg ; // grado - bool m_bRat ; // flag di razionale/polinomiale + Status m_nStatus ; // stato + int m_nDeg ; // grado + bool m_bRat ; // flag di razionale/polinomiale mutable double m_dParSing ; // eventuale parametro della singolarità (-1=no, -2=da calcolare) - int m_nDimArr ; // dimensione dell'array dinamico di punti - Point3d* m_aPtCtrl ; // array dei punti di controllo - double* m_aWeCtrl ; // array dei pesi di controllo - Point3d m_aStPtCtrl[ST_PTC] ; // array predefinito di 4 punti di controllo - double m_aStWeCtrl[ST_PTC] ; // array predefinito di 4 pesi di controllo - Vector3d m_VtExtr ; // vettore estrusione (normalmente coincide con m_VtN) - double m_dThick ; // spessore - int m_nTempProp ; // proprietà temporanea + PNTVECTOR m_vPtCtrl ; // vettore dei punti di controllo + DBLVECTOR m_vWeCtrl ; // vettore dei pesi di controllo + Vector3d m_VtExtr ; // vettore estrusione (normalmente coincide con m_VtN) + double m_dThick ; // spessore + int m_nTempProp ; // proprietà temporanea } ; //----------------------------------------------------------------------------- diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index 3e71516..91fe364 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -513,6 +513,7 @@ copy $(TargetPath) \EgtProg\Dll64 + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index 63c70d3..4235999 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -983,6 +983,9 @@ File di intestazione\Include + + File di intestazione + diff --git a/HashGrids3d.cpp b/HashGrids3d.cpp index e4b6279..2c552ae 100644 --- a/HashGrids3d.cpp +++ b/HashGrids3d.cpp @@ -132,7 +132,7 @@ HashGrid3d::~HashGrid3d( void) { Clear() ; - for ( Cell* pCell = m_cell ; pCell < m_cell + m_xyzCellCount ; ++ pCell) { + for ( Cell* pCell = m_cell ; pCell < m_cell + m_xyzCellCount ; ++ pCell) { if ( pCell->m_neighborOffset != m_stdNeighborOffset) delete[] pCell->m_neighborOffset ; } diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index 42b61dc..e34c120 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -2086,8 +2086,8 @@ SurfTriMesh::CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nR return false ; // recupero i punti iniziali su curva 1 - int nV1p ; double dU1p ; double dA1p ; Point3d ptP1p ; - int nV1s ; double dU1s ; double dA1s ; Point3d ptP1s ; + int nV1p = SVT_NULL ; double dU1p ; double dA1p ; Point3d ptP1p ; + int nV1s = SVT_NULL ; double dU1s ; double dA1s ; Point3d ptP1s ; bool bNext1 = PL1.GetFirstUPoint( &dU1p, &ptP1p) && PL1.GetNextUPoint( &dU1s, &ptP1s, bClosed) ; if ( ! bNext1) return false ; @@ -2096,8 +2096,8 @@ SurfTriMesh::CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nR if ( ( nV1p = AddVertex( ptP1p)) == SVT_NULL) return false ; // recupero i punti iniziali su curva 2 - int nV2p ; double dU2p ; double dA2p ; Point3d ptP2p ; - int nV2s ; double dU2s ; double dA2s ; Point3d ptP2s ; + int nV2p = SVT_NULL ; double dU2p ; double dA2p ; Point3d ptP2p ; + int nV2s = SVT_NULL ; double dU2s ; double dA2s ; Point3d ptP2s ; bool bNext2 = PL2.GetFirstUPoint( &dU2p, &ptP2p) && PL2.GetNextUPoint( &dU2s, &ptP2s, bClosed) ; if ( ! bNext2) return false ;