EgtGeomKernel 1.4l3 : Modifiche a ApproxWithLines anche per CurveComposite.

Aggiunta classe PolyLine.
This commit is contained in:
Dario Sassi
2013-12-24 22:09:55 +00:00
parent 30f8c71894
commit 2cd7dcee57
14 changed files with 381 additions and 133 deletions
+3 -6
View File
@@ -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 ;
+6 -6
View File
@@ -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) ;
+17 -21
View File
@@ -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 ;
}
+11 -11
View File
@@ -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} ;
+47
View File
@@ -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 ;
}
+10 -8
View File
@@ -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) ;
+3 -4
View File
@@ -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 ;
}
+5 -5
View File
@@ -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) ;
BIN
View File
Binary file not shown.
+2
View File
@@ -138,6 +138,7 @@ copy $(TargetPath) \EgtProg\Dll</Command>
<ClCompile Include="GeoVector3d.cpp" />
<ClCompile Include="OutScl.cpp" />
<ClCompile Include="Point3d.cpp" />
<ClCompile Include="PolyLine.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
@@ -164,6 +165,7 @@ copy $(TargetPath) \EgtProg\Dll</Command>
<ClInclude Include="..\Include\EGkGeoType.h" />
<ClInclude Include="..\Include\EGkGeoVector3d.h" />
<ClInclude Include="..\Include\EGkPoint3d.h" />
<ClInclude Include="..\Include\EGkPolyLine.h" />
<ClInclude Include="..\Include\EGkVector3d.h" />
<ClInclude Include="..\Include\EgnGetModuleVer.h" />
<ClInclude Include="..\Include\EGnStringUtils.h" />
+6
View File
@@ -96,6 +96,9 @@
<ClCompile Include="DistPointLine.cpp">
<Filter>File di origine\Base</Filter>
</ClCompile>
<ClCompile Include="PolyLine.cpp">
<Filter>File di origine\Base</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@@ -230,6 +233,9 @@
<ClInclude Include="DllMain.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkPolyLine.h">
<Filter>File di intestazione</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="EgtGeomKernel.rc">
+93 -72
View File
@@ -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 ;
+1
View File
@@ -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 ;
+177
View File
@@ -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 ;
}