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