From e87ef178c2e1dc6c003843a73cdb644e2747ff14 Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Tue, 10 Feb 2026 15:42:03 +0100 Subject: [PATCH] EgtGeomKernel : - correzione alla distanza punto- curva di bezier. --- DistPointCrvAux.cpp | 17 +++++++++++++++-- DistPointCrvBezier.cpp | 11 +++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/DistPointCrvAux.cpp b/DistPointCrvAux.cpp index fee8316..7afeb91 100644 --- a/DistPointCrvAux.cpp +++ b/DistPointCrvAux.cpp @@ -116,6 +116,7 @@ PolishMinDistPointCurve( const Point3d& ptP, const ICurve& cCurve, vtDiff = ptQ - ptP ; // angolo tra vettore e tangente dTemp = vtDer1 * vtDiff ; + bool bEquiverse = dTemp > 0 ; if ( abs( dTemp) > EPS_ZERO) dSqCosA = dTemp * dTemp / ( vtDer1.SqLen() * vtDiff.SqLen()) ; else @@ -123,8 +124,20 @@ PolishMinDistPointCurve( const Point3d& ptP, const ICurve& cCurve, // stima prossimo valore del parametro (Newton : Unext = U - F(U) / F'(U)) dPrevPar = dPar ; dTemp = vtDer2 * vtDiff + vtDer1.SqLen() ; - if ( abs( dTemp) > EPS_ZERO) - dPar = dPrevPar - ( vtDer1 * vtDiff) / dTemp ; + + // se il coseno tra questi due vettori è troppo grande potrei aver avuto una cattiva stima iniziale + // provo quindi ad aggiustare a mano, anziché usare il segno suggerito da newton, che con queste premesse potrebbe divergere + double dCos75 = 0.2588 ; + if ( abs( dTemp) > EPS_ZERO) { + double dDelta = ( vtDer1 * vtDiff) / dTemp ; + if ( dSqCosA > dCos75) { + if ( ( bEquiverse && dDelta > 0) || ( ! bEquiverse && dDelta < 0)) + dDelta *= -1 ; + dPar = dPrevPar + dDelta ; + } + else + dPar = dPrevPar - dDelta ; + } // clipping parametro if ( dPar < approxMin.dParMin) { if ( approxMin.bParMinSing && ! bClampedFromSing) { diff --git a/DistPointCrvBezier.cpp b/DistPointCrvBezier.cpp index 9c324a5..6106698 100644 --- a/DistPointCrvBezier.cpp +++ b/DistPointCrvBezier.cpp @@ -42,6 +42,17 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& if ( ! CrvBez.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL)) return ; + int nDeg = CrvBez.GetDegree() ; + if ( PL.GetPointNbr() < nDeg + 1) { + // costruisco una polilinea con un numero di curve scelto in base al grado della curva + PL.Clear() ; + for ( int i = 0 ; i <= nDeg + 1 ; ++i) { + double dU = double(i) / (nDeg + 1) ; + Point3d ptBez ; + CrvBez.GetPointD1D2( dU, ICurve::Side::FROM_MINUS, ptBez) ; + PL.AddUPoint( dU, ptBez) ; + } + } // cerco la minima distanza per la polilinea MDCVECTOR vApproxMin ; if ( ! CalcMinDistPointPolyLine( ptP, PL, dLinTol, vApproxMin))