EgtGeomKernel 1.5h3 :
- aggiunta IsFlat a tutte le Curve - aggiunta ApproxWithArcs a tutte le Curve - aggiunto oggetto PolyArc (raccolta ordinata di linee e archi con bulge) - aggiunto oggetto PointsPCA per stima componenti principali di un insieme di punti - FromSpheriical e FromPolar di Vector3d sono diventati funzioni e aggiunto FromUprightOrtho - aggiunte Invert e a Vector3d.
This commit is contained in:
+2
-4
@@ -176,8 +176,7 @@ GetArc2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStartDeg)
|
||||
// calcolo arco non riuscito, verifico se retta va bene
|
||||
Vector3d vtDiff = ptEnd - ptStart ;
|
||||
vtDiff.z = 0 ;
|
||||
Vector3d vtDir ;
|
||||
vtDir.FromPolar( 1, dDirStartDeg) ;
|
||||
Vector3d vtDir = FromPolar( 1, dDirStartDeg) ;
|
||||
// verifico se i punti sono allineati con la direzione e nel giusto verso
|
||||
if ( fabs( CrossXY( vtDiff, vtDir)) < EPS_SMALL && ScalarXY( vtDiff, vtDir) > EPS_SMALL) {
|
||||
// creo l'oggetto retta
|
||||
@@ -204,8 +203,7 @@ GetArcPntDirTgArc( const Point3d& ptP, double dDirStartDeg, const ICurveArc& crv
|
||||
}
|
||||
|
||||
// versore ortogonale alla direzione iniziale (si lavora nel piano XY locale)
|
||||
Vector3d vtOrtho ;
|
||||
vtOrtho.FromPolar( 1, dDirStartDeg) ;
|
||||
Vector3d vtOrtho = FromPolar( 1, dDirStartDeg) ;
|
||||
vtOrtho.Rotate( Z_AX, 0, 1) ;
|
||||
|
||||
// calcolo arco spostando il punto iniziale di + raggio in direzione ortogonale
|
||||
|
||||
+2
-2
@@ -88,7 +88,7 @@ CalcCircleStartDer( double dU0, const Point3d& ptP0, double dU1, const Point3d&
|
||||
vtDer = ptP0 - ptCen ;
|
||||
vtDer.Rotate( vtN, 0, 1) ;
|
||||
if ( ( vtDer * vtA) < 0)
|
||||
vtDer *= - 1 ;
|
||||
vtDer.Invert() ;
|
||||
// ne aggiusto il modulo
|
||||
if ( ! vtDer.Normalize())
|
||||
return false ;
|
||||
@@ -120,7 +120,7 @@ CalcCircleEndDer( double dU0, const Point3d& ptP0, double dU1, const Point3d& pt
|
||||
vtDer = ptP2 - ptCen ;
|
||||
vtDer.Rotate( vtN, 0, 1) ;
|
||||
if ( ( vtDer * ( ptP2 - ptP1)) < 0)
|
||||
vtDer *= - 1 ;
|
||||
vtDer.Invert() ;
|
||||
// ne aggiusto il modulo
|
||||
if ( ! vtDer.Normalize())
|
||||
return false ;
|
||||
|
||||
+60
-11
@@ -124,7 +124,7 @@ CurveArc::SetXY( const Point3d& ptCen, double dRad, double dAngIniDeg, double dA
|
||||
// assegno e calcolo i dati
|
||||
m_PtCen = ptCen ;
|
||||
m_VtN = Z_AX ;
|
||||
m_VtS.FromPolar( 1, dAngIniDeg) ;
|
||||
m_VtS = FromPolar( 1, dAngIniDeg) ;
|
||||
m_dRad = dRad ;
|
||||
m_dAngCenDeg = dAngCenDeg ;
|
||||
m_dDeltaN = dDeltaZ ;
|
||||
@@ -278,8 +278,7 @@ CurveArc::Set2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStart
|
||||
m_nStatus = ERR ;
|
||||
|
||||
// vettore tangente iniziale ( nel piano XY)
|
||||
Vector3d vtA ;
|
||||
vtA.FromPolar( 1, dDirStartDeg) ;
|
||||
Vector3d vtA = FromPolar( 1, dDirStartDeg) ;
|
||||
// vettore da inizio a fine ( nel piano XY)
|
||||
Vector3d vtB = ptEnd - ptStart ;
|
||||
vtB.z = 0 ;
|
||||
@@ -313,9 +312,9 @@ CurveArc::Set2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStart
|
||||
|
||||
// se normale con Z negativa, inverto senza modificare la geometria
|
||||
if ( m_VtN.z < 0) {
|
||||
m_VtN *= - 1 ;
|
||||
m_dAngCenDeg *= - 1 ;
|
||||
m_dDeltaN *= - 1 ;
|
||||
m_VtN.Invert() ;
|
||||
m_dAngCenDeg = - m_dAngCenDeg ;
|
||||
m_dDeltaN = - m_dDeltaN ;
|
||||
}
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
@@ -605,6 +604,21 @@ CurveArc::Validate( void)
|
||||
return ( m_nStatus == OK) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveArc::IsFlat( Plane3d& plPlane, double dToler) const
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// assegno dati possibile piano
|
||||
plPlane.vtN = m_VtN ;
|
||||
plPlane.dDist = ( m_PtCen - ORIG) * plPlane.vtN ;
|
||||
// verifico piattezza
|
||||
return IsFlat( dToler) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveArc::GetStartPoint( Point3d& ptStart) const
|
||||
@@ -845,8 +859,43 @@ CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) cons
|
||||
ArcApproxer aAppr( dLinTol, dAngTolDeg, true, *this) ;
|
||||
double dU ;
|
||||
Point3d ptPos ;
|
||||
while ( aAppr.GetPoint( dU, ptPos))
|
||||
PL.AddUPoint( dU, ptPos) ;
|
||||
while ( aAppr.GetPoint( dU, ptPos)) {
|
||||
if ( ! PL.AddUPoint( dU, ptPos))
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveArc::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const
|
||||
{
|
||||
// pulisco la polilinea
|
||||
PA.Clear() ;
|
||||
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// la curva deve avere normale coincidente con Z
|
||||
if ( ! m_VtN.IsZplus() && ! m_VtN.IsZminus())
|
||||
return false ;
|
||||
|
||||
// inserisco punto iniziale con bulge
|
||||
Point3d ptStart ;
|
||||
GetStartPoint( ptStart) ;
|
||||
double dBulge = tan( m_dAngCenDeg / 4 * DEGTORAD) ;
|
||||
if ( m_VtN.IsZminus())
|
||||
dBulge = - dBulge ;
|
||||
if ( ! PA.AddUPoint( 0, ptStart, dBulge))
|
||||
return false ;
|
||||
|
||||
// inserisco punto finale senza bulge
|
||||
Point3d ptEnd ;
|
||||
GetEndPoint( ptEnd) ;
|
||||
if ( ! PA.AddUPoint( 1, ptEnd, 0))
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -1357,9 +1406,9 @@ CurveArc::InvertN( void)
|
||||
return false ;
|
||||
|
||||
// si inverte il verso della normale senza modificare la geometria dell'arco
|
||||
m_VtN *= - 1 ;
|
||||
m_dAngCenDeg *= - 1 ;
|
||||
m_dDeltaN *= - 1 ;
|
||||
m_VtN.Invert() ;
|
||||
m_dAngCenDeg = - m_dAngCenDeg ;
|
||||
m_dDeltaN = - m_dDeltaN ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
+16
-2
@@ -55,6 +55,7 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
{ return true ; }
|
||||
virtual bool IsClosed( void) const
|
||||
{ return ::IsClosed( *this) ; }
|
||||
virtual bool IsFlat( Plane3d& plPlane, double dToler = EPS_SMALL) const ;
|
||||
virtual bool GetStartPoint( Point3d& ptStart) const ;
|
||||
virtual bool GetEndPoint( Point3d& ptEnd) const ;
|
||||
virtual bool GetMidPoint( Point3d& ptMid) const ;
|
||||
@@ -85,6 +86,7 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
return ::GetPointDiffGeom( *this, dU, nS, oDiffG) ; }
|
||||
virtual bool IsPointOn( const Point3d& ptP, double dTol = EPS_SMALL) const ;
|
||||
virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ;
|
||||
virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ;
|
||||
virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ;
|
||||
virtual bool Invert( void) ;
|
||||
virtual bool Offset( double dDist, int nSide, int nType = OFF_FILLET) ;
|
||||
@@ -108,8 +110,8 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
virtual bool Set2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStartDeg) ;
|
||||
virtual bool Set2PRS( const Point3d& ptStart, const Point3d& ptEnd, double dRad, bool bCCW = true) ;
|
||||
virtual bool SetC2P( const Point3d& ptCen, const Point3d& ptStart, const Point3d& ptNearEnd) ;
|
||||
virtual bool IsFlat( void) const
|
||||
{ return ( fabs( m_dDeltaN) < EPS_SMALL) ; }
|
||||
virtual bool IsFlat( double dToler = EPS_SMALL) const
|
||||
{ return ( fabs( m_dDeltaN) < dToler) ; }
|
||||
virtual bool IsACircle( void) const
|
||||
{ return ( IsFlat() && IsClosed()) ; }
|
||||
virtual bool IsInPlaneXY( void) const
|
||||
@@ -164,3 +166,15 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
double m_dAngCenDeg ; // angolo al centro in gradi (positivo se antiorario visto da VtN)
|
||||
double m_dDeltaN ; // variazione di quota lungo VtN della fine rispetto all'inizio
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CurveArc* CreateBasicCurveArc( void)
|
||||
{ return (static_cast<CurveArc*>( CreateGeoObj( CRV_ARC))) ; }
|
||||
inline CurveArc* CloneBasicCurveArc( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_ARC)
|
||||
return nullptr ;
|
||||
return (static_cast<CurveArc*>(pGObj->Clone())) ; }
|
||||
inline const CurveArc* GetBasicCurveArc( const IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<const CurveArc*>(pGObj)) ; }
|
||||
inline CurveArc* GetBasicCurveArc( IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<CurveArc*>(pGObj)) ; }
|
||||
|
||||
+2
-2
@@ -110,7 +110,7 @@ GetPointTang( const ICurve& crvC, double dU, ICurve::Side nS, Point3d& ptPos, Ve
|
||||
if ( ! crvC.GetPointD1D2( dU, nS, ptDummy, &vtD1near))
|
||||
return false ;
|
||||
if ( ( vtTang * vtD1near) < 0)
|
||||
vtTang *= - 1 ;
|
||||
vtTang.Invert() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ GetPointDiffGeom( const ICurve& crvC, double dU, ICurve::Side nS, CrvPointDiffGe
|
||||
dU += ( nS == ICurve::FROM_MINUS ? -1 : +1) * 100 * EPS_PARAM ;
|
||||
if ( crvC.GetPointD1D2( dU, nS, ptDummy, &vtD1near)) {
|
||||
if ( ( oDiffG.vtT * vtD1near) < 0)
|
||||
oDiffG.vtT *= - 1 ;
|
||||
oDiffG.vtT.Invert() ;
|
||||
oDiffG.nStatus = CrvPointDiffGeom::TANG ;
|
||||
}
|
||||
else {
|
||||
|
||||
+62
-6
@@ -473,6 +473,52 @@ CurveBezier::GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::IsFlat( Plane3d& plPlane, double dToler) const
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// polilinea dei punti rappresentativi
|
||||
PolyLine shPL ;
|
||||
int nLastPC = m_nDeg ;
|
||||
for ( int i = 0 ; i <= nLastPC ; ++ i) {
|
||||
double dU = i / double( nLastPC) ;
|
||||
if ( ! shPL.AddUPoint( dU, GetControlPoint( i)))
|
||||
return false ;
|
||||
}
|
||||
// recupero dati sulla planarità
|
||||
int nRank ;
|
||||
Point3d ptCen ;
|
||||
Vector3d vtDir ;
|
||||
bool bFlat = shPL.IsFlat( nRank, ptCen, vtDir, dToler) ;
|
||||
// se punto
|
||||
switch ( nRank) {
|
||||
case 0 : // punto
|
||||
if ( bFlat) {
|
||||
plPlane.vtN = Z_AX ;
|
||||
plPlane.dDist = ( ptCen - ORIG) * plPlane.vtN ;
|
||||
}
|
||||
else {
|
||||
plPlane.vtN = V_NULL ;
|
||||
plPlane.dDist = 0 ;
|
||||
}
|
||||
break ;
|
||||
case 1 : // linea
|
||||
plPlane.vtN = FromUprightOrtho( vtDir) ;
|
||||
plPlane.dDist = ( ptCen - ORIG) * plPlane.vtN ;
|
||||
break ;
|
||||
default : // piana o 3d
|
||||
plPlane.vtN = vtDir ;
|
||||
plPlane.dDist = ( ptCen - ORIG) * plPlane.vtN ;
|
||||
break ;
|
||||
}
|
||||
|
||||
return bFlat ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::GetStartPoint( Point3d& ptStart) const
|
||||
@@ -1201,9 +1247,7 @@ CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) c
|
||||
|
||||
// se di primo grado, basta inserire gli estremi
|
||||
if ( m_nDeg == 1) {
|
||||
PL.AddUPoint( 0, m_aPtCtrl[0]) ;
|
||||
PL.AddUPoint( 1, m_aPtCtrl[m_nDeg]) ;
|
||||
return true ;
|
||||
return ( PL.AddUPoint( 0, m_aPtCtrl[0]) && PL.AddUPoint( 1, m_aPtCtrl[m_nDeg])) ;
|
||||
}
|
||||
|
||||
// limiti minimi su tolleranza e deviazione angolare
|
||||
@@ -1211,18 +1255,30 @@ CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) c
|
||||
dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ;
|
||||
|
||||
// inserisco il punto iniziale
|
||||
PL.AddUPoint( 0, m_aPtCtrl[0]) ;
|
||||
if ( ! PL.AddUPoint( 0, m_aPtCtrl[0]))
|
||||
return false ;
|
||||
|
||||
// verifico se va divisa
|
||||
FlatOrSplit( 0, *this, 0, 1, dLinTol, dAngTolDeg, PL) ;
|
||||
if ( ! FlatOrSplit( 0, *this, 0, 1, dLinTol, dAngTolDeg, PL))
|
||||
return false ;
|
||||
|
||||
// se è stato inserito un solo punto, aggiungo il finale
|
||||
if ( PL.GetPointNbr() == 1)
|
||||
PL.AddUPoint( 1, m_aPtCtrl[m_nDeg]) ;
|
||||
return PL.AddUPoint( 1, m_aPtCtrl[m_nDeg]) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const
|
||||
{
|
||||
// pulisco la polilinea
|
||||
PA.Clear() ;
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
CurveBezier::CopyParamRange( double dUStart, double dUEnd) const
|
||||
|
||||
@@ -56,6 +56,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
virtual bool IsSimple( void) const { return true ; }
|
||||
virtual bool IsClosed( void) const
|
||||
{ return ::IsClosed( *this) ; }
|
||||
virtual bool IsFlat( Plane3d& plPlane, double dToler) const ;
|
||||
virtual bool GetStartPoint( Point3d& ptStart) const ;
|
||||
virtual bool GetEndPoint( Point3d& ptEnd) const ;
|
||||
virtual bool GetMidPoint( Point3d& ptMid) const ;
|
||||
@@ -87,6 +88,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
return ::GetPointDiffGeom( *this, dU, nS, oDiffG) ; }
|
||||
virtual bool IsPointOn( const Point3d& ptP, double dTol = EPS_SMALL) const ;
|
||||
virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ;
|
||||
virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ;
|
||||
virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ;
|
||||
virtual bool Invert( void) ;
|
||||
virtual bool Offset( double dDist, int nSide, int nType = OFF_FILLET)
|
||||
@@ -159,3 +161,15 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
Point3d m_aStPtCtrl[ST_PTC] ; // array predefinito di 4 punti di controllo
|
||||
double m_aStWeCtrl[ST_PTC] ; // array predefinito di 4 pesi di controllo
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CurveBezier* CreateBasicCurveBezier( void)
|
||||
{ return (static_cast<CurveBezier*>( CreateGeoObj( CRV_BEZ))) ; }
|
||||
inline CurveBezier* CloneBasicCurveBezier( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_BEZ)
|
||||
return nullptr ;
|
||||
return (static_cast<CurveBezier*>(pGObj->Clone())) ; }
|
||||
inline const CurveBezier* GetBasicCurveBezier( const IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<const CurveBezier*>(pGObj)) ; }
|
||||
inline CurveBezier* GetBasicCurveBezier( IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<CurveBezier*>(pGObj)) ; }
|
||||
|
||||
+132
-12
@@ -15,14 +15,14 @@
|
||||
#include "stdafx.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "DistPointCrvComposite.h"
|
||||
#include "CurveLine.h"
|
||||
#include "CurveArc.h"
|
||||
#include "CurveBezier.h"
|
||||
#include "GeoConst.h"
|
||||
#include "GeoObjFactory.h"
|
||||
#include "NgeWriter.h"
|
||||
#include "NgeReader.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EGkCurveLine.h"
|
||||
#include "/EgtDev/Include/EGkCurveArc.h"
|
||||
#include "/EgtDev/Include/EGkCurveBezier.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <algorithm>
|
||||
|
||||
@@ -325,7 +325,7 @@ CurveComposite::FromPointBulgeVector( const UPNTVECTOR& vUPnt, const Vector3d& v
|
||||
// se retta
|
||||
if ( fabs( vUPnt[i-1].first) < EPS_SMALL) {
|
||||
// creo la retta
|
||||
PtrOwner<ICurveLine> pCrvLine( CreateCurveLine()) ;
|
||||
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
|
||||
if ( ! ::IsValid( pCrvLine))
|
||||
return false ;
|
||||
// setto la linea
|
||||
@@ -338,7 +338,7 @@ CurveComposite::FromPointBulgeVector( const UPNTVECTOR& vUPnt, const Vector3d& v
|
||||
// altrimenti arco
|
||||
else {
|
||||
// creo l'arco
|
||||
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
|
||||
PtrOwner<CurveArc> pCrvArc( CreateBasicCurveArc()) ;
|
||||
if ( ! ::IsValid( pCrvArc))
|
||||
return false ;
|
||||
// setto l'arco
|
||||
@@ -384,7 +384,7 @@ CurveComposite::PolygonCenterCorner( int nSides, const Point3d& ptCen, const Poi
|
||||
return false ;
|
||||
}
|
||||
// creo il segmento di retta
|
||||
PtrOwner<ICurveLine> pCrvLine( CreateCurveLine()) ;
|
||||
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
|
||||
if ( ! ::IsValid( pCrvLine))
|
||||
return false ;
|
||||
// assegno i punti estremi
|
||||
@@ -473,11 +473,11 @@ bool
|
||||
CurveComposite::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
// se sorgente è una curva composita
|
||||
const CurveComposite* pCC = dynamic_cast<const CurveComposite*>( pGObjSrc) ;
|
||||
const CurveComposite* pCC = GetBasicCurveComposite( pGObjSrc) ;
|
||||
if ( pCC != nullptr)
|
||||
return CopyFrom( *pCC) ;
|
||||
// se sorgente è un'altro tipo di curva
|
||||
const ICurve* pCrv = dynamic_cast<const ICurve*>( pGObjSrc) ;
|
||||
const ICurve* pCrv = GetCurve( pGObjSrc) ;
|
||||
if ( pCrv != nullptr) {
|
||||
Clear() ;
|
||||
return AddCurve( *pCrv) ;
|
||||
@@ -716,6 +716,89 @@ CurveComposite::Validate( void)
|
||||
return ( m_nStatus == OK) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::IsFlat( Plane3d& plPlane, double dToler) const
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// polilinea dei punti rappresentativi
|
||||
PolyLine shPL ;
|
||||
// punto iniziale
|
||||
Point3d ptP ;
|
||||
if ( ! GetStartPoint( ptP) ||
|
||||
! shPL.AddUPoint( 0, ptP))
|
||||
return false ;
|
||||
// ciclo sulle curve semplici (aggiungo solo eventuali punti intermedi e finali)
|
||||
int nCount = 0 ;
|
||||
for ( const ICurve* pCrv = GetFirstCurve() ;
|
||||
pCrv != nullptr ;
|
||||
pCrv = GetNextCurve(), ++ nCount) {
|
||||
switch ( pCrv->GetType()) {
|
||||
case CRV_LINE :
|
||||
// punto finale
|
||||
if ( ! pCrv->GetEndPoint( ptP) ||
|
||||
! shPL.AddUPoint( nCount + 1, ptP))
|
||||
return false ;
|
||||
break ;
|
||||
case CRV_ARC :
|
||||
// punto a 1/3
|
||||
if ( ! pCrv->GetPointD1D2( 0.3333, ICurve::FROM_MINUS, ptP) ||
|
||||
! shPL.AddUPoint( nCount + 0.3333, ptP))
|
||||
return false ;
|
||||
// punto a 7/11
|
||||
if ( ! pCrv->GetPointD1D2( 0.6363, ICurve::FROM_MINUS, ptP) ||
|
||||
! shPL.AddUPoint( nCount + 0.6363, ptP))
|
||||
return false ;
|
||||
// punto finale
|
||||
if ( ! pCrv->GetEndPoint( ptP) ||
|
||||
! shPL.AddUPoint( nCount + 1, ptP))
|
||||
return false ;
|
||||
break ;
|
||||
case CRV_BEZ :
|
||||
{ const CurveBezier* pBez = GetBasicCurveBezier( pCrv) ;
|
||||
// inserisco tutti i punti di controllo tranne il primo
|
||||
int nLastPC = pBez->GetDegree() ;
|
||||
for ( int i = 1 ; i <= nLastPC ; ++ i) {
|
||||
double dU = nCount + i / double( nLastPC) ;
|
||||
if ( ! shPL.AddUPoint( dU, pBez->GetControlPoint( i)))
|
||||
return false ;
|
||||
}
|
||||
} break ;
|
||||
}
|
||||
}
|
||||
// recupero dati sulla planarità della polilinea
|
||||
int nRank ;
|
||||
Point3d ptCen ;
|
||||
Vector3d vtDir ;
|
||||
bool bFlat = shPL.IsFlat( nRank, ptCen, vtDir, dToler) ;
|
||||
// se punto
|
||||
switch ( nRank) {
|
||||
case 0 : // punto
|
||||
if ( bFlat) {
|
||||
plPlane.vtN = Z_AX ;
|
||||
plPlane.dDist = ( ptCen - ORIG) * plPlane.vtN ;
|
||||
}
|
||||
else {
|
||||
plPlane.vtN = V_NULL ;
|
||||
plPlane.dDist = 0 ;
|
||||
}
|
||||
break ;
|
||||
case 1 : // linea
|
||||
plPlane.vtN = FromUprightOrtho( vtDir) ;
|
||||
plPlane.dDist = ( ptCen - ORIG) * plPlane.vtN ;
|
||||
break ;
|
||||
default : // piana o 3d
|
||||
plPlane.vtN = vtDir ;
|
||||
plPlane.dDist = ( ptCen - ORIG) * plPlane.vtN ;
|
||||
break ;
|
||||
}
|
||||
|
||||
return bFlat ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::GetStartPoint( Point3d& ptStart) const
|
||||
@@ -999,6 +1082,43 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const
|
||||
{
|
||||
// pulisco il poliarco
|
||||
PA.Clear() ;
|
||||
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// eseguo approssimazione
|
||||
bool bFirst = true ;
|
||||
double dStartPar = 0 ;
|
||||
PolyArc PASmpl ;
|
||||
PCRVSMPL_DEQUE::const_iterator Iter ;
|
||||
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
|
||||
// recupero approssimazione per curva semplice
|
||||
if ( ! (*Iter)->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl))
|
||||
return false ;
|
||||
// la accodo opportunamente a quella della curva composita
|
||||
if ( bFirst) {
|
||||
PA.Splice( PASmpl) ;
|
||||
bFirst = false ;
|
||||
}
|
||||
else {
|
||||
PA.EraseLastUPoint() ;
|
||||
PASmpl.AddOffsetToU( dStartPar) ;
|
||||
PA.Splice( PASmpl) ;
|
||||
}
|
||||
// incremento inizio parametro per prossima curva semplice
|
||||
dStartPar += 1 ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
CurveComposite::CopyParamRange( double dUStart, double dUEnd) const
|
||||
@@ -1230,10 +1350,11 @@ CurveComposite::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim)
|
||||
if ( dUStartTrim < - EPS_PARAM || dUStartTrim > m_nCounter + EPS_PARAM ||
|
||||
dUEndTrim < - EPS_PARAM || dUEndTrim > m_nCounter + EPS_PARAM)
|
||||
return false ;
|
||||
#if 0
|
||||
// verifico che i trim non cancellino interamente la curva
|
||||
if ( dUStartTrim > dUEndTrim - EPS_PARAM)
|
||||
return false ;
|
||||
#if 0
|
||||
#endif
|
||||
// se il parametro start supera quello di end
|
||||
if ( dUStartTrim > dUEndTrim - EPS_PARAM) {
|
||||
// se curva aperta, il trim la cancella completamente quindi errore
|
||||
@@ -1252,7 +1373,6 @@ CurveComposite::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// per parametro start : determino la curva di appartenenza e il valore locale del parametro
|
||||
int nCs ;
|
||||
double dUcs ;
|
||||
@@ -1757,11 +1877,11 @@ CurveComposite::ArcsToBezierCurves( void)
|
||||
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
|
||||
// se arco, devo trasformare in una o più curve di Bezier
|
||||
if ( (*Iter)->GetType() == CRV_ARC) {
|
||||
const ICurveArc* pArc = GetCurveArc( (*Iter)) ;
|
||||
const CurveArc* pArc = GetBasicCurveArc( (*Iter)) ;
|
||||
// se angolo al centro sotto il limite, basta una curva
|
||||
if ( fabs( pArc->GetAngCenter()) <= BEZARC_ANG_CEN_MAX + EPS_ANG_SMALL) {
|
||||
// creo la curva di Bezier
|
||||
PtrOwner<ICurveBezier> pCrvBez( CreateCurveBezier()) ;
|
||||
PtrOwner<CurveBezier> pCrvBez( CreateBasicCurveBezier()) ;
|
||||
if ( ! ::IsValid( pCrvBez))
|
||||
return false ;
|
||||
if ( ! pCrvBez->FromArc( *pArc))
|
||||
|
||||
@@ -56,6 +56,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
virtual bool IsSimple( void) const { return false ; }
|
||||
virtual bool IsClosed( void) const
|
||||
{ return ( m_nStatus == OK && m_bClosed) ; }
|
||||
virtual bool IsFlat( Plane3d& plPlane, double dToler = EPS_SMALL) const ;
|
||||
virtual bool GetStartPoint( Point3d& ptStart) const ;
|
||||
virtual bool GetEndPoint( Point3d& ptEnd) const ;
|
||||
virtual bool GetMidPoint( Point3d& ptMid) const ;
|
||||
@@ -86,6 +87,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
return ::GetPointDiffGeom( *this, dU, nS, oDiffG) ; }
|
||||
virtual bool IsPointOn( const Point3d& ptP, double dTol = EPS_SMALL) const ;
|
||||
virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ;
|
||||
virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ;
|
||||
virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ;
|
||||
virtual bool Invert( void) ;
|
||||
virtual bool Offset( double dDist, int nSide, int nType = OFF_FILLET)
|
||||
@@ -154,3 +156,15 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
bool m_bClosed ; // flag per indicare che la curva è chiusa
|
||||
mutable PCRVSMPL_DEQUE::const_iterator m_Iter ; // iteratore
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CurveComposite* CreateBasicCurveComposite( void)
|
||||
{ return (static_cast<CurveComposite*>( CreateGeoObj( CRV_COMPO))) ; }
|
||||
inline CurveComposite* CloneBasicCurveComposite( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_COMPO)
|
||||
return nullptr ;
|
||||
return (static_cast<CurveComposite*>(pGObj->Clone())) ; }
|
||||
inline const CurveComposite* GetBasicCurveComposite( const IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<const CurveComposite*>(pGObj)) ; }
|
||||
inline CurveComposite* GetBasicCurveComposite( IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<CurveComposite*>(pGObj)) ; }
|
||||
|
||||
+31
-1
@@ -79,7 +79,7 @@ CurveLine::SetPDL( const Point3d& ptStart, double dDirAngDeg, double dLen)
|
||||
// assegno i dati
|
||||
m_PtStart = ptStart ;
|
||||
Vector3d vtDelta ;
|
||||
vtDelta.FromPolar( dLen, dDirAngDeg) ;
|
||||
vtDelta = FromPolar( dLen, dDirAngDeg) ;
|
||||
m_PtEnd = ptStart + vtDelta ;
|
||||
m_nStatus = TO_VERIFY ;
|
||||
|
||||
@@ -229,6 +229,21 @@ CurveLine::Validate( void)
|
||||
return ( m_nStatus == OK) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveLine::IsFlat( Plane3d& plPlane, double dToler) const
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// assegno dati piano
|
||||
plPlane.vtN = FromUprightOrtho( m_PtEnd - m_PtStart) ; ;
|
||||
plPlane.dDist = ( m_PtStart - ORIG) * plPlane.vtN ;
|
||||
// ritorno conferma
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveLine::GetStartPoint( Point3d& ptStart) const
|
||||
@@ -422,6 +437,21 @@ CurveLine::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) con
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveLine::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const
|
||||
{
|
||||
// pulisco la polilinea
|
||||
PA.Clear() ;
|
||||
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// inserisco gli estremi
|
||||
return ( PA.AddUPoint( 0, m_PtStart, 0) && PA.AddUPoint( 1, m_PtEnd, 0)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
CurveLine::CopyParamRange( double dUStart, double dUEnd) const
|
||||
|
||||
+14
@@ -55,6 +55,7 @@ class CurveLine : public ICurveLine, public IGeoObjRW
|
||||
{ return true ; }
|
||||
virtual bool IsClosed( void) const
|
||||
{ return ::IsClosed( *this) ; }
|
||||
virtual bool IsFlat( Plane3d& plPlane, double dToler) const ;
|
||||
virtual bool GetStartPoint( Point3d& ptStart) const ;
|
||||
virtual bool GetEndPoint( Point3d& ptEnd) const ;
|
||||
virtual bool GetMidPoint( Point3d& ptMid) const ;
|
||||
@@ -85,6 +86,7 @@ class CurveLine : public ICurveLine, public IGeoObjRW
|
||||
return ::GetPointDiffGeom( *this, dU, nS, oDiffG) ; }
|
||||
virtual bool IsPointOn( const Point3d& ptP, double dTol = EPS_SMALL) const ;
|
||||
virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ;
|
||||
virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ;
|
||||
virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ;
|
||||
virtual bool Invert( void) ;
|
||||
virtual bool Offset( double dDist, int nSide, int nType = OFF_FILLET) ;
|
||||
@@ -132,3 +134,15 @@ class CurveLine : public ICurveLine, public IGeoObjRW
|
||||
Point3d m_PtStart ; // punto iniziale
|
||||
Point3d m_PtEnd ; // punto finale
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CurveLine* CreateBasicCurveLine( void)
|
||||
{ return (static_cast<CurveLine*>( CreateGeoObj( CRV_LINE))) ; }
|
||||
inline CurveLine* CloneBasicCurveLine( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_LINE)
|
||||
return nullptr ;
|
||||
return (static_cast<CurveLine*>(pGObj->Clone())) ; }
|
||||
inline const CurveLine* GetBasicCurveLine( const IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<const CurveLine*>(pGObj)) ; }
|
||||
inline CurveLine* GetBasicCurveLine( IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<CurveLine*>(pGObj)) ; }
|
||||
|
||||
Binary file not shown.
@@ -277,6 +277,9 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="OutTsc.cpp" />
|
||||
<ClCompile Include="Point3d.cpp" />
|
||||
<ClCompile Include="PointGrid3d.cpp" />
|
||||
<ClCompile Include="PointsPCA.cpp" />
|
||||
<ClCompile Include="PolyArc.cpp" />
|
||||
<ClCompile Include="PolygonPlane.cpp" />
|
||||
<ClCompile Include="PolyLine.cpp" />
|
||||
<ClCompile Include="PolynomialPoint3d.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
@@ -330,6 +333,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="..\Include\EGkPlane3d.h" />
|
||||
<ClInclude Include="..\Include\EGkPoint3d.h" />
|
||||
<ClInclude Include="..\Include\EGkPointGrid3d.h" />
|
||||
<ClInclude Include="..\Include\EGkPolyArc.h" />
|
||||
<ClInclude Include="..\Include\EGkPolyLine.h" />
|
||||
<ClInclude Include="..\Include\EGkStringUtils3d.h" />
|
||||
<ClInclude Include="..\Include\EgkSurfTriMesh.h" />
|
||||
@@ -388,6 +392,8 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="ObjGraphicsMgr.h" />
|
||||
<ClInclude Include="FontOs.h" />
|
||||
<ClInclude Include="OutTsc.h" />
|
||||
<ClInclude Include="PointsPCA.h" />
|
||||
<ClInclude Include="PolygonPlane.h" />
|
||||
<ClInclude Include="PolynomialPoint3d.h" />
|
||||
<ClInclude Include="Resource.h" />
|
||||
<ClInclude Include="SelManager.h" />
|
||||
|
||||
@@ -216,6 +216,15 @@
|
||||
<ClCompile Include="CurveByInterp.cpp">
|
||||
<Filter>File di origine\GeoCreate</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PolygonPlane.cpp">
|
||||
<Filter>File di origine\Base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PointsPCA.cpp">
|
||||
<Filter>File di origine\Base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PolyArc.cpp">
|
||||
<Filter>File di origine\Base</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
@@ -524,6 +533,15 @@
|
||||
<ClInclude Include="CalcDerivate.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PolygonPlane.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PointsPCA.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkPolyArc.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
+5
-5
@@ -48,7 +48,7 @@ ExtText::Set( const string& sText, const Point3d& ptP, double dAngDeg, double dH
|
||||
// assegno i dati
|
||||
m_ptP = ptP ;
|
||||
m_vtN = Z_AX ;
|
||||
m_vtD.FromPolar( 1, dAngDeg) ;
|
||||
m_vtD = FromPolar( 1, dAngDeg) ;
|
||||
m_sText = sText ;
|
||||
m_sFont.clear() ;
|
||||
m_nWeight = 400 ;
|
||||
@@ -79,7 +79,7 @@ ExtText::Set( const string& sText, const Point3d& ptP, double dAngDeg,
|
||||
// assegno i dati
|
||||
m_ptP = ptP ;
|
||||
m_vtN = Z_AX ;
|
||||
m_vtD.FromPolar( 1, dAngDeg) ;
|
||||
m_vtD = FromPolar( 1, dAngDeg) ;
|
||||
m_sText = sText ;
|
||||
m_sFont = sFont ;
|
||||
m_nWeight = nW ;
|
||||
@@ -802,8 +802,8 @@ ExtText::Mir( bool bOnLen)
|
||||
case ETXT_IPBR : m_nInsPos = ETXT_IPBL ; break ;
|
||||
}
|
||||
// inverto i versori
|
||||
m_vtN *= - 1 ;
|
||||
m_vtD *= - 1 ;
|
||||
m_vtN.Invert() ;
|
||||
m_vtD.Invert() ;
|
||||
}
|
||||
// altrimenti auto-mirror su altezza del testo
|
||||
else {
|
||||
@@ -817,7 +817,7 @@ ExtText::Mir( bool bOnLen)
|
||||
case ETXT_IPBR : m_nInsPos = ETXT_IPTR ; break ;
|
||||
}
|
||||
// inverto il versore normale
|
||||
m_vtN *= - 1 ;
|
||||
m_vtN.Invert() ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
|
||||
+2
-2
@@ -102,7 +102,7 @@ Frame3d::Set( const Point3d& ptOrig, const Vector3d& vtDirZ)
|
||||
m_vtVersX = Z_AX ^ m_vtVersZ ;
|
||||
if ( ! m_vtVersX.Normalize())
|
||||
return false ;
|
||||
// verzsore Y
|
||||
// versore Y
|
||||
m_vtVersY = m_vtVersZ ^ m_vtVersX ;
|
||||
if ( ! m_vtVersY.Normalize())
|
||||
return false ;
|
||||
@@ -526,7 +526,7 @@ Frame3d::GetRotationsCAC1( double& dAngCDeg, double& dAngADeg, double& dAngC1Deg
|
||||
m_vtVersX.ToSpherical( nullptr, nullptr, &dAngCDeg) ;
|
||||
|
||||
// calcolo l'asse X senza la rotazione attorno a C'
|
||||
vtXnoC1.FromPolar( 1, dAngCDeg) ;
|
||||
vtXnoC1 = FromPolar( 1, dAngCDeg) ;
|
||||
|
||||
// calcolo la rotazione attorno a C'
|
||||
if ( ! vtXnoC1.GetRotation( m_vtVersX, m_vtVersZ, dAngC1Deg, bDet) || ! bDet)
|
||||
|
||||
+2
-4
@@ -383,8 +383,7 @@ GdbExecutor::VectorFromSpherical( const STRVECTOR& vsParams)
|
||||
IGeoVector3d* pGVect = CreateGeoVector3d() ;
|
||||
if ( pGVect == nullptr)
|
||||
return false ;
|
||||
Vector3d vtV ;
|
||||
vtV.FromSpherical( dLen, dAngVertDeg, dAngOrizzDeg) ;
|
||||
Vector3d vtV = FromSpherical( dLen, dAngVertDeg, dAngOrizzDeg) ;
|
||||
pGVect->Set( vtV) ;
|
||||
return AddGeoObj( vsParams[0], vsParams[1], pGVect) ;
|
||||
}
|
||||
@@ -2461,8 +2460,7 @@ GdbExecutor::GetPolylineFromCurve( int nId, const Frame3d& frDest, double dLinTo
|
||||
if ( ! IsValid( pModCrv))
|
||||
return false ;
|
||||
// eseguo la trasformazione
|
||||
pModCrv->ToGlob( frCrv) ;
|
||||
pModCrv->ToLoc( frDest) ;
|
||||
pModCrv->LocToLoc( frCrv, frDest) ;
|
||||
// ricavo l'approssimazione
|
||||
if ( ! pModCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
return false ;
|
||||
|
||||
@@ -655,14 +655,14 @@ CalcATypeFromDisk( const ICurve& CurveA, double dUA, ICurve::Side nSideA,
|
||||
! CurveA.GetPointTang( dUAm, nSideA, ptP, vtADir))
|
||||
return false ;
|
||||
if ( nSideA == ICurve::FROM_MINUS)
|
||||
vtADir *= - 1 ;
|
||||
vtADir.Invert() ;
|
||||
// direzioni di arrivo (prev) e partenza (next) curva B
|
||||
Vector3d vtBpDir ;
|
||||
double dUBp = dUB ;
|
||||
if ( ! MoveParamToAvoidTg( dUBp, ICurve::FROM_MINUS, CurveB) ||
|
||||
! CurveB.GetPointTang( dUBp, ICurve::FROM_MINUS, ptP, vtBpDir))
|
||||
return false ;
|
||||
vtBpDir *= - 1 ;
|
||||
vtBpDir.Invert() ;
|
||||
Vector3d vtBnDir ;
|
||||
double dUBn = dUB ;
|
||||
if ( ! MoveParamToAvoidTg( dUBn, ICurve::FROM_PLUS, CurveB) ||
|
||||
@@ -702,14 +702,14 @@ CalcATypeFromDisk2( const ICurve& CurveA, double dUA, ICurve::Side nSideA,
|
||||
! CurveA.GetPointTang( dUAm, nSideA, ptP, vtADir))
|
||||
return false ;
|
||||
if ( nSideA == ICurve::FROM_MINUS)
|
||||
vtADir *= - 1 ;
|
||||
vtADir.Invert() ;
|
||||
// direzioni di arrivo (prev) e partenza (next) curva B (P1)
|
||||
Vector3d vtB1pDir ;
|
||||
double dUB1p = dUB1 ;
|
||||
if ( ! MoveParamToAvoidTg( dUB1p, ICurve::FROM_MINUS, CurveB) ||
|
||||
! CurveB.GetPointTang( dUB1p, ICurve::FROM_MINUS, ptP, vtB1pDir))
|
||||
return false ;
|
||||
vtB1pDir *= - 1 ;
|
||||
vtB1pDir.Invert() ;
|
||||
Vector3d vtB1nDir ;
|
||||
double dUB1n = dUB1 ;
|
||||
if ( ! MoveParamToAvoidTg( dUB1n, ICurve::FROM_PLUS, CurveB) ||
|
||||
@@ -721,7 +721,7 @@ CalcATypeFromDisk2( const ICurve& CurveA, double dUA, ICurve::Side nSideA,
|
||||
if ( ! MoveParamToAvoidTg( dUB2p, ICurve::FROM_MINUS, CurveB) ||
|
||||
! CurveB.GetPointTang( dUB2p, ICurve::FROM_MINUS, ptP, vtB2pDir))
|
||||
return false ;
|
||||
vtB2pDir *= - 1 ;
|
||||
vtB2pDir.Invert() ;
|
||||
Vector3d vtB2nDir ;
|
||||
double dUB2n = dUB2 ;
|
||||
if ( ! MoveParamToAvoidTg( dUB2n, ICurve::FROM_PLUS, CurveB) ||
|
||||
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2014
|
||||
//----------------------------------------------------------------------------
|
||||
// File : PointsPCA.cpp Data : 12.08.14 Versione : 1.5h3
|
||||
// Contenuto : Implementazione della classe PointsPCA,
|
||||
// Principal Components Analysis di un insieme di punti.
|
||||
//
|
||||
//
|
||||
// Modifiche : 12.08.14 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "PointsPCA.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
PointsPCA::PointsPCA( void)
|
||||
{
|
||||
// azzero numero punti
|
||||
m_nPntNbr = 0 ;
|
||||
// azzero il baricentro
|
||||
m_ptCen.Set( 0, 0, 0) ;
|
||||
// azzero matrice di covarianza
|
||||
m_CovMat.setZero() ;
|
||||
// inizializzo il rank ad un valore assurdo
|
||||
m_nRank = - 1 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
PointsPCA::AddPoint( const Point3d& ptP)
|
||||
{
|
||||
// incremento numero punti
|
||||
++ m_nPntNbr ;
|
||||
// aggiorno il baricentro
|
||||
m_ptCen += ptP ;
|
||||
// aggiorno la matrice di covarianza (solo triangolo superiore perchè simmetrica)
|
||||
m_CovMat(0,0) += ptP.x * ptP.x ;
|
||||
m_CovMat(1,1) += ptP.y * ptP.y ;
|
||||
m_CovMat(2,2) += ptP.z * ptP.z ;
|
||||
m_CovMat(0,1) += ptP.x * ptP.y ;
|
||||
m_CovMat(0,2) += ptP.x * ptP.z ;
|
||||
m_CovMat(1,2) += ptP.y * ptP.z ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PointsPCA::Finalize( void)
|
||||
{
|
||||
// se già eseguito il calcolo finale, esco
|
||||
if ( m_nRank >= 0)
|
||||
return true ;
|
||||
|
||||
// il rank viene annullato ( non sono ancora note direzioni principali)
|
||||
m_nRank = 0 ;
|
||||
|
||||
// se non sono stati assegnati punti, esco
|
||||
if ( m_nPntNbr == 0)
|
||||
return false ;
|
||||
|
||||
// fattore di scala per numero di punti
|
||||
double dScale = 1 / double( m_nPntNbr) ;
|
||||
|
||||
// calcolo del baricentro
|
||||
m_ptCen *= dScale ;
|
||||
|
||||
// completo la matrice di covarianza
|
||||
m_CovMat(0,0) = m_CovMat(0,0) * dScale - m_ptCen.x * m_ptCen.x ;
|
||||
m_CovMat(1,1) = m_CovMat(1,1) * dScale - m_ptCen.y * m_ptCen.y ;
|
||||
m_CovMat(2,2) = m_CovMat(2,2) * dScale - m_ptCen.z * m_ptCen.z ;
|
||||
m_CovMat(0,1) = m_CovMat(0,1) * dScale - m_ptCen.x * m_ptCen.y ;
|
||||
m_CovMat(0,2) = m_CovMat(0,2) * dScale - m_ptCen.x * m_ptCen.z ;
|
||||
m_CovMat(1,2) = m_CovMat(1,2) * dScale - m_ptCen.y * m_ptCen.z ;
|
||||
m_CovMat(1,0) = m_CovMat(0,1) ;
|
||||
m_CovMat(2,0) = m_CovMat(0,2) ;
|
||||
m_CovMat(2,1) = m_CovMat(1,2) ;
|
||||
|
||||
// calcolo gli autovalori e autovettori (essendo matrice 3x3 uso metodo diretto)
|
||||
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> es ;
|
||||
es.compute( m_CovMat) ; // non usare computeDirect : errore nell'ordine degli autovettori
|
||||
if ( es.info() == Eigen::NoConvergence)
|
||||
return false ;
|
||||
|
||||
// recupero gli autovettori corrispondenti agli autovalori non nulli
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
int j = ( i + 1) % 3 ;
|
||||
int k = ( i + 2) % 3 ;
|
||||
// se l'autovalore corrente è il più grande in modulo
|
||||
if ( fabs( es.eigenvalues()(i)) >= fabs( es.eigenvalues()(j)) &&
|
||||
fabs( es.eigenvalues()(i)) >= fabs( es.eigenvalues()(k)) &&
|
||||
fabs( es.eigenvalues()(i)) > EPS_SMALL * EPS_SMALL) {
|
||||
// il suo autovettore è il primo
|
||||
++ m_nRank ;
|
||||
m_vtPC[0].Set( es.eigenvectors()(0,i), es.eigenvectors()(1,i), es.eigenvectors()(2,i)) ;
|
||||
// se il successivo autovalore è maggiore del rimanente in modulo
|
||||
if ( fabs( es.eigenvalues()(j)) >= fabs(es.eigenvalues()(k)) &&
|
||||
fabs( es.eigenvalues()(j)) > EPS_SMALL * EPS_SMALL) {
|
||||
// il suo autovettore è il secondo
|
||||
++ m_nRank ;
|
||||
m_vtPC[1].Set( es.eigenvectors()(0,j), es.eigenvectors()(1,j), es.eigenvectors()(2,j)) ;
|
||||
// se il rimanente autovalore è non nullo
|
||||
if ( fabs( es.eigenvalues()(k)) > EPS_SMALL * EPS_SMALL) {
|
||||
// il suo autovettore è il terzo
|
||||
++ m_nRank ;
|
||||
m_vtPC[2].Set( es.eigenvectors()(0,k), es.eigenvectors()(1,k), es.eigenvectors()(2,k)) ;
|
||||
}
|
||||
}
|
||||
// altrimenti, se il rimanente autovalore è maggiore del successivo in modulo
|
||||
else if ( fabs( es.eigenvalues()(k)) >= fabs( es.eigenvalues()(j)) &&
|
||||
fabs( es.eigenvalues()(k)) > EPS_SMALL * EPS_SMALL) {
|
||||
// il suo autovettore è il secondo
|
||||
++ m_nRank ;
|
||||
m_vtPC[1].Set( es.eigenvectors()(0,k), es.eigenvectors()(1,k), es.eigenvectors()(2,k)) ;
|
||||
// se il rimanente autovalore è non nullo
|
||||
if ( fabs( es.eigenvalues()(j)) > EPS_SMALL * EPS_SMALL) {
|
||||
// il suo autovettore è il terzo
|
||||
++ m_nRank ;
|
||||
m_vtPC[2].Set( es.eigenvectors()(0,j), es.eigenvectors()(1,j), es.eigenvectors()(2,j)) ;
|
||||
}
|
||||
}
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
PointsPCA::GetRank( void)
|
||||
{
|
||||
// verifico completamento conti
|
||||
Finalize() ;
|
||||
|
||||
return m_nRank ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PointsPCA::GetCenter( Point3d& ptCen)
|
||||
{
|
||||
// verifico completamento conti
|
||||
Finalize() ;
|
||||
// assegno i dati
|
||||
ptCen = m_ptCen ;
|
||||
return ( m_nPntNbr > 0) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PointsPCA::GetPrincipalComponent( int nId, Vector3d& vtPC)
|
||||
{
|
||||
// verifico completamento conti
|
||||
Finalize() ;
|
||||
// verifico esistenza componente (indice 0-based)
|
||||
if ( nId < 0 || nId >= m_nRank)
|
||||
return false ;
|
||||
// assegno dati
|
||||
vtPC = m_vtPC[nId] ;
|
||||
return true ;
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2014
|
||||
//----------------------------------------------------------------------------
|
||||
// File : PointsPCA.h Data : 12.08.14 Versione : 1.5h3
|
||||
// Contenuto : Dichiarazione della classe PointsPCA.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 12.08.14 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||
#include "/EgtDev/Extern/Eigen/Dense"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class PointsPCA
|
||||
{
|
||||
public :
|
||||
PointsPCA( void) ;
|
||||
void AddPoint( const Point3d& ptP) ;
|
||||
int GetRank( void) ;
|
||||
bool GetCenter( Point3d& ptCen) ;
|
||||
bool GetPrincipalComponent( int nId, Vector3d& vtPC) ;
|
||||
|
||||
private :
|
||||
bool Finalize( void) ;
|
||||
|
||||
private :
|
||||
static const int MAX_RANK = 3 ;
|
||||
|
||||
private :
|
||||
int m_nPntNbr ; // numero punti
|
||||
Point3d m_ptCen ; // baricentro
|
||||
Eigen::Matrix3d m_CovMat ; // matrice di covarianza
|
||||
int m_nRank ; // numero delle componenti principali (MAX_RANK = 3)
|
||||
Vector3d m_vtPC[MAX_RANK] ; // direzioni delle componenti principali
|
||||
} ;
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2014
|
||||
//----------------------------------------------------------------------------
|
||||
// File : PolyArc.cpp Data : 14.08.14 Versione : 1.5h3
|
||||
// Contenuto : Implementazione della classe PolyArc.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 14.08.14 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "\EgtDev\Include\EGkPolyArc.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
PolyArc::PolyArc( void)
|
||||
{
|
||||
m_nCount = 0 ;
|
||||
m_iter = m_lUPointBs.end() ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
PolyArc::~PolyArc( void)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyArc::Clear( void)
|
||||
{
|
||||
m_nCount = 0 ;
|
||||
m_lUPointBs.clear() ;
|
||||
m_iter = m_lUPointBs.end() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyArc::AddUPoint( double dPar, const Point3d& ptP, double dBulge)
|
||||
{
|
||||
try {
|
||||
m_lUPointBs.push_back( UPointB( dPar, ptP, dBulge)) ;
|
||||
}
|
||||
catch (...) {
|
||||
return false ;
|
||||
}
|
||||
|
||||
m_nCount ++ ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyArc::EraseFirstUPoint( void)
|
||||
{
|
||||
if ( m_lUPointBs.empty())
|
||||
return false ;
|
||||
|
||||
m_lUPointBs.pop_front() ;
|
||||
m_nCount -- ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyArc::EraseLastUPoint( void)
|
||||
{
|
||||
if ( m_lUPointBs.empty())
|
||||
return false ;
|
||||
|
||||
m_lUPointBs.pop_back() ;
|
||||
m_nCount -- ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyArc::AddOffsetToU( double dOffset)
|
||||
{
|
||||
UPNTBLIST::iterator iter ;
|
||||
for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter)
|
||||
iter->dU += dOffset ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyArc::ToGlob( const Frame3d& frRef)
|
||||
{
|
||||
UPNTBLIST::iterator iter ;
|
||||
for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter)
|
||||
iter->ptP.ToGlob( frRef) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyArc::ToLoc( const Frame3d& frRef)
|
||||
{
|
||||
UPNTBLIST::iterator iter ;
|
||||
for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter)
|
||||
iter->ptP.ToLoc( frRef) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyArc::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
{
|
||||
UPNTBLIST::iterator iter ;
|
||||
for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter)
|
||||
iter->ptP.LocToLoc( frOri, frDest) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyArc::Splice( PolyArc& PA)
|
||||
{
|
||||
m_lUPointBs.splice( m_lUPointBs.end(), PA.m_lUPointBs) ;
|
||||
m_nCount += PA.GetPointNbr() ;
|
||||
PA.m_nCount = 0 ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyArc::GetFirstUPoint( double* pdPar, Point3d* pptP, double* pdBulge) const
|
||||
{
|
||||
m_iter = m_lUPointBs.begin() ;
|
||||
if ( m_iter == m_lUPointBs.end())
|
||||
return false ;
|
||||
|
||||
if ( pdPar != nullptr)
|
||||
*pdPar = m_iter->dU ;
|
||||
if ( pptP != nullptr)
|
||||
*pptP = m_iter->ptP ;
|
||||
if ( pdBulge != nullptr)
|
||||
*pdBulge = m_iter->dB ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyArc::GetNextUPoint( double* pdPar, Point3d* pptP, double* pdBulge, bool bNotLast) const
|
||||
{
|
||||
if ( m_iter == m_lUPointBs.end())
|
||||
return false ;
|
||||
++ m_iter ;
|
||||
if ( m_iter == m_lUPointBs.end())
|
||||
return false ;
|
||||
if ( bNotLast && m_iter == -- ( m_lUPointBs.end()))
|
||||
return false ;
|
||||
|
||||
if ( pdPar != nullptr)
|
||||
*pdPar = m_iter->dU ;
|
||||
if ( pptP != nullptr)
|
||||
*pptP = m_iter->ptP ;
|
||||
if ( pdBulge != nullptr)
|
||||
*pdBulge = m_iter->dB ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
+54
-39
@@ -14,6 +14,8 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "PolygonPlane.h"
|
||||
#include "PointsPCA.h"
|
||||
#include "\EgtDev\Include\EGkPolyLine.h"
|
||||
#include "\EgtDev\Include\EGkPlane3d.h"
|
||||
|
||||
@@ -379,57 +381,70 @@ PolyLine::GetPrevULine( double* pdIni, Point3d* pptIni, double* pdFin, Point3d*
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyLine::NewellPlane( Plane3d& plPlane, double& dArea) const
|
||||
PolyLine::IsFlat( int& nRank, Point3d& ptCen, Vector3d& vtDir, double dToler) const
|
||||
{
|
||||
// Compute normal as being proportional to projected areas of polygon onto the yz,
|
||||
// xz, and xy planes. Also compute centroid as representative point on the plane
|
||||
Vector3d vtN ;
|
||||
Point3d ptCen ;
|
||||
int nNumSide = 0 ;
|
||||
Point3d ptIni, ptFin ;
|
||||
for ( bool bFound = GetFirstLine( ptIni, ptFin) ; bFound ; bFound = GetNextLine( ptIni, ptFin)) {
|
||||
vtN.x += ( ptIni.y - ptFin.y) * ( ptIni.z + ptFin.z) ; // projection on yz
|
||||
vtN.y += ( ptIni.z - ptFin.z) * ( ptIni.x + ptFin.x) ; // projection on xz
|
||||
vtN.z += ( ptIni.x - ptFin.x) * ( ptIni.y + ptFin.y) ; // projection on xy
|
||||
ptCen += ptFin ;
|
||||
++ nNumSide ;
|
||||
// cerco le componenti principali (tramite PCA)
|
||||
Point3d ptP ;
|
||||
PointsPCA ptsPCA ;
|
||||
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP))
|
||||
ptsPCA.AddPoint( ptP) ;
|
||||
// recupero il rango, ovvero la dimensionalità dell'insieme di punti
|
||||
nRank = ptsPCA.GetRank() ;
|
||||
// se dimensione nulla, o non ci sono punti o sono tutti praticamente coincidenti
|
||||
if ( nRank == 0)
|
||||
return ptsPCA.GetCenter( ptCen) ;
|
||||
// se dimensione 1, allora i punti sono distribuiti su una linea
|
||||
if ( nRank == 1) {
|
||||
// assegno il centro e la direzione della linea (il verso è indifferente)
|
||||
ptsPCA.GetCenter( ptCen) ;
|
||||
ptsPCA.GetPrincipalComponent( 0, vtDir) ;
|
||||
return true ;
|
||||
}
|
||||
// If open and existent, add segment from last to first points
|
||||
if ( ! IsClosed() && nNumSide > 0) {
|
||||
ptIni = ptFin ;
|
||||
GetFirstPoint( ptFin) ;
|
||||
vtN.x += ( ptIni.y - ptFin.y) * ( ptIni.z + ptFin.z) ; // projection on yz
|
||||
vtN.y += ( ptIni.z - ptFin.z) * ( ptIni.x + ptFin.x) ; // projection on xz
|
||||
vtN.z += ( ptIni.x - ptFin.x) * ( ptIni.y + ptFin.y) ; // projection on xy
|
||||
ptCen += ptFin ;
|
||||
++ nNumSide ;
|
||||
// altrimenti dimensione 2 o 3, allora è determinato un piano principale, verifico se tutti i punti vi giacciono
|
||||
// Center and normal vector
|
||||
ptsPCA.GetCenter( ptCen) ;
|
||||
Vector3d vtX, vtY ;
|
||||
ptsPCA.GetPrincipalComponent( 0, vtX) ;
|
||||
ptsPCA.GetPrincipalComponent( 1, vtY) ;
|
||||
vtDir = vtX ^ vtY ;
|
||||
if ( ! vtDir.Normalize()) {
|
||||
// riduco la dimensionalità a lineare
|
||||
nRank = 1 ;
|
||||
// assegno il centro e la direzione della linea (il verso è indifferente)
|
||||
ptsPCA.GetCenter( ptCen) ;
|
||||
vtDir = vtX ;
|
||||
return true ;
|
||||
}
|
||||
if ( vtDir.z < 0)
|
||||
vtDir.Invert() ;
|
||||
// Plane calculation
|
||||
Plane3d plPlane ;
|
||||
plPlane.vtN = vtDir ;
|
||||
plPlane.dDist = ( ptCen - ORIG) * plPlane.vtN ;
|
||||
// Test each vertex to see if it is farther from plane than allowed max distance
|
||||
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP)) {
|
||||
double dDist = ( ( ptP - ORIG) * plPlane.vtN) - plPlane.dDist ;
|
||||
if ( fabs( dDist) > dToler)
|
||||
return false ;
|
||||
}
|
||||
// At least 3 sides
|
||||
if ( nNumSide < 3)
|
||||
return false ;
|
||||
// Normal must be normalizable (the length of the normal is the double of the area of the polygon)
|
||||
double dLenN = vtN.Len() ;
|
||||
if ( dLenN < EPS_SMALL)
|
||||
return false ;
|
||||
vtN /= dLenN ;
|
||||
// Fill in the plane equation fields
|
||||
plPlane.vtN = vtN ;
|
||||
plPlane.dDist = ( ( ptCen - ORIG) * plPlane.vtN) / nNumSide ; // “centroid / n” is the true centroid point
|
||||
// Set area
|
||||
dArea = 0.5 * dLenN ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyLine::IsFlat( Plane3d& plPlane, double& dArea, double dToler) const
|
||||
PolyLine::IsClosedAndFlat( Plane3d& plPlane, double& dArea, double dToler) const
|
||||
{
|
||||
// Test if closed
|
||||
if ( ! IsClosed())
|
||||
return false ;
|
||||
// Compute a representative plane for the polygon
|
||||
if ( ! NewellPlane( plPlane, dArea))
|
||||
Point3d ptP ;
|
||||
PolygonPlane PolyPlane ;
|
||||
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP))
|
||||
PolyPlane.AddPoint( ptP) ;
|
||||
if ( ! PolyPlane.GetPlane( plPlane) || ! PolyPlane.GetArea( dArea))
|
||||
return false ;
|
||||
// Test each vertex to see if it is farther from plane than allowed max distance
|
||||
Point3d ptP ;
|
||||
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP)) {
|
||||
double dDist = ( ( ptP - ORIG) * plPlane.vtN) - plPlane.dDist ;
|
||||
if ( fabs( dDist) > dToler)
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2014
|
||||
//----------------------------------------------------------------------------
|
||||
// File : PolygonPlane.cpp Data : 12.08.14 Versione : 1.5h3
|
||||
// Contenuto : Implementazione della classe PolygonPlane.
|
||||
// Calcolo della normale e delle aree con il metodo di Newell.
|
||||
//
|
||||
//
|
||||
// Modifiche : 12.08.14 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "PolygonPlane.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
PolygonPlane::AddPoint( const Point3d& ptP)
|
||||
{
|
||||
// se è il primo punto (parto da -1 perchè verrà contato alla chiusura)
|
||||
if ( m_nPntNbr == -1)
|
||||
m_ptFirst = ptP ;
|
||||
// dal secondo punto posso cominciare ad eseguire le somme parziali
|
||||
else {
|
||||
// Compute normal as being proportional to projected areas of polygon onto the yz,
|
||||
// xz, and xy planes. Also compute centroid as representative point on the plane
|
||||
m_vtN.x += ( m_ptLast.y - ptP.y) * ( m_ptLast.z + ptP.z) ; // projection on yz
|
||||
m_vtN.y += ( m_ptLast.z - ptP.z) * ( m_ptLast.x + ptP.x) ; // projection on xz
|
||||
m_vtN.z += ( m_ptLast.x - ptP.x) * ( m_ptLast.y + ptP.y) ; // projection on xy
|
||||
m_ptCen += ptP ;
|
||||
}
|
||||
// salvo punto e incremento numero di punti
|
||||
m_ptLast = ptP ;
|
||||
++ m_nPntNbr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolygonPlane::Finalize( void)
|
||||
{
|
||||
// almeno 3 punti (il triangolo è il poligono con minimo numero di lati)
|
||||
if ( m_nPntNbr < 3)
|
||||
return false ;
|
||||
// se il poligono non è stato chiuso, aggiungo calcolo per ultimo lato
|
||||
if ( ! AreSamePointApprox( m_ptFirst, m_ptLast)) {
|
||||
// aggiungo il primo punto per far eseguire i conti sul lato di chiusura
|
||||
AddPoint( m_ptFirst) ;
|
||||
}
|
||||
// se non effettuato, eseguo il calcolo finale
|
||||
if ( m_dLenN < EPS_SMALL) {
|
||||
// lunghezza della normale (doppio dell'area del poligono)
|
||||
m_dLenN = m_vtN.Len() ;
|
||||
if ( m_dLenN < EPS_SMALL)
|
||||
return false ;
|
||||
// normalizzo
|
||||
m_vtN /= m_dLenN ;
|
||||
// sistemo baricentro
|
||||
m_ptCen /= m_nPntNbr ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolygonPlane::GetPlane( Plane3d& plPlane)
|
||||
{
|
||||
// verifico completamento conti
|
||||
if ( ! Finalize())
|
||||
return false ;
|
||||
// assegno i dati al piano
|
||||
plPlane.vtN = m_vtN ;
|
||||
plPlane.dDist = ( ( m_ptCen - ORIG) * plPlane.vtN) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolygonPlane::GetArea( double& dArea)
|
||||
{
|
||||
// verifico completamento conti
|
||||
if ( ! Finalize())
|
||||
return false ;
|
||||
// assegno l'area
|
||||
dArea = 0.5 * m_dLenN ;
|
||||
return true ;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2014
|
||||
//----------------------------------------------------------------------------
|
||||
// File : PolygonPlane.h Data : 12.08.14 Versione : 1.5h3
|
||||
// Contenuto : Dichiarazione della classe PolygonPlane.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 12.08.14 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class PolygonPlane
|
||||
{
|
||||
public :
|
||||
PolygonPlane( void) : m_nPntNbr( -1), m_dLenN( 0) {}
|
||||
void AddPoint( const Point3d& ptP) ;
|
||||
bool GetPlane( Plane3d& plPlane) ;
|
||||
bool GetArea( double& dArea) ;
|
||||
|
||||
private :
|
||||
bool Finalize( void) ;
|
||||
|
||||
private :
|
||||
int m_nPntNbr ; // numero punti aggiunti
|
||||
double m_dLenN ; // lunghezza della normale
|
||||
Point3d m_ptFirst ; // primo punto aggiunto
|
||||
Point3d m_ptLast ; // ultimo punto aggiunto
|
||||
Vector3d m_vtN ; // versore normale
|
||||
Point3d m_ptCen ; // baricentro
|
||||
} ;
|
||||
+1
-1
@@ -1752,7 +1752,7 @@ SurfTriMesh::InvertTriangle( int nT)
|
||||
// scambio delle conseguenti due adiacenze
|
||||
swap( m_vTria[nT].nIdAdjac[0], m_vTria[nT].nIdAdjac[2]) ;
|
||||
// inversione della normale
|
||||
m_vTria[nT].vtN *= - 1 ;
|
||||
m_vTria[nT].vtN.Invert() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
+2
-5
@@ -27,13 +27,10 @@ using namespace std ;
|
||||
bool
|
||||
Triangulate::Make( const PolyLine& PL, PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
{
|
||||
// verifico che la polilinea sia chiusa -> poligono
|
||||
if ( ! PL.IsClosed())
|
||||
return false ;
|
||||
// calcolo il piano medio del poligono
|
||||
// verific che la polilinea sia chiusa e calcolo il piano medio del poligono
|
||||
double dArea ;
|
||||
Plane3d plPlane ;
|
||||
if ( ! PL.IsFlat( plPlane, dArea, 50 * EPS_SMALL))
|
||||
if ( ! PL.IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL))
|
||||
return false ;
|
||||
bool bCCW ;
|
||||
if ( fabs( plPlane.vtN.z) >= fabs( plPlane.vtN.x) &&
|
||||
|
||||
+33
-12
@@ -13,7 +13,6 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "\EgtDev\Include\EGkGeoConst.h"
|
||||
#include "\EgtDev\Include\EGkVector3d.h"
|
||||
#include "\EgtDev\Include\EGKFrame3d.h"
|
||||
|
||||
@@ -21,27 +20,49 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Definizione a partire da coordinate sferiche
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
Vector3d::FromSpherical( double dLen, double dAngVertDeg, double dAngOrizzDeg)
|
||||
Vector3d
|
||||
FromSpherical( double dLen, double dAngVertDeg, double dAngOrizzDeg)
|
||||
{
|
||||
double dAngVertRad = dAngVertDeg * DEGTORAD ;
|
||||
double dAngOrizzRad = dAngOrizzDeg * DEGTORAD ;
|
||||
double dSinAngVert = sin( dAngVertRad) ;
|
||||
x = dLen * dSinAngVert * cos( dAngOrizzRad) ;
|
||||
y = dLen * dSinAngVert * sin( dAngOrizzRad) ;
|
||||
z = dLen * cos( dAngVertRad) ;
|
||||
Vector3d vtV( dLen * dSinAngVert * cos( dAngOrizzRad),
|
||||
dLen * dSinAngVert * sin( dAngOrizzRad),
|
||||
dLen * cos( dAngVertRad)) ;
|
||||
return vtV ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Definizione a partire da coordinate polari
|
||||
// Definizione a partire da coordinate polari ( nel piano XY, Z = 0)
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
Vector3d::FromPolar( double dLen, double dAngDeg)
|
||||
Vector3d
|
||||
FromPolar( double dLen, double dAngDeg)
|
||||
{
|
||||
double dAngRad = dAngDeg * DEGTORAD ;
|
||||
x = dLen * cos( dAngRad) ;
|
||||
y = dLen * sin( dAngRad) ;
|
||||
z = 0 ;
|
||||
Vector3d vtV( dLen * cos( dAngRad),
|
||||
dLen * sin( dAngRad),
|
||||
0) ;
|
||||
return vtV ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Definizione dal più verticale dei vettori ortogonali a quello ricevuto
|
||||
//----------------------------------------------------------------------------
|
||||
Vector3d
|
||||
FromUprightOrtho( const Vector3d& vtV)
|
||||
{
|
||||
// se vettore nullo, imposto asse Z+
|
||||
if ( vtV.IsZero())
|
||||
return Z_AX ;
|
||||
// se vettore coincidente con asse Z, imposto asse X+
|
||||
if ( vtV.IsZplus() || vtV.IsZminus())
|
||||
return X_AX ;
|
||||
// caso generico
|
||||
Vector3d vtAx = vtV ;
|
||||
vtAx.z = 0 ;
|
||||
vtAx.Normalize( EPS_ZERO) ;
|
||||
vtAx.Rotate( Z_AX, 0, 1) ;
|
||||
return ( vtV ^ vtAx) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user