ec109908fa
- inizio stesura codice per Rotation Minimize Frame.
182 lines
5.6 KiB
C++
182 lines
5.6 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2024
|
|
//----------------------------------------------------------------------------
|
|
// File : RotationMinimizeFrame.cpp Data : 05.03.24 Versione : 2.6c1
|
|
// Contenuto : Classe per RotationMinimizeFrame
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 05.03.24 RE Creazione modulo.
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "RotationMinimizeFrame.h"
|
|
#include "GeoConst.h"
|
|
|
|
using namespace std ;
|
|
|
|
RotationMinimizeFrame::RotationMinimizeFrame( const ICurve* pCrv, const Frame3d& fr_Start, const double dStep)
|
|
{
|
|
// assegno i parametri
|
|
m_pCrv = pCrv->Clone() ;
|
|
m_Frame0 = fr_Start ;
|
|
m_dStep = dStep ;
|
|
}
|
|
|
|
RotationMinimizeFrame::RotationMinimizeFrame( const ICurve* pCrv, const Frame3d& fr_Start, const int nStep)
|
|
{
|
|
// assegno i parametri
|
|
if ( nStep < 1) // devo averne almeno 1, altrimenti è automaticamente il fr_Start
|
|
return ;
|
|
|
|
// recupero la lunghezza della curva
|
|
double dLen = 0 ;
|
|
if ( pCrv == nullptr || ! pCrv->IsValid() || ! pCrv->GetLength( dLen))
|
|
return ;
|
|
|
|
m_pCrv = pCrv->Clone() ;
|
|
m_Frame0 = fr_Start ;
|
|
m_dStep = dLen / nStep ;
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
RotationMinimizeFrame::~RotationMinimizeFrame( void)
|
|
{
|
|
Clear() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
RotationMinimizeFrame::IsValid()
|
|
{
|
|
// controllo validità della curva
|
|
if ( m_pCrv == nullptr || ! m_pCrv->IsValid())
|
|
return false ;
|
|
|
|
// controllo del frame iniziale
|
|
if ( ! m_Frame0.IsValid())
|
|
return false ;
|
|
|
|
// controllo sul parametro di discretizzazione
|
|
if ( m_dStep < EPS_SMALL)
|
|
return false ;
|
|
// controllo che il passo non sia superiore alla lunghezza della curva
|
|
double dLen = 0. ;
|
|
if ( ! m_pCrv->GetLength( dLen) || m_dStep > dLen)
|
|
return false ;
|
|
|
|
return true ;
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
RotationMinimizeFrame::Clear( void)
|
|
{
|
|
// pulizia della curva
|
|
if ( m_pCrv != nullptr)
|
|
delete m_pCrv ;
|
|
m_pCrv = nullptr ;
|
|
|
|
// reset del frame di partenza
|
|
m_Frame0.Reset() ;
|
|
|
|
// reset dell'intervallo di discretizzazione
|
|
m_dStep = 0. ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
RotationMinimizeFrame::GetFrames( FRAME3DVECTOR& vRMFrams)
|
|
{
|
|
// controllo validità
|
|
if ( ! IsValid()) {
|
|
Clear() ;
|
|
return false ;
|
|
}
|
|
|
|
/*
|
|
Double Reflection
|
|
Computation of Rotation Minimizing Frame in Computer Graphics
|
|
Wenping Wang Bert Juttler Dayue Zheng Yang Liu
|
|
*/
|
|
|
|
// calcolo lunghezza della curva
|
|
double dLen = 0. ;
|
|
if ( ! m_pCrv->GetLength( dLen))
|
|
return false ;
|
|
|
|
// ricavo il numero degli step
|
|
int nStep = 1 + ceil( dLen / nStep) ; // frame iniziale, ... frame intermedi ..., frame finale
|
|
|
|
// in prima posizione viene inserito il frame iniziale
|
|
m_vRMFrams.push_back( m_Frame0) ;
|
|
|
|
// variabili di utilizzo
|
|
double dLenCurr = 0 ; // lunghezza della curva allo step i-esimo
|
|
double dLenNext ; // lunghezza della curva allo step (i+1)-esimo
|
|
double dUCurr = 0. ; // parametro sulla curva allo step i-esimo
|
|
double dUnext ; // parametro sulla curva allo step (i+1)-esimo
|
|
Point3d ptCurr ; // punto sulla curva allo step i-esimo
|
|
if ( ! m_pCrv->GetPointD1D2( dUCurr, ICurve::FROM_MINUS, ptCurr))
|
|
return false ;
|
|
Point3d ptNext ; // punto sulla curva allo step (i+1)-esimo
|
|
|
|
// definizione dei versori r,s,t
|
|
Vector3d vt_r = m_Frame0.VersX() ;
|
|
Vector3d vt_s = m_Frame0.VersY() ;
|
|
Vector3d vt_t = m_Frame0.VersZ() ;
|
|
|
|
// ciclo sugli step in cui la curva è suddivisa
|
|
for ( int i = 0 ; i <= nStep ; ++ i) {
|
|
// ricavo la lunghezza della curva nello step successivo
|
|
dLenNext = min( dLen, ( i + 1) * dLen / nStep) ;
|
|
// parametro successivo sulla curva
|
|
if ( ! m_pCrv->GetParamAtLength( dLenNext, dUnext))
|
|
return false ;
|
|
// punto successivo sulla curva
|
|
if ( ! m_pCrv->GetPointD1D2( dUnext, ICurve::FROM_MINUS, ptNext))
|
|
return false ;
|
|
// ricavo il vettore di riflessione rispetto al piano R1
|
|
Vector3d v1 = ptNext - ptCurr ;
|
|
if ( ! v1.IsValid())
|
|
return false ;
|
|
// parametro di riflessione
|
|
double c1 = v1 * v1 ;
|
|
// riflessione rispetto al piano R1
|
|
Vector3d vt_r_L = vt_r - ( 2 / c1) * ( v1 * vt_r) * v1 ;
|
|
Vector3d vt_t_L = vt_t - ( 2 / c1) * ( v1 * vt_t) * v1 ;
|
|
// vettore tangente al punto successivo
|
|
Vector3d vt_t_next ;
|
|
Point3d ptH ;
|
|
if ( ! m_pCrv->GetPointD1D2( dUnext, ICurve::FROM_MINUS, ptH, &vt_t_next) ||
|
|
! vt_t_next.IsValid())
|
|
return false ;
|
|
// risplessione rispetto al piano R2
|
|
Vector3d v2 = vt_t_next - vt_t ;
|
|
if ( ! v2.IsValid())
|
|
return false ;
|
|
// parametro di riflessione
|
|
double c2 = v2 * v2 ;
|
|
// versore r del nuovo frame
|
|
Vector3d vt_r_next = vt_r_L - ( 2 / c2) * ( v2 * vt_r_L) * v2 ;
|
|
// versore t del nuovo frame
|
|
Vector3d vt_s_next = vt_t_next ^ vt_r_next ;
|
|
// creazione del nuovo frame
|
|
Frame3d RMFrame_next ;
|
|
RMFrame_next.Set( ptNext, vt_r_next, vt_s_next, vt_t_next) ;
|
|
if ( ! RMFrame_next.IsValid())
|
|
return false ;
|
|
// aggiornamento vettore dei frame
|
|
m_vRMFrams.push_back( RMFrame_next) ;
|
|
// aggiornamento dei parametri
|
|
dLenCurr = dLenNext ;
|
|
dUCurr = dUnext ;
|
|
ptCurr = ptNext ;
|
|
}
|
|
|
|
return true ;
|
|
} |