//---------------------------------------------------------------------------- // EgalTech 2013-2013 //---------------------------------------------------------------------------- // File : DistPointArc.cpp Data : 28.12.13 Versione : 1.4l5 // Contenuto : Implementazione della classe distanza punto da circonferenza/arco. // // // // Modifiche : 28.12.13 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "DistPointArc.h" //---------------------------------------------------------------------------- DistPointArc::DistPointArc( const Point3d& ptP, const ICurveArc& arArc) { // distanza non calcolata m_dDist = - 1 ; if ( ! arArc.IsValid()) return ; // se circonferenza if ( arArc.IsACircle()) DistPointCircle( ptP, arArc) ; // se arco in un piano else if ( arArc.IsFlat()) DistPointFlatArc( ptP, arArc) ; // altrimenti caso generico else DistPointHelix( ptP, arArc) ; } //---------------------------------------------------------------------------- void DistPointArc::DistPointCircle( const Point3d& ptP, const ICurveArc& arArc) { // vettori ausiliari Vector3d vtDiff = ptP - arArc.GetCenter() ; double dDistN = vtDiff * arArc.GetNormVersor() ; Vector3d vtDiffPlane = vtDiff - dDistN * arArc.GetNormVersor() ; double dDistPlane = fabs( vtDiffPlane.Len() - arArc.GetRadius()) ; // calcolo della distanza if ( fabs( dDistPlane) > EPS_ZERO && fabs( dDistN) > EPS_ZERO) m_dDist = sqrt( dDistPlane * dDistPlane + dDistN * dDistN) ; else if ( fabs( dDistPlane) > EPS_ZERO) m_dDist = dDistPlane ; else if ( fabs( dDistN) > EPS_ZERO) m_dDist = fabs( dDistN) ; else m_dDist = 0 ; // calcolo del parametro del punto a minima distanza if ( vtDiffPlane.Normalize()) { bool bDet ; double dAngDeg ; arArc.GetStartVersor().GetRotation( vtDiffPlane, arArc.GetNormVersor(), dAngDeg, bDet) ; if ( arArc.GetAngCenter() > 0 && dAngDeg < 0) dAngDeg += 360 ; else if ( arArc.GetAngCenter() < 0 && dAngDeg > 0) dAngDeg -= 360 ; m_dParam = dAngDeg / arArc.GetAngCenter() ; if ( m_dParam < 0) m_dParam = 0 ; else if ( m_dParam > 1) m_dParam = 1 ; m_bDet = true ; } else { // tutti i punti della circonferenza sono a minima distanza, imposto il punto medio m_dParam = 0.5 ; m_bDet = false ; } // calcolo del punto di minima distanza arArc.GetPointD1D2( m_dParam, ICurve::FROM_MINUS, m_ptMinDist) ; } //---------------------------------------------------------------------------- void DistPointArc::DistPointFlatArc( const Point3d& ptP, const ICurveArc& arArc) { // calcolo come per il cerchio (ma angolo al centro corretto) DistPointCircle( ptP, arArc) ; // se il parametro è sui bordi, verifico quale dei due if ( fabs( m_dParam) < EPS_ZERO || fabs( m_dParam - 1) < EPS_ZERO) { Point3d ptTest ; m_dDist = INFINITO ; for ( int i = 0 ; i <= 1 ; i ++) { double dU = i ; arArc.GetPointD1D2( dU, ICurve::FROM_MINUS, ptTest) ; double dSqDist = SqDist( ptP, ptTest) ; if ( dSqDist < m_dDist * m_dDist) { m_dDist = sqrt( dSqDist) ; m_dParam = dU ; m_ptMinDist = ptTest ; } } } } //---------------------------------------------------------------------------- void DistPointArc::DistPointHelix( const Point3d& ptP, const ICurveArc& arArc) { } //---------------------------------------------------------------------------- bool DistPointArc::GetSqDist( double& dSqDist) { if ( m_dDist < 0) return false ; dSqDist = m_dDist * m_dDist ; return true ; } //---------------------------------------------------------------------------- bool DistPointArc::GetDist( double& dDist) { if ( m_dDist < 0) return false ; dDist = m_dDist ; return true ; } //---------------------------------------------------------------------------- bool DistPointArc::GetPointMinDist( Point3d& ptMinDist, bool* pbDet) { if ( m_dDist < 0) return false ; ptMinDist = m_ptMinDist ; if ( pbDet != nullptr) *pbDet = m_bDet ; return true ; } //---------------------------------------------------------------------------- bool DistPointArc::GetParamAtPointMinDist( double& dParam, bool* pbDet) { if ( m_dDist < 0) return false ; dParam = m_dParam ; if ( pbDet != nullptr) *pbDet = m_bDet ; return true ; }