2bd53476ca
- modifiche per RotationMinimizingFrame e RotationXplaneFrame - aggiornato calcolo superfici TriMesh da Swept di curva o di regione.
224 lines
6.3 KiB
C++
224 lines
6.3 KiB
C++
//----------------------------------------------------------------------------
|
|
// 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 ;
|
|
}
|