650540e573
- semplificata e ottimizzata creazione di superficie trimesh box standard - miglioramenti sintattici vari.
199 lines
6.4 KiB
C++
199 lines
6.4 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2013-2014
|
|
//----------------------------------------------------------------------------
|
|
// File : DistPointArc.cpp Data : 13.01.14 Versione : 1.5a3
|
|
// Contenuto : Implementazione della classe distanza punto da circonferenza/arco.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 28.12.13 DS Creazione modulo.
|
|
// 13.01.14 DS Implementata gestione elica.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "DistPointArc.h"
|
|
#include "DistPointCrvAux.h"
|
|
#include "GeoConst.h"
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
DistPointArc::DistPointArc( const Point3d& ptP, const ICurveArc& arArc)
|
|
{
|
|
// distanza non calcolata
|
|
m_dDist = - 1 ;
|
|
|
|
if ( &arArc == nullptr || ! arArc.IsValid())
|
|
return ;
|
|
|
|
// se circonferenza
|
|
if ( arArc.IsACircle())
|
|
DistPointCircle( ptP, arArc) ;
|
|
|
|
// se arco in un piano
|
|
else if ( arArc.IsPlane())
|
|
DistPointFlatArc( ptP, arArc) ;
|
|
|
|
// altrimenti caso generico
|
|
else
|
|
DistPointHelix( ptP, arArc) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
DistPointArc::DistPointCircle( const Point3d& ptP, const ICurveArc& arArc)
|
|
{
|
|
// se il punto non sta sul centro dell'arco, posso calcolarne la posizione angolare
|
|
double dAngDeg ;
|
|
if ( arArc.CalcPointAngle( ptP, dAngDeg)) {
|
|
double dParam = dAngDeg / arArc.GetAngCenter() ;
|
|
if ( dParam < 0)
|
|
dParam = 0 ;
|
|
else if ( dParam > 1)
|
|
dParam = 1 ;
|
|
// calcolo del punto di minima distanza
|
|
Point3d ptMinDist ;
|
|
arArc.GetPointD1D2( dParam, ICurve::FROM_MINUS, ptMinDist) ;
|
|
// calcolo del valore di minima distanza
|
|
m_dDist = Dist( ptP, ptMinDist) ;
|
|
// salvo i dati
|
|
m_Info.emplace_back( MDPCI_NORMAL, dParam, ptMinDist) ;
|
|
}
|
|
// altrimenti tutti i punti della circonferenza sono a minima distanza
|
|
else {
|
|
// calcolo del valore di minima distanza
|
|
m_dDist = sqrt( SqDist( ptP, arArc.GetCenter()) + arArc.GetRadius() * arArc.GetRadius()) ;
|
|
// salvo iniziale e finale, come estremi del range
|
|
Point3d ptMinDist ;
|
|
arArc.GetStartPoint( ptMinDist) ;
|
|
m_Info.emplace_back( MDPCI_START_CONT, 0, ptMinDist) ;
|
|
arArc.GetEndPoint( ptMinDist) ;
|
|
m_Info.emplace_back( MDPCI_END_CONT, 1, ptMinDist) ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
DistPointArc::DistPointFlatArc( const Point3d& ptP, const ICurveArc& arArc)
|
|
{
|
|
// calcolo come per il cerchio (ma angolo al centro corretto)
|
|
DistPointCircle( ptP, arArc) ;
|
|
|
|
// se non tutti i punti e il parametro è sui bordi, li verifico entrambi
|
|
if ( m_Info[0].nFlag != MDPCI_START_CONT &&
|
|
( abs( m_Info[0].dPar) < EPS_ZERO || abs( m_Info[0].dPar - 1) < EPS_ZERO)) {
|
|
for ( int i = 0 ; i <= 1 ; i ++) {
|
|
// eseguo il calcolo
|
|
double dU = i ;
|
|
Point3d ptTest ;
|
|
arArc.GetPointD1D2( dU, ICurve::FROM_MINUS, ptTest) ;
|
|
double dDist = Dist( ptP, ptTest) ;
|
|
// altro punto con la stessa minima distanza
|
|
if ( i == 1 && abs( dDist - m_dDist) < EPS_SMALL) {
|
|
// lo aggiungo
|
|
m_Info.emplace_back( MDPCI_NORMAL, dU, ptTest) ;
|
|
}
|
|
// primo punto o punto con minima distanza più bassa
|
|
else if ( i == 0 || dDist < m_dDist) {
|
|
// aggiorno i minimi
|
|
m_dDist = dDist ;
|
|
// il nuovo vettore deve contenere solo quest'ultimo minimo
|
|
m_Info.clear() ;
|
|
m_Info.emplace_back( MDPCI_NORMAL, dU, ptTest) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
DistPointArc::DistPointHelix( const Point3d& ptP, const ICurveArc& arArc)
|
|
{
|
|
// determino tolleranza di approssimazione in base a raggio curva
|
|
double dRad = arArc.GetRadius() ;
|
|
const double FRAZ = 0.2 ;
|
|
double dLinTol = ( ( FRAZ * dRad > LIN_TOL_APPROX) ? LIN_TOL_APPROX : FRAZ * dRad) ;
|
|
|
|
// creo una polilinea di approssimazione
|
|
PolyLine PL ;
|
|
if ( ! arArc.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL))
|
|
return ;
|
|
|
|
// cerco la minima distanza per la polilinea
|
|
MDCVECTOR vApproxMin ;
|
|
if ( ! CalcMinDistPointPolyLine( ptP, PL, dLinTol, vApproxMin))
|
|
return ;
|
|
|
|
// raffino i punti trovati
|
|
double dPolishedPar ;
|
|
Point3d ptPolishedQ ;
|
|
for ( auto Iter = vApproxMin.begin() ; Iter != vApproxMin.end() ; ++Iter) {
|
|
// eseguo raffinamento
|
|
if ( PolishMinDistPointCurve( ptP, arArc, *Iter, dPolishedPar, ptPolishedQ)) {
|
|
(*Iter).dDist = Dist( ptP, ptPolishedQ) ;
|
|
(*Iter).dPar = dPolishedPar ;
|
|
(*Iter).ptQ = ptPolishedQ ;
|
|
}
|
|
else
|
|
(*Iter).dDist = INFINITO ;
|
|
}
|
|
|
|
// determino i minimi raffinati da tenere
|
|
double dMinDist ;
|
|
if ( FilterMinDistPointCurve( ptP, arArc, vApproxMin, dMinDist, m_Info))
|
|
m_dDist = dMinDist ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
DistPointArc::GetSqDist( double& dSqDist) const
|
|
{
|
|
if ( m_dDist < 0)
|
|
return false ;
|
|
|
|
dSqDist = m_dDist * m_dDist ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
DistPointArc::GetDist( double& dDist) const
|
|
{
|
|
if ( m_dDist < 0)
|
|
return false ;
|
|
|
|
dDist = m_dDist ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
DistPointArc::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) const
|
|
{
|
|
if ( m_dDist < 0)
|
|
return false ;
|
|
|
|
if ( nInd < 0 || nInd >= (int) m_Info.size())
|
|
return false ;
|
|
|
|
ptMinDist = m_Info[nInd].ptQ ;
|
|
nFlag = m_Info[nInd].nFlag ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
DistPointArc::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) const
|
|
{
|
|
if ( m_dDist < 0)
|
|
return false ;
|
|
|
|
if ( nInd < 0 || nInd >= (int) m_Info.size())
|
|
return false ;
|
|
|
|
dParam = m_Info[nInd].dPar ;
|
|
nFlag = m_Info[nInd].nFlag ;
|
|
return true ;
|
|
}
|