//---------------------------------------------------------------------------- // EgalTech 2024-2024 //---------------------------------------------------------------------------- // File : RotationXplaneFrame.cpp Data : 05.04.24 Versione : 2.6d1 // Contenuto : Classe per RotationXplaneFrame. // // // // Modifiche : 05.04.24 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "GeoConst.h" #include "/EgtDev/Include/EGkRotationXplaneFrame.h" using namespace std ; //---------------------------------------------------------------------------- bool RotationXplaneFrame::Set( const ICurve* pCrv, const Vector3d& vtNorm, const Vector3d& vtNearX) { // pulisco Clear() ; // verifico i parametri if ( pCrv == nullptr || ! pCrv->IsValid() || ! vtNorm.IsValid() || vtNorm.IsSmall() || ! vtNearX.IsValid()) return false ; // assegno i parametri m_pCrv = pCrv->Clone() ; m_vtNorm = vtNorm ; m_vtNearX = vtNearX ; return true ; } //---------------------------------------------------------------------------- bool RotationXplaneFrame::Clear( void) { // pulizia della curva if ( m_pCrv != nullptr) delete m_pCrv ; m_pCrv = nullptr ; // reset dei vettori m_vtNorm = V_NULL ; m_vtNearX = V_NULL ; return true ; } //---------------------------------------------------------------------------- bool RotationXplaneFrame::IsValid( void) { // controllo validità della curva if ( m_pCrv == nullptr || ! m_pCrv->IsValid()) return false ; // controllo della normale al piano if ( m_vtNorm.IsSmall()) return false ; return true ; } //---------------------------------------------------------------------------- bool RotationXplaneFrame::GetFrameAtParam( const Frame3d& frAct, const double dParNext, Frame3d& frNext) { // verifico il riferimento corrente if ( ! frAct.IsValid()) return false ; // recupero punto e tangente nel nuovo punto Point3d ptNext ; Vector3d vtNext ; if ( ! m_pCrv->GetPointD1D2( dParNext, ICurve::FROM_MINUS, ptNext, &vtNext) || ! vtNext.Normalize()) return false ; // calcolo il nuovo riferimento Vector3d vtAxX = m_vtNorm ^ vtNext ; if ( vtAxX.IsSmall()) vtAxX = frAct.VersX() ; else if ( vtAxX * frAct.VersX() < 0) vtAxX.Invert() ; // lo imposto return frNext.Set( ptNext, vtNext, vtAxX) ; } //---------------------------------------------------------------------------- bool RotationXplaneFrame::GetFramesByStep( double dStep, bool bUniform, FRAME3DVECTOR& vRXFrames) { // controllo validità if ( ! IsValid()) return false ; // controllo sullo step dStep = max( 10 * EPS_SMALL, dStep) ; // lunghezza della curva double dCrvLen = 0. ; if ( ! m_pCrv->GetLength( dCrvLen) || dCrvLen < 10 * EPS_SMALL) return false ; // numero e lunghezza effettiva di ogni step int nStep = int( ceil( dCrvLen / dStep)) ; double dMyStep = ( bUniform ? dCrvLen / nStep : dStep) ; // calcolo il riferimento iniziale Point3d ptStart ; m_pCrv->GetStartPoint( ptStart) ; Vector3d vtStart ; m_pCrv->GetStartDir( vtStart) ; Vector3d vtAxX = m_vtNorm ^ vtStart ; if ( vtAxX.IsSmall()) { vtAxX = OrthoCompo( m_vtNearX, m_vtNorm) ; if ( vtAxX.IsSmall()) { vtAxX = FromUprightOrtho( m_vtNorm) ; vtAxX.Rotate( m_vtNorm, 0, 1) ; } } Frame3d frStart ; if ( ! frStart.Set( ptStart, vtStart, vtAxX)) return false ; // inserisco questo frame nel vettore dei riferimenti vRXFrames.clear() ; vRXFrames.reserve( nStep + 1) ; vRXFrames.push_back( frStart) ; // ciclo sugli step in cui la curva è suddivisa for ( int i = 1 ; i <= nStep ; ++ i) { // ricavo il parametro della curva allo step i-esimo double dParNext ; if ( ! m_pCrv->GetParamAtLength( min( i * dMyStep, dCrvLen - EPS_SMALL), dParNext)) return false ; // ricavo il frame alla posizione calcolata Frame3d frNext ; if ( ! GetFrameAtParam( vRXFrames[i-1], dParNext, frNext)) return false ; // inserisco nuovo frame nel vettore dei riferimenti vRXFrames.push_back( frNext) ; } return true ; } //---------------------------------------------------------------------------- bool RotationXplaneFrame::GetFramesBySplit( int nIntervals, FRAME3DVECTOR& vRXFrames) { // controllo validità if ( ! IsValid()) return false ; // controllo sul numero di intervalli nIntervals = max( 1, nIntervals) ; // ricavo lo step double dLen = 0 ; if ( ! m_pCrv->GetLength( dLen)) return false ; double dStep = dLen / nIntervals ; return GetFramesByStep( dStep, true, vRXFrames) ; } //---------------------------------------------------------------------------- bool RotationXplaneFrame::GetFramesByTolerance( double dTol, FRAME3DVECTOR& vRXFrames) { // controllo validità if ( ! IsValid()) return false ; // controllo sulla tolleranza dTol = max( EPS_SMALL, dTol) ; // ricavo la PolyLine associata alla curva mediante tale tolleranza PolyLine PL ; if ( ! m_pCrv->ApproxWithLines( dTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) return false ; int nStep = PL.GetLineNbr() ; // calcolo il riferimento iniziale Point3d ptStart ; m_pCrv->GetStartPoint( ptStart) ; Vector3d vtStart ; m_pCrv->GetStartDir( vtStart) ; Vector3d vtAxX = m_vtNorm ^ vtStart ; if ( vtAxX.IsSmall()) { vtAxX = OrthoCompo( m_vtNearX, m_vtNorm) ; if ( vtAxX.IsSmall()) { vtAxX = FromUprightOrtho( m_vtNorm) ; vtAxX.Rotate( m_vtNorm, 0, 1) ; } } Frame3d frStart ; if ( ! frStart.Set( ptStart, vtStart, vtAxX)) return false ; // inserisco questo frame nel vettore dei riferimenti vRXFrames.clear() ; vRXFrames.reserve( nStep + 1) ; vRXFrames.push_back( frStart) ; // eseguo il calcolo dei frame sui punti della polyline approssimante Point3d ptCurr ; PL.GetFirstPoint( ptCurr) ; double dParNext ; Point3d ptNext ; while ( PL.GetNextUPoint( &dParNext, &ptNext)) { // ricavo il Frame associato a questa posizione Frame3d frNext ; if ( ! GetFrameAtParam( vRXFrames.back(), dParNext, frNext)) return false ; vRXFrames.emplace_back( frNext) ; } return true ; }