diff --git a/CurveBezier.cpp b/CurveBezier.cpp index e6cece4..f99684c 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -975,18 +975,24 @@ CurveBezier::FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart, // curva da dividere { + double dParDiv ; double dParMid ; CurveBezier crvBez1 ; - // parametro a metà - dParMid = 0.5 * ( dParStart + dParEnd) ; + // se prima suddivisione e c'è singolarità, divido su questa + if ( nLev == 0 && GetSingularParam( dParDiv) > 0) + ; + // altrimenti divido a metà + else + dParDiv = 0.5 ; + dParMid = dParDiv * ( dParStart + dParEnd) ; // prima metà crvBez1 = crvBez ; - crvBez1.TrimEndAtParam( 0.5) ; + crvBez1.TrimEndAtParam( dParDiv) ; if ( ! FlatOrSplit( nLev + 1, crvBez1, dParStart, dParMid, dLinTol, dAngTolDeg, PL)) return false ; // seconda metà crvBez1 = crvBez ; - crvBez1.TrimStartAtParam( 0.5) ; + crvBez1.TrimStartAtParam( dParDiv) ; if ( ! FlatOrSplit( nLev + 1, crvBez1, dParMid, dParEnd, dLinTol, dAngTolDeg, PL)) return false ; } diff --git a/DistPointArc.cpp b/DistPointArc.cpp index a7d89af..f63d5c4 100644 --- a/DistPointArc.cpp +++ b/DistPointArc.cpp @@ -60,25 +60,31 @@ DistPointArc::DistPointCircle( const Point3d& ptP, const ICurveArc& arArc) if ( vtDiffPlane.Normalize()) { bool bDet ; double dAngDeg ; + double dParam ; + Point3d ptMinDist ; 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 ; + dParam = dAngDeg / arArc.GetAngCenter() ; + if ( dParam < 0) + dParam = 0 ; + else if ( dParam > 1) + dParam = 1 ; + // calcolo del punto di minima distanza + arArc.GetPointD1D2( dParam, ICurve::FROM_MINUS, ptMinDist) ; + // salvo i dati + m_Info.push_back( MinDistPCInfo( MDPCI_NORMAL, dParam, ptMinDist)) ; } else { - // tutti i punti della circonferenza sono a minima distanza, imposto il punto medio - m_dParam = 0.5 ; - m_bDet = false ; + Point3d ptMinDist ; + // tutti i punti della circonferenza sono a minima distanza salvo iniziale e finale + arArc.GetStartPoint( ptMinDist) ; + m_Info.push_back( MinDistPCInfo( MDPCI_START_CONT, 0, ptMinDist)) ; + arArc.GetEndPoint( ptMinDist) ; + m_Info.push_back( MinDistPCInfo( MDPCI_END_CONT, 1, ptMinDist)) ; } - // calcolo del punto di minima distanza - arArc.GetPointD1D2( m_dParam, ICurve::FROM_MINUS, m_ptMinDist) ; } //---------------------------------------------------------------------------- @@ -88,18 +94,27 @@ 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 ; + // se non tutti i punti e il parametro è sui bordi, li verifico entrambi + if ( m_Info[0].nFlag != MDPCI_START_CONT && + ( fabs( m_Info[0].dPar) < EPS_ZERO || fabs( 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 dSqDist = SqDist( ptP, ptTest) ; - if ( dSqDist < m_dDist * m_dDist) { - m_dDist = sqrt( dSqDist) ; - m_dParam = dU ; - m_ptMinDist = ptTest ; + double dDist = Dist( ptP, ptTest) ; + // altro punto con la stessa minima distanza + if ( i == 1 && fabs( dDist - m_dDist) < EPS_SMALL) { + // lo aggiungo + m_Info.push_back( MinDistPCInfo( 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.push_back( MinDistPCInfo( MDPCI_NORMAL, dU, ptTest)) ; } } } @@ -136,26 +151,30 @@ DistPointArc::GetDist( double& dDist) //---------------------------------------------------------------------------- bool -DistPointArc::GetPointMinDist( Point3d& ptMinDist, bool* pbDet) +DistPointArc::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) { if ( m_dDist < 0) return false ; - ptMinDist = m_ptMinDist ; - if ( pbDet != nullptr) - *pbDet = m_bDet ; + if ( nInd < 0 || nInd >= (int) m_Info.size()) + return false ; + + ptMinDist = m_Info[nInd].ptQ ; + nFlag = m_Info[nInd].nFlag ; return true ; } //---------------------------------------------------------------------------- bool -DistPointArc::GetParamAtPointMinDist( double& dParam, bool* pbDet) +DistPointArc::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) { if ( m_dDist < 0) return false ; - dParam = m_dParam ; - if ( pbDet != nullptr) - *pbDet = m_bDet ; + if ( nInd < 0 || nInd >= (int) m_Info.size()) + return false ; + + dParam = m_Info[nInd].dPar ; + nFlag = m_Info[nInd].nFlag ; return true ; } diff --git a/DistPointArc.h b/DistPointArc.h index 711da5c..c7d6891 100644 --- a/DistPointArc.h +++ b/DistPointArc.h @@ -15,14 +15,7 @@ #include "/EgtDev/Include/EGkPoint3d.h" #include "/EgtDev/Include/EGkCurveArc.h" - -//----------------------- Macro per import/export ---------------------------- -#undef EGK_EXPORT -#if defined( I_AM_EGK) // da definirsi solo nella DLL - #define EGK_EXPORT __declspec( dllexport) -#else - #define EGK_EXPORT __declspec( dllimport) -#endif +#include "/EgtDev/Include/EGkDistPointCurve.h" //----------------------------------------------------------------------------- @@ -31,13 +24,14 @@ class DistPointArc friend class DistPointCurve ; public : - EGK_EXPORT DistPointArc( const Point3d& ptP, const ICurveArc& arArc) ; + DistPointArc( const Point3d& ptP, const ICurveArc& arArc) ; public : - EGK_EXPORT bool GetSqDist( double& dSqDist) ; - EGK_EXPORT bool GetDist( double& dDist) ; - EGK_EXPORT bool GetPointMinDist( Point3d& ptMinDist, bool* pbDet = nullptr) ; - EGK_EXPORT bool GetParamAtPointMinDist( double& dParam, bool* pbDet = nullptr) ; + bool GetSqDist( double& dSqDist) ; + bool GetDist( double& dDist) ; + int GetNbrMinDist( void) { return m_Info.size() ; } + bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) ; + bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) ; private : DistPointArc( void) ; @@ -46,9 +40,7 @@ class DistPointArc void DistPointHelix( const Point3d& ptP, const ICurveArc& arArc) ; private : - bool m_bDet ; - double m_dDist ; - double m_dParam ; - Point3d m_ptMinDist ; + double m_dDist ; + MDPCIVECTOR m_Info ; } ; diff --git a/DistPointCrvBezier.cpp b/DistPointCrvBezier.cpp index 0450611..1f906aa 100644 --- a/DistPointCrvBezier.cpp +++ b/DistPointCrvBezier.cpp @@ -42,19 +42,6 @@ struct MinDistCalc { } ; typedef std::vector MDCVECTOR ; // vettore di MinDistCalc -//---------------------------------------------------------------------------- -enum MdiType { MDI_NORMAL, MDI_START_CONT, MDI_END_CONT} ; -struct MinDistInfo { - MdiType nFlag ; - double dPar ; - Point3d ptQ ; - MinDistInfo( void) - : nFlag( MDI_NORMAL), dPar( 0), ptQ( 0, 0, 0) {} - MinDistInfo( MdiType nF, double dP, Point3d pT) - : nFlag( nF), dPar( dP), ptQ( pT) {} -} ; -typedef std::vector MDIVECTOR ; // vettore di MinDistInfo - //---------------------------------------------------------------------------- bool PolishMinDistPointCurve( const Point3d& ptP, const ICurve& cCurve, @@ -160,8 +147,8 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& if ( bFound && fabs( dSqDist - dSqMinDist) < 2 * dMinDist * LIN_TOL_APPROX) { // salvo i dati nella struttura approxMin.dDist = dMinDist ; - dstPtLn.GetPointMinDist( approxMin.ptQ) ; - dstPtLn.GetParamAtPointMinDist( dPar) ; + dstPtLn.GetMinDistPoint( approxMin.ptQ) ; + dstPtLn.GetParamAtMinDistPoint( dPar) ; approxMin.dPar = ( 1 - dPar) * dUIni + dPar * dUFin ; approxMin.dParMin = dUIni ; approxMin.dParMax = dUFin ; @@ -178,8 +165,8 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& dMinDist = sqrt( dSqMinDist) ; // salvo i dati nella struttura approxMin.dDist = dMinDist ; - dstPtLn.GetPointMinDist( approxMin.ptQ) ; - dstPtLn.GetParamAtPointMinDist( dPar) ; + dstPtLn.GetMinDistPoint( approxMin.ptQ) ; + dstPtLn.GetParamAtMinDistPoint( dPar) ; approxMin.dPar = ( 1 - dPar) * dUIni + dPar * dUFin ; approxMin.dParMin = dUIni ; approxMin.dParMax = dUFin ; @@ -222,17 +209,16 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& } // determino i minimi raffinati da tenere - MDIVECTOR vQmin ; bFound = false ; for ( Iter = vApproxMin.begin() ; Iter != vApproxMin.end() ; ++Iter) { // altro punto con la stessa minima distanza if ( bFound && fabs( (*Iter).dDist - dMinDist) < EPS_SMALL) { // se abbastanza lontano lo aggiungo - if ( SqDist( (*Iter).ptQ, vQmin.back().ptQ) > 1) - vQmin.push_back( MinDistInfo( MDI_NORMAL, (*Iter).dPar, (*Iter).ptQ)) ; + if ( SqDist( (*Iter).ptQ, m_Info.back().ptQ) > 1) + m_Info.push_back( MinDistPCInfo( MDPCI_NORMAL, (*Iter).dPar, (*Iter).ptQ)) ; // altrimenti lo sostituisco se distanza minore else if ( (*Iter).dDist < dMinDist) - vQmin.back() = MinDistInfo( MDI_NORMAL, (*Iter).dPar, (*Iter).ptQ) ; + m_Info.back() = MinDistPCInfo( MDPCI_NORMAL, (*Iter).dPar, (*Iter).ptQ) ; } // primo punto o punto con minima distanza più bassa else if ( ! bFound || (*Iter).dDist < dMinDist) { @@ -240,21 +226,21 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& bFound = true ; dMinDist = (*Iter).dDist ; // il nuovo vettore deve contenere solo quest'ultimo minimo - vQmin.clear() ; - vQmin.push_back( MinDistInfo( MDI_NORMAL, (*Iter).dPar, (*Iter).ptQ)) ; + m_Info.clear() ; + m_Info.push_back( MinDistPCInfo( MDPCI_NORMAL, (*Iter).dPar, (*Iter).ptQ)) ; } } - if ( vQmin.empty()) + if ( m_Info.empty()) return ; // se 2 o più minimi, verifico se tratto continuo - if ( vQmin.size() >= 2) { + if ( m_Info.size() >= 2) { bool bCont = true ; double dU ; Point3d ptQ ; // se tutti i punti intermedi hanno la stessa distanza, è una zona continua - for ( int i = 1 ; i < (int) vQmin.size() ; ++ i) { - dU = 0.5 * ( vQmin[i-1].dPar + vQmin[i].dPar) ; + for ( int i = 1 ; i < (int) m_Info.size() ; ++ i) { + dU = 0.5 * ( m_Info[i-1].dPar + m_Info[i].dPar) ; CrvBez.GetPointD1D2( dU, ICurve::FROM_MINUS, ptQ) ; if ( fabs( SqDist( ptP, ptQ) - dMinDist * dMinDist) > 2 * dMinDist * EPS_SMALL) { bCont = false ; @@ -264,33 +250,30 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& // se zona continua è un arco di circonferenza, tengo solo primo e ultimo punto e imposto opportuni flag if ( bCont) { // se è praticamente tutta la curva, la faccio diventare tutta - if ( ( vQmin.back().dPar - vQmin.front().dPar) > 0.8) { + if ( ( m_Info.back().dPar - m_Info.front().dPar) > 0.8) { // primo elemento == inizio della curva - vQmin[0].dPar = 0 ; - vQmin[0].nFlag = MDI_START_CONT ; - CrvBez.GetStartPoint( vQmin[0].ptQ) ; + m_Info[0].dPar = 0 ; + m_Info[0].nFlag = MDPCI_START_CONT ; + CrvBez.GetStartPoint( m_Info[0].ptQ) ; // ultimo elemento == fine curva - vQmin[1].dPar = 1 ; - vQmin[1].nFlag = MDI_END_CONT ; - CrvBez.GetEndPoint( vQmin[1].ptQ) ; + m_Info[1].dPar = 1 ; + m_Info[1].nFlag = MDPCI_END_CONT ; + CrvBez.GetEndPoint( m_Info[1].ptQ) ; } else { // sistemo flag primo elemento - vQmin[0].nFlag = MDI_START_CONT ; + m_Info[0].nFlag = MDPCI_START_CONT ; // sposto ultimo elemento al secondo posto e ne sistemo il flag - vQmin[1] = vQmin.back() ; - vQmin[1].nFlag = MDI_END_CONT ; + m_Info[1] = m_Info.back() ; + m_Info[1].nFlag = MDPCI_END_CONT ; } // cancello tutti gli altri elementi - vQmin.erase( vQmin.begin() + 2, vQmin.end()) ; + m_Info.erase( m_Info.begin() + 2, m_Info.end()) ; } } - // assegno i dati - m_bDet = ( vQmin[0].nFlag == MDI_NORMAL) ; + // salvo anche il valore della minima distanza m_dDist = dMinDist ; - m_dParam = vQmin[0].dPar ; - m_ptMinDist = vQmin[0].ptQ ; } //---------------------------------------------------------------------------- @@ -317,26 +300,30 @@ DistPointCrvBezier::GetDist( double& dDist) //---------------------------------------------------------------------------- bool -DistPointCrvBezier::GetPointMinDist( Point3d& ptMinDist, bool* pbDet) +DistPointCrvBezier::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) { if ( m_dDist < 0) return false ; - ptMinDist = m_ptMinDist ; - if ( pbDet != nullptr) - *pbDet = m_bDet ; + if ( nInd < 0 || nInd >= (int) m_Info.size()) + return false ; + + ptMinDist = m_Info[nInd].ptQ ; + nFlag = m_Info[nInd].nFlag ; return true ; } //---------------------------------------------------------------------------- bool -DistPointCrvBezier::GetParamAtPointMinDist( double& dParam, bool* pbDet) +DistPointCrvBezier::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) { if ( m_dDist < 0) return false ; - dParam = m_dParam ; - if ( pbDet != nullptr) - *pbDet = m_bDet ; + if ( nInd < 0 || nInd >= (int) m_Info.size()) + return false ; + + dParam = m_Info[nInd].dPar ; + nFlag = m_Info[nInd].nFlag ; return true ; } diff --git a/DistPointCrvBezier.h b/DistPointCrvBezier.h index 3ab812a..f7d36d3 100644 --- a/DistPointCrvBezier.h +++ b/DistPointCrvBezier.h @@ -15,14 +15,7 @@ #include "/EgtDev/Include/EGkPoint3d.h" #include "/EgtDev/Include/EGkCurveBezier.h" - -//----------------------- Macro per import/export ---------------------------- -#undef EGK_EXPORT -#if defined( I_AM_EGK) // da definirsi solo nella DLL - #define EGK_EXPORT __declspec( dllexport) -#else - #define EGK_EXPORT __declspec( dllimport) -#endif +#include "/EgtDev/Include/EGkDistPointCurve.h" //----------------------------------------------------------------------------- @@ -31,21 +24,20 @@ class DistPointCrvBezier friend class DistPointCurve ; public : - EGK_EXPORT DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& CrvBez) ; + DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& CrvBez) ; public : - EGK_EXPORT bool GetSqDist( double& dSqDist) ; - EGK_EXPORT bool GetDist( double& dDist) ; - EGK_EXPORT bool GetPointMinDist( Point3d& ptMinDist, bool* pbDet = nullptr) ; - EGK_EXPORT bool GetParamAtPointMinDist( double& dParam, bool* pbDet = nullptr) ; + bool GetSqDist( double& dSqDist) ; + bool GetDist( double& dDist) ; + int GetNbrMinDist( void) { return m_Info.size() ; } + bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) ; + bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) ; private : DistPointCrvBezier( void) ; private : - bool m_bDet ; - double m_dDist ; - double m_dParam ; - Point3d m_ptMinDist ; + double m_dDist ; + MDPCIVECTOR m_Info ; } ; diff --git a/DistPointCurve.cpp b/DistPointCurve.cpp index 3af2fe6..0a070b1 100644 --- a/DistPointCurve.cpp +++ b/DistPointCurve.cpp @@ -22,8 +22,9 @@ //---------------------------------------------------------------------------- DistPointCurve::DistPointCurve( const Point3d& ptP, const ICurve& Curve) { - // distanza non calcolata + // distanza non calcolata e curva sconosciuta m_dDist = - 1 ; + m_pCurve = nullptr ; // curva non valida if ( ! Curve.IsValid()) @@ -44,6 +45,8 @@ DistPointCurve::DistPointCurve( const Point3d& ptP, const ICurve& Curve) CrvCompositeCalculate( ptP, Curve) ; break ; } + // salvo il puntatore alla curva + m_pCurve = &Curve ; } //---------------------------------------------------------------------------- @@ -52,10 +55,10 @@ DistPointCurve::LineCalculate( const Point3d& ptP, const ICurve& Curve) { DistPointLine dstPtLn( ptP, *GetCurveLine( &Curve)) ; - m_bDet = true ; - m_dDist = (( dstPtLn.m_dSqDist > 0) ? sqrt( dstPtLn.m_dSqDist) : dstPtLn.m_dSqDist) ; - m_dParam = dstPtLn.m_dParam ; - m_ptMinDist = dstPtLn.m_ptMinDist ; + if ( dstPtLn.m_dSqDist > 0) { + m_dDist = sqrt( dstPtLn.m_dSqDist) ; + m_Info.push_back( MinDistPCInfo( MDPCI_NORMAL, dstPtLn.m_dParam, dstPtLn.m_ptMinDist)) ; + } } //---------------------------------------------------------------------------- @@ -64,10 +67,8 @@ DistPointCurve::ArcCalculate( const Point3d& ptP, const ICurve& Curve) { DistPointArc dstPtArc( ptP, *GetCurveArc( &Curve)) ; - m_bDet = dstPtArc.m_bDet ; m_dDist = dstPtArc.m_dDist ; - m_dParam = dstPtArc.m_dParam ; - m_ptMinDist = dstPtArc.m_ptMinDist ; + m_Info = dstPtArc.m_Info ; } //---------------------------------------------------------------------------- @@ -76,10 +77,8 @@ DistPointCurve::CrvBezierCalculate( const Point3d& ptP, const ICurve& Curve) { DistPointCrvBezier dstPtCBez( ptP, *GetCurveBezier( &Curve)) ; - m_bDet = dstPtCBez.m_bDet ; m_dDist = dstPtCBez.m_dDist ; - m_dParam = dstPtCBez.m_dParam ; - m_ptMinDist = dstPtCBez.m_ptMinDist ; + m_Info = dstPtCBez.m_Info ; } //---------------------------------------------------------------------------- @@ -113,26 +112,101 @@ DistPointCurve::GetDist( double& dDist) //---------------------------------------------------------------------------- bool -DistPointCurve::GetPointMinDist( Point3d& ptMinDist, bool* pbDet) +DistPointCurve::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) { if ( m_dDist < 0) return false ; - ptMinDist = m_ptMinDist ; - if ( pbDet != nullptr) - *pbDet = m_bDet ; + if ( nInd < 0 || nInd >= (int) m_Info.size()) + return false ; + + ptMinDist = m_Info[nInd].ptQ ; + nFlag = m_Info[nInd].nFlag ; return true ; } //---------------------------------------------------------------------------- bool -DistPointCurve::GetParamAtPointMinDist( double& dParam, bool* pbDet) +DistPointCurve::GetMinDistPoint( double dNearParam, Point3d& ptMinDist, int& nFlag) { if ( m_dDist < 0) return false ; - dParam = m_dParam ; - if ( pbDet != nullptr) - *pbDet = m_bDet ; + if ( 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 || + fabs( m_Info[i].dPar - dNearParam) < fabs( 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) +{ + 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 ; +} + +//---------------------------------------------------------------------------- +bool +DistPointCurve::GetParamAtMinDistPoint( double dNearParam, double& dParam, int& nFlag) +{ + if ( m_dDist < 0) + return false ; + + if ( 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 || + fabs( m_Info[i].dPar - dNearParam) < fabs( dParam - dNearParam)) { + dParam = m_Info[i].dPar ; + nFlag = m_Info[i].nFlag ; + } + } + return true ; } diff --git a/DistPointLine.cpp b/DistPointLine.cpp index 1687385..3d8ca8d 100644 --- a/DistPointLine.cpp +++ b/DistPointLine.cpp @@ -21,7 +21,7 @@ DistPointLine::DistPointLine( const Point3d& ptP, const ICurveLine& crvLine, bool bIsSegment) { // distanza non calcolata - m_dDist = - 1 ; + m_dSqDist = - 1 ; if ( ! crvLine.IsValid()) return ; @@ -108,7 +108,7 @@ DistPointLine::GetDist( double& dDist) //---------------------------------------------------------------------------- bool -DistPointLine::GetPointMinDist( Point3d& ptMinDist) +DistPointLine::GetMinDistPoint( Point3d& ptMinDist) { if ( m_dSqDist < 0) return false ; @@ -119,7 +119,7 @@ DistPointLine::GetPointMinDist( Point3d& ptMinDist) //---------------------------------------------------------------------------- bool -DistPointLine::GetParamAtPointMinDist( double& dParam) +DistPointLine::GetParamAtMinDistPoint( double& dParam) { if ( m_dSqDist < 0) return false ; diff --git a/DistPointLine.h b/DistPointLine.h index fdf86e6..b89aa4e 100644 --- a/DistPointLine.h +++ b/DistPointLine.h @@ -16,14 +16,6 @@ #include "/EgtDev/Include/EGkPoint3d.h" #include "/EgtDev/Include/EGkCurveLine.h" -//----------------------- Macro per import/export ---------------------------- -#undef EGK_EXPORT -#if defined( I_AM_EGK) // da definirsi solo nella DLL - #define EGK_EXPORT __declspec( dllexport) -#else - #define EGK_EXPORT __declspec( dllimport) -#endif - //----------------------------------------------------------------------------- class DistPointLine @@ -31,19 +23,20 @@ class DistPointLine friend class DistPointCurve ; public : - EGK_EXPORT DistPointLine( const Point3d& ptP, - const ICurveLine& crvLine, bool bIsSegment = true) ; - EGK_EXPORT DistPointLine( const Point3d& ptP, - const Point3d& ptIni, const Point3d& ptFin, bool bIsSegment = true) ; - EGK_EXPORT DistPointLine( const Point3d& ptP, - const Point3d& ptIni, const Vector3d& vtDir, double dLen, bool bIsSegment = true) - { Calculate( ptP, ptIni, vtDir, dLen, bIsSegment) ; } + DistPointLine( const Point3d& ptP, + const ICurveLine& crvLine, bool bIsSegment = true) ; + DistPointLine( const Point3d& ptP, + const Point3d& ptIni, const Point3d& ptFin, bool bIsSegment = true) ; + DistPointLine( const Point3d& ptP, + const Point3d& ptIni, const Vector3d& vtDir, double dLen, bool bIsSegment = true) + { Calculate( ptP, ptIni, vtDir, dLen, bIsSegment) ; } public : - EGK_EXPORT bool GetSqDist( double& dSqDist) ; - EGK_EXPORT bool GetDist( double& dDist) ; - EGK_EXPORT bool GetPointMinDist( Point3d& ptMinDist) ; - EGK_EXPORT bool GetParamAtPointMinDist( double& dParam) ; + bool GetSqDist( double& dSqDist) ; + bool GetDist( double& dDist) ; + int GetNbrMinDist( void) { return (( m_dSqDist < 0) ? 0 : 1) ; } + bool GetMinDistPoint( Point3d& ptMinDist) ; + bool GetParamAtMinDistPoint( double& dParam) ; private : DistPointLine( void) ; diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index 04fb09c..cdc6fd1 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -292,8 +292,8 @@ GdbExecutor::ExecuteCurveLine( const string& sCmd2, const STRVECTOR& vsParams) } // creazione linea di minima distanza tra punto e curva else if ( sCmd2 == "MINPOINTCURVE" || sCmd2 == "MPC") { - // 4 parametri - if ( vsParams.size() != 4) + // almeno 4 parametri + if ( vsParams.size() < 4) return false ; // recupero l'identificativo del gruppo destinazione int nIdParent ; @@ -322,10 +322,15 @@ GdbExecutor::ExecuteCurveLine( const string& sCmd2, const STRVECTOR& vsParams) // porto il punto nel riferimento della curva Point3d ptSloc = ptStart ; ptSloc.LocToLoc( frPoint, frCurve) ; + // recupero eventuale parametro per discriminare tra più soluzioni + double dNearParam ; + if ( vsParams.size() < 5 || ! FromString( vsParams[4], dNearParam)) + dNearParam = 0 ; // calcolo il punto a minima distanza + int nFlag ; Point3d ptEnd ; DistPointCurve dstPtCurve( ptSloc, *pCurve) ; - if ( ! dstPtCurve.GetPointMinDist( ptEnd)) + if ( ! dstPtCurve.GetMinDistPoint( dNearParam, ptEnd, nFlag)) return false ; // porto il punto finale nel riferimento di creazione ptEnd.LocToLoc( frCurve, frPoint) ;