55ce22b06c
- piccoli aggiustamenti stilistici.
291 lines
8.8 KiB
C++
291 lines
8.8 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2013-2013
|
|
//----------------------------------------------------------------------------
|
|
// File : DistPointCurve.cpp Data : 02.01.14 Versione : 1.5a1
|
|
// Contenuto : Implementazione della classe distanza punto da Curva.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 02.01.14 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "DistPointArc.h"
|
|
#include "DistPointCrvBezier.h"
|
|
#include "DistPointCrvComposite.h"
|
|
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
DistPointCurve::DistPointCurve( const Point3d& ptP, const ICurve& Curve, bool bIsSegment)
|
|
{
|
|
// Il flag bIsSegment vale solo per linee.
|
|
|
|
// distanza non calcolata e curva sconosciuta
|
|
m_dDist = - 1 ;
|
|
m_pCurve = nullptr ;
|
|
|
|
// curva non valida
|
|
if ( &Curve == nullptr || ! Curve.IsValid())
|
|
return ;
|
|
|
|
// chiamo calcolatore opportuno
|
|
switch ( Curve.GetType()) {
|
|
case CRV_LINE :
|
|
LineCalculate( ptP, Curve, bIsSegment) ;
|
|
break ;
|
|
case CRV_ARC :
|
|
ArcCalculate( ptP, Curve) ;
|
|
break ;
|
|
case CRV_BEZIER :
|
|
CrvBezierCalculate( ptP, Curve) ;
|
|
break ;
|
|
case CRV_COMPO :
|
|
CrvCompositeCalculate( ptP, Curve) ;
|
|
break ;
|
|
default :
|
|
break ;
|
|
}
|
|
// salvo il punto
|
|
m_ptP = ptP ;
|
|
// salvo il puntatore alla curva
|
|
m_pCurve = &Curve ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
DistPointCurve::LineCalculate( const Point3d& ptP, const ICurve& Curve, bool bIsSegment)
|
|
{
|
|
DistPointLine dstPtLn( ptP, *GetCurveLine( &Curve), bIsSegment) ;
|
|
|
|
if ( dstPtLn.m_dSqDist >= 0) {
|
|
m_dDist = sqrt( dstPtLn.m_dSqDist) ;
|
|
m_Info.emplace_back( MDPCI_NORMAL, dstPtLn.m_dParam, dstPtLn.m_ptMinDist) ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
DistPointCurve::ArcCalculate( const Point3d& ptP, const ICurve& Curve)
|
|
{
|
|
DistPointArc dstPtArc( ptP, *GetCurveArc( &Curve)) ;
|
|
|
|
m_dDist = dstPtArc.m_dDist ;
|
|
m_Info = dstPtArc.m_Info ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
DistPointCurve::CrvBezierCalculate( const Point3d& ptP, const ICurve& Curve)
|
|
{
|
|
DistPointCrvBezier dstPtCBez( ptP, *GetCurveBezier( &Curve)) ;
|
|
|
|
m_dDist = dstPtCBez.m_dDist ;
|
|
m_Info = dstPtCBez.m_Info ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
DistPointCurve::CrvCompositeCalculate( const Point3d& ptP, const ICurve& Curve)
|
|
{
|
|
DistPointCrvComposite dstPtCCompo( ptP, *GetCurveComposite( &Curve)) ;
|
|
|
|
m_dDist = dstPtCCompo.m_dDist ;
|
|
m_Info = dstPtCCompo.m_Info ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
DistPointCurve::GetSqDist( double& dSqDist) const
|
|
{
|
|
if ( m_dDist < 0)
|
|
return false ;
|
|
|
|
dSqDist = m_dDist * m_dDist ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
DistPointCurve::GetDist( double& dDist) const
|
|
{
|
|
if ( m_dDist < 0)
|
|
return false ;
|
|
|
|
dDist = m_dDist ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
DistPointCurve::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) const
|
|
{
|
|
if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size())
|
|
return false ;
|
|
|
|
ptMinDist = m_Info[nInd].ptQ ;
|
|
nFlag = m_Info[nInd].nFlag ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
DistPointCurve::GetMinDistPoint( double dNearParam, Point3d& ptMinDist, int& nFlag) const
|
|
{
|
|
if ( m_dDist < 0 || m_Info.empty())
|
|
return false ;
|
|
|
|
// verifico se cade in una zona continua
|
|
for ( int i = 1 ; i < (int) m_Info.size() ; ++ i) {
|
|
if ( m_Info[i-1].nFlag == MDPCI_START_CONT &&
|
|
m_Info[i].nFlag == MDPCI_END_CONT) {
|
|
if ( dNearParam > m_Info[i-1].dPar && dNearParam < m_Info[i].dPar) {
|
|
nFlag = MDPCI_START_CONT ;
|
|
if ( m_pCurve != nullptr &&
|
|
m_pCurve->GetPointD1D2( dNearParam, ICurve::FROM_MINUS, ptMinDist))
|
|
return true ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// cerco punto discreto più vicino (anche estremi di zone continue)
|
|
double dParam ;
|
|
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
|
if ( i == 0 ||
|
|
abs( m_Info[i].dPar - dNearParam) < abs( dParam - dNearParam)) {
|
|
dParam = m_Info[i].dPar ;
|
|
ptMinDist = m_Info[i].ptQ ;
|
|
nFlag = m_Info[i].nFlag ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
DistPointCurve::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) const
|
|
{
|
|
if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size())
|
|
return false ;
|
|
|
|
dParam = m_Info[nInd].dPar ;
|
|
nFlag = m_Info[nInd].nFlag ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
DistPointCurve::GetParamAtMinDistPoint( double dNearParam, double& dParam, int& nFlag) const
|
|
{
|
|
if ( m_dDist < 0 || m_Info.empty())
|
|
return false ;
|
|
|
|
// verifico se cade in una zona continua
|
|
for ( int i = 1 ; i < (int) m_Info.size() ; ++ i) {
|
|
if ( m_Info[i-1].nFlag == MDPCI_START_CONT &&
|
|
m_Info[i].nFlag == MDPCI_END_CONT) {
|
|
if ( dNearParam > m_Info[i-1].dPar && dNearParam < m_Info[i].dPar) {
|
|
dParam = dNearParam ;
|
|
nFlag = MDPCI_START_CONT ;
|
|
return true ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// cerco punto discreto più vicino (anche estremi di zone continue)
|
|
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
|
if ( i == 0 ||
|
|
abs( m_Info[i].dPar - dNearParam) < abs( dParam - dNearParam)) {
|
|
dParam = m_Info[i].dPar ;
|
|
nFlag = m_Info[i].nFlag ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide) const
|
|
{
|
|
if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size())
|
|
return false ;
|
|
|
|
// se distanza nulla, il punto giace sulla curva
|
|
if ( m_dDist <= EPS_SMALL) {
|
|
nSide = MDS_ON ;
|
|
return true ;
|
|
}
|
|
|
|
// determino la tangente nell'intorno del punto
|
|
Point3d ptQ ;
|
|
Vector3d vtPreTg, vtPostTg ;
|
|
if ( m_pCurve == nullptr ||
|
|
! m_pCurve->GetPointTang( m_Info[nInd].dPar, ICurve::FROM_MINUS, ptQ, vtPreTg) ||
|
|
! m_pCurve->GetPointTang( m_Info[nInd].dPar, ICurve::FROM_PLUS, ptQ, vtPostTg))
|
|
return false ;
|
|
Vector3d vtTg = 0.5 * ( vtPreTg + vtPostTg) ;
|
|
// se tangenti opposte, si deve ricalcolare spostandosi un poco
|
|
if ( ! vtTg.Normalize()) {
|
|
double dDeltaU = 1000 * EPS_PARAM ;
|
|
if ( ! m_pCurve->GetPointTang( m_Info[nInd].dPar - dDeltaU, ICurve::FROM_MINUS, ptQ, vtPreTg) ||
|
|
! m_pCurve->GetPointTang( m_Info[nInd].dPar + dDeltaU, ICurve::FROM_PLUS, ptQ, vtPostTg))
|
|
return false ;
|
|
vtTg = 0.5 * ( vtPreTg + vtPostTg) ;
|
|
if ( ! vtTg.Normalize( EPS_ZERO))
|
|
return false ;
|
|
}
|
|
|
|
// determino la direzione di riferimento
|
|
Vector3d vtRef = vtN ^ vtTg ;
|
|
if ( ! vtRef.Normalize())
|
|
return false ;
|
|
|
|
// determino il lato di giacitura del punto
|
|
double dSide = vtRef * ( m_ptP - ptQ) ;
|
|
if ( abs( dSide) < EPS_SMALL)
|
|
nSide = MDS_ON ;
|
|
else if ( dSide > 0)
|
|
nSide = MDS_LEFT ;
|
|
else
|
|
nSide = MDS_RIGHT ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
DistPointCurve::GetSideAtMinDistPoint( double dNearParam, const Vector3d& vtN, int& nSide) const
|
|
{
|
|
if ( m_dDist < 0 || m_Info.empty())
|
|
return false ;
|
|
|
|
// cerco punto discreto più vicino (anche estremi di zone continue)
|
|
int nInd ;
|
|
double dParam ;
|
|
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
|
if ( i == 0 ||
|
|
abs( m_Info[i].dPar - dNearParam) < abs( dParam - dNearParam)) {
|
|
nInd = i ;
|
|
dParam = m_Info[i].dPar ;
|
|
}
|
|
}
|
|
// mi sono ricondotto al caso precedente
|
|
return GetSideAtMinDistPoint( nInd, vtN, nSide) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
DistPointCurve::GetMinDistInfo( int nInd, MinDistPCInfo& aInfo) const
|
|
{
|
|
if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size())
|
|
return false ;
|
|
|
|
aInfo = m_Info[nInd] ;
|
|
return true ;
|
|
}
|