diff --git a/FilletChamfer.cpp b/FilletChamfer.cpp index b754037..35ef8df 100644 --- a/FilletChamfer.cpp +++ b/FilletChamfer.cpp @@ -147,6 +147,10 @@ CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1, &vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr) return nullptr ; + // verifico il minimo raggio + if ( dRadius < 10 * EPS_SMALL) + return nullptr ; + // eseguo calcoli Point3d ptCen, ptTg1, ptTg2 ; int nSide1, nSide2 ; @@ -165,6 +169,11 @@ CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1, return nullptr ; } + // verifico dimensione minima + double dLen = Dist( ptTg1, ptTg2) ; + if ( dLen < 2 * EPS_SMALL) + return nullptr ; + // orientamento tra le curve bool bCCW = ( dSinA > 0) ; @@ -207,6 +216,10 @@ CreateChamfer( const ICurve& cCrv1, const Point3d& ptNear1, &vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr) return nullptr ; + // verifico lo smusso minimo + if ( dDist < 10 * EPS_SMALL) + return nullptr ; + // calcolo un riferimento sul piano perpendicolare alla normale Frame3d frIntr ; if ( ! frIntr.Set( ORIG, vtNorm)) diff --git a/IntersLineLine.cpp b/IntersLineLine.cpp index 189d6f7..896df6c 100644 --- a/IntersLineLine.cpp +++ b/IntersLineLine.cpp @@ -19,20 +19,18 @@ using namespace std ; //---------------------------------------------------------------------------- -// Il punto è esterno al FatSegment se dista da questo più di Tol e la sua proiezione sta sul segmento -bool -IsPointOutFatSegment( const Point3d& ptP, const Point3d& ptS, const Vector3d& vtDir, double dLenXY, double dTol) +// Posizione del punto rispetto alla linea (+1=a destra, 0=nella banda di tolleranza, -1=a sinistra) +static int +GetPointToLineSide( const Point3d& ptP, const Point3d& ptS, const Vector3d& vtDir, double dLenXY, double dTol) { - // distanza del punto dalla linea del segmento (con compensazione piccolissimi errori) - if ( abs( CrossXY( ( ptP - ptS), vtDir)) < ( dTol + EPS_ZERO) * dLenXY) - return false ; - // distanza con segno della proiezione del punto sul segmento dall'inizio per lunghezza segmento - double dDistXY = ScalarXY( ( ptP - ptS), vtDir) ; - // se il punto non si proietta sul segmento entro la tolleranza - if ( dDistXY < - dTol * dLenXY || dDistXY > ( dLenXY + dTol) * dLenXY) - return false ; - // altrimenti - return true ; + double dCross = CrossXY( ( ptP - ptS), vtDir) ; + double dFat = ( dTol + EPS_ZERO) * dLenXY ; + if ( dCross > dFat) + return +1 ; + else if ( dCross < - dFat) + return -1 ; + else + return 0 ; } //---------------------------------------------------------------------------- @@ -44,7 +42,7 @@ IntersLineLine::IntersLineLine( const CurveLine& Line1, const CurveLine& Line2, m_bOverlaps = false ; m_nNumInters = 0 ; - // verifico validità linee + // verifico validità linee if ( ! Line1.IsValid() || ! Line2.IsValid()) return ; @@ -130,30 +128,36 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line if ( ! boxL1.OverlapsXY( boxL2)) return ; - // linea 1 : Start, End, Direzione e Lunghezza + // segmento 1 : Start, End, Direzione e Lunghezza Point3d ptS1 = Line1.GetStart() ; Point3d ptE1 = Line1.GetEnd() ; Vector3d vtDir1 = ptE1 - ptS1 ; double dLen1XY = vtDir1.LenXY() ; if ( dLen1XY < EPS_SMALL) return ; - // linea 2 : Start, Direzione e Lunghezza + // segmento 2 : Start, Direzione e Lunghezza Point3d ptS2 = Line2.GetStart() ; Point3d ptE2 = Line2.GetEnd() ; Vector3d vtDir2 = ptE2 - ptS2 ; double dLen2XY = vtDir2.LenXY() ; if ( dLen2XY < EPS_SMALL) return ; + // posizioni estremi segmento 1 rispetto a linea 2 + int nS1Side = GetPointToLineSide( ptS1, ptS2, vtDir2, dLen2XY, EPS_SMALL) ; + int nE1Side = GetPointToLineSide( ptE1, ptS2, vtDir2, dLen2XY, EPS_SMALL) ; + if ( ( nS1Side == 1 && nE1Side == 1) || ( nS1Side == -1 && nE1Side == -1)) + return ; + // posizioni estremi segmento 2 rispetto a linea 1 + int nS2Side = GetPointToLineSide( ptS2, ptS1, vtDir1, dLen1XY, EPS_SMALL) ; + int nE2Side = GetPointToLineSide( ptE2, ptS1, vtDir1, dLen1XY, EPS_SMALL) ; + if ( ( nS2Side == 1 && nE2Side == 1) || ( nS2Side == -1 && nE2Side == -1)) + return ; // prodotto vettoriale nel piano XY tra le direzioni delle linee double dCrossXY = CrossXY( vtDir1, vtDir2) ; // flag per linee parallele bool bParallel = ( abs( dCrossXY) < SIN_EPS_ANG_ZERO * ( dLen1XY * dLen2XY)) ; // flag per segmenti che si allontanano significativamente - bool bFarEnds = ( /*( abs( dCrossXY) > SIN_EPS_ANG_SMALL * ( dLen1XY * dLen2XY)) ||*/ - IsPointOutFatSegment( ptS1, ptS2, vtDir2, dLen2XY, EPS_SMALL) || - IsPointOutFatSegment( ptE1, ptS2, vtDir2, dLen2XY, EPS_SMALL) || - IsPointOutFatSegment( ptS2, ptS1, vtDir1, dLen1XY, EPS_SMALL) || - IsPointOutFatSegment( ptE2, ptS1, vtDir1, dLen1XY, EPS_SMALL)) ; + bool bFarEnds = ( nS1Side != 0 || nE1Side != 0 || nS2Side != 0 || nE2Side != 0) ; // se non sono paralleli e si allontanano tra loro abbastanza if ( ! bParallel && bFarEnds) { @@ -168,6 +172,8 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line nPos1 = ICurve::PP_END ; // vicino a fine else if ( m_Info.IciA[0].dU > 0 && m_Info.IciA[0].dU < 1) nPos1 = ICurve::PP_MID ; // nell'interno + else + return ; // verifica posizione intersezione su seconda linea int nPos2 = ICurve::PP_NULL ; // fuori if ( abs( m_Info.IciB[0].dU * dLen2XY) < EPS_SMALL) @@ -176,8 +182,7 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line nPos2 = ICurve::PP_END ; // vicino a fine else if ( m_Info.IciB[0].dU > 0 && m_Info.IciB[0].dU < 1) nPos2 = ICurve::PP_MID ; // nell'interno - // se soluzione non accettata, esco - if ( nPos1 == ICurve::PP_NULL || nPos2 == ICurve::PP_NULL) + else return ; // limito i parametri a stare sui segmenti (0...1) m_Info.IciA[0].dU = min( max( m_Info.IciA[0].dU, 0.), 1.) ; @@ -190,7 +195,7 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line m_Info.IciA[0].nNextTy = ICCT_NULL ; m_Info.IciB[0].nPrevTy = ICCT_NULL ; m_Info.IciB[0].nNextTy = ICCT_NULL ; - // si incontrano alle estremità, non si può dire alcunché + // si incontrano alle estremità, non si può dire alcunché if ( ( nPos1 == ICurve::PP_START || nPos1 == ICurve::PP_END) && ( nPos2 == ICurve::PP_START || nPos2 == ICurve::PP_END)) { ; // rimangono tutti NULL