EgtGeomKernel 3.1f2 :
- aggiunta modalità per IntersLineCyl - spostate funzioni relative - cambiuo versione.
This commit is contained in:
@@ -2071,127 +2071,6 @@ VolZmap::CDeSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecise)
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Riferimento con origine nel centro della base e asse di simmetria coincidente con l'asse Z.
|
||||
// La funzione restituisce true in caso di intersezione, false altrimenti.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||
const Frame3d& CylFrame, double dH, double dRad, bool bTapLow, bool bTapUp,
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const
|
||||
{
|
||||
// Porto la linea nel riferimento del cilindro
|
||||
Point3d ptP = GetToLoc( ptLineSt, CylFrame) ;
|
||||
Vector3d vtV = GetToLoc( vtLineDir, CylFrame) ;
|
||||
|
||||
// Determino le eventuali intersezioni con le due basi a quota minima e massima (solo se linea non parallela ad esse)
|
||||
int nBasInt = 0 ;
|
||||
if ( abs( vtV.z) > EPS_ZERO) {
|
||||
// le linee tangenti al cilindro non sono considerate intersecanti
|
||||
double dEpsRad = ( vtV.IsZeroXY() ? - EPS_SMALL : EPS_SMALL) ;
|
||||
ptInt1 = ptP + ( ( 0 - ptP.z) / vtV.z) * vtV ;
|
||||
if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dRad * dRad + 2 * dRad * dEpsRad) {
|
||||
nBasInt += 1 ;
|
||||
vtN1 = Z_AX ;
|
||||
}
|
||||
ptInt2 = ptP + ( ( dH - ptP.z) / vtV.z) * vtV ;
|
||||
if ( ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y < dRad * dRad + 2 * dRad * dEpsRad) {
|
||||
nBasInt += 2 ;
|
||||
vtN2 = - Z_AX ;
|
||||
}
|
||||
}
|
||||
|
||||
// Se la linea interseca entrambe le basi, si sono trovate le due intersezioni
|
||||
if ( nBasInt == 3) {
|
||||
// Porto i punti e i versori nel riferimento globale
|
||||
ptInt1.ToGlob( CylFrame) ;
|
||||
vtN1.ToGlob( CylFrame) ;
|
||||
ptInt2.ToGlob( CylFrame) ;
|
||||
vtN2.ToGlob( CylFrame) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Determino le intersezioni con la superficie laterale del cilindro
|
||||
DBLVECTOR vdCoeff{ ptP.x * ptP.x + ptP.y * ptP.y - dRad * dRad,
|
||||
2 * ( ptP.x * vtV.x + ptP.y * vtV.y),
|
||||
vtV.x * vtV.x + vtV.y * vtV.y} ;
|
||||
DBLVECTOR vdRoots ;
|
||||
int nRoot = PolynomialRoots( 2, vdCoeff, vdRoots) ;
|
||||
|
||||
// Epsilon per piani di tappo
|
||||
double dEpsLow = ( bTapLow ? - EPS_SMALL : EPS_SMALL) ;
|
||||
double dEpsUp = ( bTapUp ? EPS_SMALL : - EPS_SMALL) ;
|
||||
|
||||
// Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z del cilindro
|
||||
if ( nRoot == 2) {
|
||||
double dIntZ2 = ptP.z + vdRoots[1] * vtV.z ;
|
||||
if ( dIntZ2 < 0 + dEpsLow || dIntZ2 > dH + dEpsUp)
|
||||
-- nRoot ;
|
||||
}
|
||||
if ( nRoot >= 1) {
|
||||
double dIntZ1 = ptP.z + vdRoots[0] * vtV.z ;
|
||||
if ( dIntZ1 < 0 + dEpsLow || dIntZ1 > dH + dEpsUp) {
|
||||
if ( nRoot == 2)
|
||||
vdRoots[0] = vdRoots[1] ;
|
||||
-- nRoot ;
|
||||
}
|
||||
}
|
||||
|
||||
// Due soluzioni: la retta interseca due volte la superficie laterale
|
||||
if ( nRoot == 2) {
|
||||
// Punti di intersezione con la superficie del cilindro
|
||||
ptInt1 = ptP + vdRoots[0] * vtV ;
|
||||
ptInt2 = ptP + vdRoots[1] * vtV ;
|
||||
// Determino le normali
|
||||
vtN1.Set( -ptInt1.x, -ptInt1.y, 0) ;
|
||||
vtN1.Normalize() ;
|
||||
vtN2.Set( -ptInt2.x, -ptInt2.y, 0) ;
|
||||
vtN2.Normalize() ;
|
||||
// Porto i punti e i versori nel riferimento globale
|
||||
ptInt1.ToGlob( CylFrame) ;
|
||||
vtN1.ToGlob( CylFrame) ;
|
||||
ptInt2.ToGlob( CylFrame) ;
|
||||
vtN2.ToGlob( CylFrame) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Una soluzione : la retta interseca la superficie laterale e un piano
|
||||
else if ( nRoot == 1) {
|
||||
// Se piano superiore
|
||||
if ( nBasInt == 2) {
|
||||
// Punto di intersezione
|
||||
ptInt1 = ptP + vdRoots[0] * vtV ;
|
||||
// Normale alla superficie del cilindro verso l'interno
|
||||
vtN1.Set( -ptInt1.x, -ptInt1.y, 0) ;
|
||||
vtN1.Normalize() ;
|
||||
}
|
||||
// altrimenti piano inferiore
|
||||
else if ( nBasInt == 1) {
|
||||
// Punto di intersezione
|
||||
ptInt2 = ptP + vdRoots[0] * vtV ;
|
||||
// Normale alla superficie del cilindro verso l'interno
|
||||
vtN2.Set( -ptInt2.x, -ptInt2.y, 0) ;
|
||||
vtN2.Normalize() ;
|
||||
}
|
||||
// altrimenti niente
|
||||
else
|
||||
return false ;
|
||||
// Porto i punti e i versori nel riferimento globale
|
||||
ptInt1.ToGlob( CylFrame) ;
|
||||
vtN1.ToGlob( CylFrame) ;
|
||||
ptInt2.ToGlob( CylFrame) ;
|
||||
vtN2.ToGlob( CylFrame) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Nessuna soluzione : nessuna intersezione
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Riferimento con origine nel vertice del cono e asse di simmetria coincidente con l'asse Z.
|
||||
// La funzione restituisce true in caso di intersezione, false altrimenti.
|
||||
|
||||
Reference in New Issue
Block a user