diff --git a/CurveArc.cpp b/CurveArc.cpp
index 1d5a55e..8ccca6d 100644
--- a/CurveArc.cpp
+++ b/CurveArc.cpp
@@ -288,7 +288,7 @@ CurveArc::GetLength( double& dLen) const
//----------------------------------------------------------------------------
bool
-CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const
+CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const
{
int i ;
int nStep ;
@@ -321,9 +321,6 @@ CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoin
// sistemo lo step (per il numero intero di passi)
dAngStepDeg = m_dAngCenDeg / nStep ;
- // riservo lo spazio necessario nel vettore di punti
- vUPoints.reserve( nStep + 1) ;
-
// versori di riferimento nel piano dell'arco
vtA1 = m_VtS ;
vtA2 = m_VtN ^ m_VtS ;
@@ -334,7 +331,7 @@ CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoin
// primo punto
ptPos = m_PtCen + vtA1 * m_dRad ;
- vUPoints.push_back( UPOINT( 0, ptPos)) ;
+ PL.AddUPoint( 0, ptPos) ;
// ciclo per i punti successivi
for ( i = 1 ; i <= nStep ; ++ i) {
@@ -349,7 +346,7 @@ CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoin
ptPos = m_PtCen + vtA1 * m_dRad ;
if ( fabs( m_dDeltaN) > EPS_ZERO)
ptPos = ptPos + ( dU * m_dDeltaN) * m_VtN ;
- vUPoints.push_back( UPOINT( dU, ptPos)) ;
+ PL.AddUPoint( dU, ptPos) ;
}
return true ;
diff --git a/CurveArc.h b/CurveArc.h
index 8717981..10f7555 100644
--- a/CurveArc.h
+++ b/CurveArc.h
@@ -52,6 +52,7 @@ class CurveArc : public ICurveArc
virtual bool GetPointTangNormCurv( double dU, Point3d& ptPos, Vector3d& vtT, Vector3d& vtN, double& dCurv) const
{ return ::GetPointTangNormCurv( *this, dU, ptPos, vtT, vtN, dCurv) ; }
virtual bool Reverse( void) ;
+ virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ;
virtual bool TrimStartAtParam( double dUTrim) ;
virtual bool TrimEndAtParam( double dUTrim) ;
virtual bool TrimStartAtLen( double dLenTrim) ;
@@ -76,15 +77,14 @@ class CurveArc : public ICurveArc
{ return m_dAngCenDeg ; }
virtual double GetDeltaN( void) const
{ return m_dDeltaN ; }
- virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const ;
public :
CurveArc( void) ;
- inline const CurveArc& operator =( const CurveArc& caSrc)
- { if ( &caSrc != this)
- Set( caSrc.m_PtCen, caSrc.m_VtN, caSrc.m_dRad,
- caSrc.m_VtS, caSrc.m_dAngCenDeg, caSrc.m_dDeltaN) ;
- return *this ; }
+ const CurveArc& operator =( const CurveArc& caSrc)
+ { if ( &caSrc != this)
+ Set( caSrc.m_PtCen, caSrc.m_VtN, caSrc.m_dRad,
+ caSrc.m_VtS, caSrc.m_dAngCenDeg, caSrc.m_dDeltaN) ;
+ return *this ; }
private :
bool Validate( void) ;
diff --git a/CurveBezier.cpp b/CurveBezier.cpp
index 04b5b02..a43f63c 100644
--- a/CurveBezier.cpp
+++ b/CurveBezier.cpp
@@ -725,7 +725,7 @@ CurveBezier::GetParamAtLength( double dLen, double& dU) const
//----------------------------------------------------------------------------
bool
CurveBezier::FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart, double dParEnd,
- double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const
+ double dLinTol, double dAngTolDeg, PolyLine& PL) const
{
const int MAX_LEV = 10 ;
int i ;
@@ -733,6 +733,7 @@ CurveBezier::FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart,
double dSqDist ;
double dAngDeg ;
double dPolLen ;
+ Point3d ptLast ;
Vector3d vtDirI ;
Vector3d vtDirF ;
DistPointLine dstPL ;
@@ -743,8 +744,9 @@ CurveBezier::FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart,
// segnalo situazione per debug
LOG_DBG_ERR( GetEGkLogger(), "ERROR : Exceeded recursions")
// considero la curva piatta (inserisco il punto se abbastanza lontano dal precedente) ed esco
- if ( SqDist( vUPoints.back().second, crvBez.m_aPtCtrl[m_nDeg]) > ( dLinTol * dLinTol))
- vUPoints.push_back( UPOINT( dParEnd, crvBez.m_aPtCtrl[m_nDeg])) ;
+ PL.GetLastPoint( ptLast) ;
+ if ( SqDist( ptLast, crvBez.m_aPtCtrl[m_nDeg]) > ( dLinTol * dLinTol))
+ PL.AddUPoint( dParEnd, crvBez.m_aPtCtrl[m_nDeg]) ;
return true ;
}
@@ -768,8 +770,9 @@ CurveBezier::FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart,
if ( fabs( dAngDeg) <= dAngTolDeg ||
( crvBez.GetControlPolygonLength( dPolLen) && dPolLen <= dLinTol)) {
// considero la curva piatta (inserisco il punto se abbastanza lontano dal precedente) ed esco
- if ( SqDist( vUPoints.back().second, crvBez.m_aPtCtrl[m_nDeg]) > ( dLinTol * dLinTol))
- vUPoints.push_back( UPOINT( dParEnd, crvBez.m_aPtCtrl[m_nDeg])) ;
+ PL.GetLastPoint( ptLast) ;
+ if ( SqDist( ptLast, crvBez.m_aPtCtrl[m_nDeg]) > ( dLinTol * dLinTol))
+ PL.AddUPoint( dParEnd, crvBez.m_aPtCtrl[m_nDeg]) ;
return true ;
}
}
@@ -783,12 +786,12 @@ CurveBezier::FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart,
// prima metà
crvBez1 = crvBez ;
crvBez1.TrimEndAtParam( 0.5) ;
- if ( ! FlatOrSplit( nLev + 1, crvBez1, dParStart, dParMid, dLinTol, dAngTolDeg, vUPoints))
+ if ( ! FlatOrSplit( nLev + 1, crvBez1, dParStart, dParMid, dLinTol, dAngTolDeg, PL))
return false ;
// seconda metà
crvBez1 = crvBez ;
crvBez1.TrimStartAtParam( 0.5) ;
- if ( ! FlatOrSplit( nLev + 1, crvBez1, dParMid, dParEnd, dLinTol, dAngTolDeg, vUPoints))
+ if ( ! FlatOrSplit( nLev + 1, crvBez1, dParMid, dParEnd, dLinTol, dAngTolDeg, PL))
return false ;
}
@@ -797,20 +800,16 @@ CurveBezier::FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart,
//----------------------------------------------------------------------------
bool
-CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const
+CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const
{
- const int VP_DIM = 64 ;
-
-
// la curva deve essere validata
if ( m_nStatus != OK)
return false ;
// se di primo grado, basta inserire gli estremi
if ( m_nDeg == 1) {
- vUPoints.reserve( 2) ;
- vUPoints.push_back( UPOINT( 0, m_aPtCtrl[0])) ;
- vUPoints.push_back( UPOINT( 1, m_aPtCtrl[m_nDeg])) ;
+ PL.AddUPoint( 0, m_aPtCtrl[0]) ;
+ PL.AddUPoint( 1, m_aPtCtrl[m_nDeg]) ;
return true ;
}
@@ -818,18 +817,15 @@ CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUP
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ;
- // riservo uno spazio standard nel vettore di punti
- vUPoints.reserve( VP_DIM) ;
-
// inserisco il punto iniziale
- vUPoints.push_back( UPOINT( 0, m_aPtCtrl[0])) ;
+ PL.AddUPoint( 0, m_aPtCtrl[0]) ;
// verifico se va divisa
- FlatOrSplit( 0, *this, PAR_START, PAR_END, dLinTol, dAngTolDeg, vUPoints) ;
+ FlatOrSplit( 0, *this, PAR_START, PAR_END, dLinTol, dAngTolDeg, PL) ;
// se è stato inserito un solo punto, aggiungo il finale
- if ( vUPoints.size() == 1)
- vUPoints.push_back( UPOINT( 1, m_aPtCtrl[m_nDeg])) ;
+ if ( PL.GetPointNbr() == 1)
+ PL.AddUPoint( 1, m_aPtCtrl[m_nDeg]) ;
return true ;
}
diff --git a/CurveBezier.h b/CurveBezier.h
index bf2e5b3..fe9ee30 100644
--- a/CurveBezier.h
+++ b/CurveBezier.h
@@ -54,6 +54,7 @@ class CurveBezier : public ICurveBezier
virtual bool GetPointTangNormCurv( double dU, Point3d& ptPos, Vector3d& vtT, Vector3d& vtN, double& dCurv) const
{ return ::GetPointTangNormCurv( *this, dU, ptPos, vtT, vtN, dCurv) ; }
virtual bool Reverse( void) ;
+ virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ;
virtual bool TrimStartAtParam( double dUTrim) ;
virtual bool TrimEndAtParam( double dUTrim) ;
virtual bool TrimStartAtLen( double dLenTrim) ;
@@ -71,19 +72,18 @@ class CurveBezier : public ICurveBezier
virtual const Point3d& GetControlPoint( int nInd, bool* pbOk = NULL) const ;
virtual double GetControlWeight( int nInd, bool* pbOk = NULL) const ;
virtual bool GetControlPolygonLength( double& dLen) const ;
- virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const ;
public :
CurveBezier( void) ;
- inline const CurveBezier& operator =( const CurveBezier& cbSrc)
- { if ( &cbSrc != this && Init( cbSrc.m_nDeg, cbSrc.m_bRat)) {
- 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] ;
- }
- }
- return *this ; }
+ const CurveBezier& operator =( const CurveBezier& cbSrc)
+ { if ( &cbSrc != this && Init( cbSrc.m_nDeg, cbSrc.m_bRat)) {
+ 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] ;
+ }
+ }
+ return *this ; }
private :
bool Validate( void) ;
@@ -93,7 +93,7 @@ class CurveBezier : public ICurveBezier
bool GetSegmentParam( double dLen, double& dCurrLen, double& dSegLen,
double& dUIni, double& dUFin) const ;
bool FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart, double dParEnd,
- double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const ;
+ double dLinTol, double dAngTolDeg, PolyLine& PL) const ;
private :
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
diff --git a/CurveComposite.cpp b/CurveComposite.cpp
index d8f4f40..00760a7 100644
--- a/CurveComposite.cpp
+++ b/CurveComposite.cpp
@@ -383,6 +383,40 @@ CurveComposite::GetLength( double& dLen) const
return true ;
}
+//----------------------------------------------------------------------------
+bool
+CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const
+{
+ bool bFirst ;
+ double dStartPar ;
+ Point3d ptP ;
+ PolyLine PLSmpl ;
+ PCRVSMPL_LIST::const_iterator Iter ;
+
+
+ bFirst = true ;
+ dStartPar = 0 ;
+ for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
+ // recupero approssimazione per curva semplice
+ if ( ! (*Iter)->ApproxWithLines( dLinTol, dAngTolDeg, PLSmpl))
+ return false ;
+ // la accodo opportunamente a quella della curva composita
+ if ( bFirst) {
+ PL.Splice( PLSmpl) ;
+ bFirst = false ;
+ }
+ else {
+ PLSmpl.EraseFirstUPoint() ;
+ PLSmpl.AddOffsetToU( dStartPar) ;
+ PL.Splice( PLSmpl) ;
+ }
+ // incremento inizio parametro per prossima curva semplice
+ dStartPar += 1 ;
+ }
+
+ return true ;
+}
+
//----------------------------------------------------------------------------
bool
CurveComposite::Reverse( void)
@@ -798,3 +832,16 @@ CurveComposite::GetNextCurve( void) const
else
return nullptr ;
}
+
+//----------------------------------------------------------------------------
+bool
+CurveComposite::IsParamAtJoint( double dU) const
+{
+ // se all'inizio, alla fine o lontano dagli interi
+ if ( fabs( dU) < EPS_ZERO ||
+ fabs( dU - m_nCounter) < EPS_ZERO ||
+ fabs( dU - (int) ( dU + EPS_ZERO)) > EPS_ZERO)
+ return false ;
+ else
+ return true ;
+}
diff --git a/CurveComposite.h b/CurveComposite.h
index 4183b91..0a8a67a 100644
--- a/CurveComposite.h
+++ b/CurveComposite.h
@@ -56,6 +56,7 @@ class CurveComposite : public ICurveComposite
virtual bool GetPointTangNormCurv( double dU, Point3d& ptPos, Vector3d& vtT, Vector3d& vtN, double& dCurv) const
{ return ::GetPointTangNormCurv( *this, dU, ptPos, vtT, vtN, dCurv) ; }
virtual bool Reverse( void) ;
+ virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ;
virtual bool TrimStartAtParam( double dUTrim) ;
virtual bool TrimEndAtParam( double dUTrim) ;
virtual bool TrimStartAtLen( double dLenTrim) ;
@@ -67,17 +68,18 @@ class CurveComposite : public ICurveComposite
virtual int GetCurveNumber( void) const { return m_nCounter ; }
virtual const ICurve* GetFirstCurve( void) const ;
virtual const ICurve* GetNextCurve( void) const ;
+ virtual bool IsParamAtJoint( double dU) const ;
public :
CurveComposite( void) ;
- inline const CurveComposite& operator =( const CurveComposite& ccSrc)
- { if ( &ccSrc != this) {
- Clear() ;
- PCRVSMPL_LIST::const_iterator Iter ;
- for ( Iter = ccSrc.m_CrvSmplS.begin() ; Iter != ccSrc.m_CrvSmplS.end() ; ++Iter)
- AddCurve( **Iter) ;
- }
- return *this ; }
+ const CurveComposite& operator =( const CurveComposite& ccSrc)
+ { if ( &ccSrc != this) {
+ Clear() ;
+ PCRVSMPL_LIST::const_iterator Iter ;
+ for ( Iter = ccSrc.m_CrvSmplS.begin() ; Iter != ccSrc.m_CrvSmplS.end() ; ++Iter)
+ AddCurve( **Iter) ;
+ }
+ return *this ; }
private :
bool Validate( void) ;
diff --git a/CurveLine.cpp b/CurveLine.cpp
index e71010a..1a456d1 100644
--- a/CurveLine.cpp
+++ b/CurveLine.cpp
@@ -204,16 +204,15 @@ CurveLine::GetLength( double& dLen) const
//----------------------------------------------------------------------------
bool
-CurveLine::ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const
+CurveLine::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const
{
// la curva deve essere validata
if ( m_nStatus != OK)
return false ;
// inserisco gli estremi
- vUPoints.reserve( 2) ;
- vUPoints.push_back( UPOINT( 0, m_PtStart)) ;
- vUPoints.push_back( UPOINT( 1, m_PtEnd)) ;
+ PL.AddUPoint( 0, m_PtStart) ;
+ PL.AddUPoint( 1, m_PtEnd) ;
return true ;
}
diff --git a/CurveLine.h b/CurveLine.h
index 298ae74..ddb347c 100644
--- a/CurveLine.h
+++ b/CurveLine.h
@@ -52,6 +52,7 @@ class CurveLine : public ICurveLine
virtual bool GetPointTangNormCurv( double dU, Point3d& ptPos, Vector3d& vtT, Vector3d& vtN, double& dCurv) const
{ return ::GetPointTangNormCurv( *this, dU, ptPos, vtT, vtN, dCurv) ; }
virtual bool Reverse( void) ;
+ virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ;
virtual bool TrimStartAtParam( double dUTrim) ;
virtual bool TrimEndAtParam( double dUTrim) ;
virtual bool TrimStartAtLen( double dLenTrim) ;
@@ -63,14 +64,13 @@ class CurveLine : public ICurveLine
{ return m_PtStart ; }
virtual const Point3d& GetEnd( void) const
{ return m_PtEnd ; }
- virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, UPNTVECTOR& vUPoints) const ;
public :
CurveLine( void) ;
- inline const CurveLine& operator =( const CurveLine& clSrc)
- { if ( &clSrc != this)
- Set( clSrc.m_PtStart, clSrc.m_PtEnd) ;
- return *this ; }
+ const CurveLine& operator =( const CurveLine& clSrc)
+ { if ( &clSrc != this)
+ Set( clSrc.m_PtStart, clSrc.m_PtEnd) ;
+ return *this ; }
private :
bool Validate( void) ;
diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc
index a4aaac6..6ffa6a2 100644
Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ
diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj
index 26d11b6..80726d7 100644
--- a/EgtGeomKernel.vcxproj
+++ b/EgtGeomKernel.vcxproj
@@ -138,6 +138,7 @@ copy $(TargetPath) \EgtProg\Dll
+
Create
Create
@@ -164,6 +165,7 @@ copy $(TargetPath) \EgtProg\Dll
+
diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters
index c0d1ade..85827a5 100644
--- a/EgtGeomKernel.vcxproj.filters
+++ b/EgtGeomKernel.vcxproj.filters
@@ -96,6 +96,9 @@
File di origine\Base
+
+ File di origine\Base
+
@@ -230,6 +233,9 @@
File di intestazione
+
+ File di intestazione
+
diff --git a/OutScl.cpp b/OutScl.cpp
index 4ec4f7b..146dd41 100644
--- a/OutScl.cpp
+++ b/OutScl.cpp
@@ -276,6 +276,35 @@ OutScl::CircleCR( const Point3d& ptCen, double dRad)
return true ;
}
+//----------------------------------------------------------------------------
+bool
+OutScl::ArcCurvOrTgOrNone( const Point3d& ptFin, const Vector3d& vtT, const Vector3d& vtN, double dCurv)
+{
+ bool bCCW ;
+ double dAngCenDeg ;
+ Point3d ptCen ;
+
+
+ // curvatura
+ if ( fabs( dCurv) > EPS_ZERO) {
+ // tratto di arco
+ ptCen = ptFin + vtN / dCurv ;
+ bCCW = ( vtT ^ vtN).z > 0 ;
+ dAngCenDeg = ( bCCW ? 1 : -1) * 4 * dCurv * RADTODEG ;
+ ArcCPA( ptCen, ptFin, dAngCenDeg) ;
+ // raggio
+ Line2P( ptFin, ptCen) ;
+ }
+ // altrimenti, tangente
+ else if ( ! vtT.IsSmall())
+ Line2P( ptFin - vtT, ptFin + vtT) ;
+ // altrimenti cerchietto
+ else
+ CircleCR( ptFin, 1) ;
+
+ return true ;
+}
+
//----------------------------------------------------------------------------
bool
OutScl::PutCurve( const IGeoObj* pCurve, int nFlag)
@@ -312,34 +341,31 @@ OutScl::PutCurveLine( const ICurveLine& CrvLine)
bool
OutScl::PutCurveArc( const ICurveArc& CrvArc, int nFlag)
{
- int i ;
- double dU ;
- double dCurv ;
- Point3d ptFin ;
- Vector3d vtT ;
- Vector3d vtN ;
- UPNTVECTOR vUPoints ;
+ bool bFound ;
+ double dU ;
+ double dCurv ;
+ Point3d ptIni ;
+ Point3d ptFin ;
+ Vector3d vtT ;
+ Vector3d vtN ;
+ PolyLine PL ;
// ciclo sui segmenti
Remark( "CurveArc") ;
- CrvArc.ApproxWithLines( 0.1, 5, vUPoints) ;
- for ( i = 1 ; i < (int) vUPoints.size() ; ++ i) {
- Line2P( vUPoints[i-1].second, vUPoints[i].second) ;
+ CrvArc.ApproxWithLines( 0.1, 5, PL) ;
+ for ( bFound = PL.GetFirstLine( ptIni, ptFin) ; bFound ; bFound = PL.GetNextLine( ptIni, ptFin)) {
+ Line2P( ptIni, ptFin) ;
}
// se richieste derivate e curvature
if ( ( nFlag & 1) != 0) {
// ciclo per disegnare le derivate
Remark( "ArcTangents+Der2") ;
- for ( i = 0 ; i < (int) vUPoints.size() ; ++ i) {
- // ricavo il punto
- dU = vUPoints[i].first ;
+ for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) {
+ // ricavo il punto, la tangente, la normale e la curvatura
CrvArc.GetPointTangNormCurv( dU, ptFin, vtT, vtN, dCurv) ;
- // tangente
- Line2P( ptFin - vtT, ptFin + vtT) ;
- // curvatura
- if ( fabs( dCurv) > EPS_ZERO)
- Line2P( ptFin, ptFin + vtN / dCurv) ;
+ // curvatura o tangente o niente
+ ArcCurvOrTgOrNone( ptFin, vtT, vtN, dCurv) ;
}
}
@@ -350,16 +376,14 @@ OutScl::PutCurveArc( const ICurveArc& CrvArc, int nFlag)
bool
OutScl::PutCurveBez( const ICurveBezier& CrvBez, int nFlag)
{
- bool bCCW ;
- int i ;
- double dU ;
- double dCurv ;
- double dAngCenDeg ;
- Point3d ptFin ;
- Point3d ptCen ;
- Vector3d vtT ;
- Vector3d vtN ;
- UPNTVECTOR vUPoints ;
+ bool bFound ;
+ double dU ;
+ double dCurv ;
+ Point3d ptIni ;
+ Point3d ptFin ;
+ Vector3d vtT ;
+ Vector3d vtN ;
+ PolyLine PL ;
// se richiesto anche il poligono di controllo
@@ -368,34 +392,19 @@ OutScl::PutCurveBez( const ICurveBezier& CrvBez, int nFlag)
// ciclo per disegnare i segmenti
Remark( "BezierCurve") ;
- CrvBez.ApproxWithLines( 0.1, 5, vUPoints) ;
- for ( i = 1 ; i < (int) vUPoints.size() ; ++ i) {
- Line2P( vUPoints[i-1].second, vUPoints[i].second) ;
+ CrvBez.ApproxWithLines( 0.1, 5, PL) ;
+ for ( bFound = PL.GetFirstLine( ptIni, ptFin) ; bFound ; bFound = PL.GetNextLine( ptIni, ptFin)) {
+ Line2P( ptIni, ptFin) ;
}
// se richieste derivate e curvature
if ( ( nFlag & 1) != 0) {
// ciclo per disegnare le derivate e le curvature
Remark( "BezierTangents+Der2") ;
- for ( i = 0 ; i < (int) vUPoints.size() ; ++ i) {
- // ricavo il punto
- dU = vUPoints[i].first ;
+ for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) {
+ // ricavo il punto, la tangente, la normale e la curvatura
CrvBez.GetPointTangNormCurv( dU, ptFin, vtT, vtN, dCurv) ;
- // curvatura
- if ( fabs( dCurv) > EPS_ZERO) {
- // tratto di arco
- ptCen = ptFin + vtN / dCurv ;
- bCCW = ( vtT ^ vtN).z > 0 ;
- dAngCenDeg = ( bCCW ? 1 : -1) * 4 * dCurv * RADTODEG ;
- ArcCPA( ptCen, ptFin, dAngCenDeg) ;
- // raggio
- Line2P( ptFin, ptCen) ;
- }
- // altrimenti, tangente
- else if ( ! vtT.IsSmall())
- Line2P( ptFin - vtT, ptFin + vtT) ;
- // altrimenti cerchietto
- else
- CircleCR( ptFin, 1) ;
+ // curvatura o tangente o niente
+ ArcCurvOrTgOrNone( ptFin, vtT, vtN, dCurv) ;
}
}
@@ -413,11 +422,11 @@ OutScl::PutPolygBez( const ICurveBezier& CrvBez)
// ciclo per disegnare il poligono di controllo
Remark( "BezierPolygon") ;
- for ( i = 0 ; i <= CrvBez.GetDegree() ; ++ i) {
+ ptIni = CrvBez.GetControlPoint( 0) ;
+ for ( i = 1 ; i <= CrvBez.GetDegree() ; ++ i) {
ptFin = CrvBez.GetControlPoint( i) ;
- // dopo il primo, disegno
- if ( i > 0)
- Line2P( ptIni, ptFin) ;
+ // disegno
+ Line2P( ptIni, ptFin) ;
// nuovo iniziale prende i valori del finale
ptIni = ptFin ;
}
@@ -429,27 +438,39 @@ OutScl::PutPolygBez( const ICurveBezier& CrvBez)
bool
OutScl::PutCurveCompo( const ICurveComposite& CrvCompo, int nFlag)
{
- const ICurve* pCrvSmpl ;
+ bool bFound ;
+ double dU ;
+ double dCurv ;
+ Point3d ptIni ;
+ Point3d ptFin ;
+ Vector3d vtT ;
+ Vector3d vtN ;
+ PolyLine PL ;
- pCrvSmpl = CrvCompo.GetFirstCurve() ;
- while ( pCrvSmpl != nullptr) {
- // scrittura comandi SCL
- Remark( "CurveComposite") ;
- // secondo il tipo
- switch ( pCrvSmpl->GetType()) {
- case CRV_LINE :
- PutCurveLine( *::GetCurveLine( pCrvSmpl)) ;
- break ;
- case CRV_ARC :
- PutCurveArc( *::GetCurveArc( pCrvSmpl), nFlag) ;
- break ;
- case CRV_BEZ :
- PutCurveBez( *::GetCurveBezier( pCrvSmpl), nFlag) ;
- break ;
+ // ciclo per disegnare i segmenti
+ Remark( "CurveComposite") ;
+ CrvCompo.ApproxWithLines( 0.1, 5, PL) ;
+ for ( bFound = PL.GetFirstLine( ptIni, ptFin) ; bFound ; bFound = PL.GetNextLine( ptIni, ptFin)) {
+ Line2P( ptIni, ptFin) ;
+ }
+ // se richieste derivate e curvature
+ if ( ( nFlag & 1) != 0) {
+ // ciclo per disegnare le derivate e le curvature
+ Remark( "CompositeTangents+Der2") ;
+ for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) {
+ // ricavo il punto, la tangente, la normale e la curvatura
+ CrvCompo.GetPointTangNormCurv( dU, ptFin, vtT, vtN, dCurv) ;
+ // curvatura o tangente o niente
+ ArcCurvOrTgOrNone( ptFin, vtT, vtN, dCurv) ;
+ // se alla giunzione tra due curve semplici, calcolo anche appena dopo
+ if ( CrvCompo.IsParamAtJoint( dU)) {
+ // ricavo il punto, la tangente, la normale e la curvatura
+ CrvCompo.GetPointTangNormCurv( dU + EPS_ZERO, ptFin, vtT, vtN, dCurv) ;
+ // curvatura o tangente o niente
+ ArcCurvOrTgOrNone( ptFin, vtT, vtN, dCurv) ;
+ }
}
- // passo alla successiva
- pCrvSmpl = CrvCompo.GetNextCurve() ;
}
return true ;
diff --git a/OutScl.h b/OutScl.h
index b218bbb..f3c82de 100644
--- a/OutScl.h
+++ b/OutScl.h
@@ -50,6 +50,7 @@ class OutScl
bool Arc3P( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptP3) ;
bool ArcCPA( const Point3d& ptCen, const Point3d& ptMed, double dAngCenDeg) ;
bool CircleCR( const Point3d& ptCen, double dRad) ;
+ bool ArcCurvOrTgOrNone( const Point3d& ptFin, const Vector3d& vtT, const Vector3d& vtN, double dCurv) ;
private :
std::ofstream m_ofFile ;
diff --git a/PolyLine.cpp b/PolyLine.cpp
new file mode 100644
index 0000000..0669d2b
--- /dev/null
+++ b/PolyLine.cpp
@@ -0,0 +1,177 @@
+//----------------------------------------------------------------------------
+// EgalTech 2013-2013
+//----------------------------------------------------------------------------
+// File : DistPointLine.cpp Data : 22.12.13 Versione : 1.4l3
+// Contenuto : Implementazione dell'oggetto PolyLine.
+//
+//
+//
+// Modifiche : 22.12.13 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+//--------------------------- Include ----------------------------------------
+#include "stdafx.h"
+#include "\EgtDev\Include\EGkPolyLine.h"
+
+
+//----------------------------------------------------------------------------
+PolyLine::PolyLine( void)
+{
+ m_nCount = 0 ;
+ m_iter = m_lUPoints.end() ;
+}
+
+//----------------------------------------------------------------------------
+PolyLine::~PolyLine( void)
+{
+}
+
+//----------------------------------------------------------------------------
+bool
+PolyLine::AddUPoint( double dPar, const Point3d& ptP)
+{
+ try {
+ m_lUPoints.push_back( UPOINT( dPar, ptP)) ;
+ }
+ catch (...) {
+ return false ;
+ }
+
+ m_nCount ++ ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+PolyLine::EraseFirstUPoint( void)
+{
+ if ( m_lUPoints.begin() == m_lUPoints.end())
+ return false ;
+
+ m_lUPoints.pop_front() ;
+ m_nCount -- ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+PolyLine::AddOffsetToU( double dOffset)
+{
+ UPNTLIST::iterator iter ;
+
+
+ for ( iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter)
+ iter->first += dOffset ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+PolyLine::Splice( PolyLine& PL)
+{
+ m_lUPoints.splice( m_lUPoints.end(), PL.m_lUPoints) ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+PolyLine::GetFirstUPoint( double* pdPar, Point3d* pptP)
+{
+ m_iter = m_lUPoints.begin() ;
+ if ( m_iter == m_lUPoints.end())
+ return false ;
+
+ if ( pdPar != nullptr)
+ *pdPar = m_iter->first ;
+ if ( pptP != nullptr)
+ *pptP = m_iter->second ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+PolyLine::GetNextUPoint( double* pdPar, Point3d* pptP)
+{
+ ++ m_iter ;
+ if ( m_iter == m_lUPoints.end())
+ return false ;
+
+ if ( pdPar != nullptr)
+ *pdPar = m_iter->first ;
+ if ( pptP != nullptr)
+ *pptP = m_iter->second ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+PolyLine::GetLastUPoint( double* pdPar, Point3d* pptP)
+{
+ if ( m_lUPoints.begin() == m_lUPoints.end())
+ return false ;
+
+ if ( pdPar != nullptr)
+ *pdPar = m_lUPoints.back().first ;
+ if ( pptP != nullptr)
+ *pptP = m_lUPoints.back().second ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+PolyLine::GetFirstULine( double* pdIni, Point3d* pptIni, double* pdFin, Point3d* pptFin)
+{
+ // parametro e punto iniziali
+ m_iter = m_lUPoints.begin() ;
+ if ( m_iter == m_lUPoints.end())
+ return false ;
+ if ( pdIni != nullptr)
+ *pdIni = m_iter->first ;
+ if ( pptIni != nullptr)
+ *pptIni = m_iter->second ;
+
+ // parametro e punto finali
+ ++ m_iter ;
+ if ( m_iter == m_lUPoints.end())
+ return false ;
+ if ( pdFin != nullptr)
+ *pdFin = m_iter->first ;
+ if ( pptFin != nullptr)
+ *pptFin = m_iter->second ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+PolyLine::GetNextULine( double* pdIni, Point3d* pptIni, double* pdFin, Point3d* pptFin)
+{
+ // parametro e punto iniziali (è il precedente finale)
+ if ( m_iter == m_lUPoints.end())
+ return false ;
+ if ( pdIni != nullptr)
+ *pdIni = m_iter->first ;
+ if ( pptIni != nullptr)
+ *pptIni = m_iter->second ;
+
+ // parametro e punto finali
+ ++ m_iter ;
+ if ( m_iter == m_lUPoints.end())
+ return false ;
+ if ( pdFin != nullptr)
+ *pdFin = m_iter->first ;
+ if ( pptFin != nullptr)
+ *pptFin = m_iter->second ;
+
+ return true ;
+}
+