EgtGeomKernel 1.9h1 :

- sistemazioni varie in CAvToolTriangle
- utilizzo di std::async in CAvToolSurfTm
- corretto GetAllTriaAroundVertex di SurfTm
- aggiunto ( nothrow) a tutti i new.
This commit is contained in:
Dario Sassi
2018-08-08 11:02:56 +00:00
parent d0fb939541
commit 866ed0b3d7
28 changed files with 618 additions and 475 deletions
+301 -233
View File
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2018-2018
//----------------------------------------------------------------------------
// File : CAvToolTriangle.cpp Data : 19.07.18 Versione : 1.9g2
// File : CAvToolTriangle.cpp Data : 19.07.18 Versione : 1.9h1
// Contenuto : Implementazione delle funzioni ToolTriangleCollisionAvoid.
//
//
@@ -34,7 +34,7 @@ GetTopTapFromPrevCurve( const ICurve* pPrevCurve)
const Point3d& ptPrevStart = pPrevLine->GetStart() ;
const Point3d& ptPrevEnd = pPrevLine->GetEnd() ;
if ( abs( ptPrevStart.y - ptPrevEnd.y) > EPS_SMALL ||
ptPrevStart.x > ptPrevEnd.x)
ptPrevStart.x > ptPrevEnd.x)
return true ;
}
else if ( pPrevCurve->GetType() == CRV_ARC) {
@@ -56,7 +56,8 @@ GetBotTapFromNextCurve( const ICurve* pNextCurve)
const ICurveLine* pNextLine = GetCurveLine( pNextCurve) ;
const Point3d& ptNextStart = pNextLine->GetStart() ;
const Point3d& ptNextEnd = pNextLine->GetEnd() ;
if ( abs( ptNextStart.y - ptNextEnd.y) > EPS_SMALL || ptNextStart.x < ptNextEnd.x)
if ( abs( ptNextStart.y - ptNextEnd.y) > EPS_SMALL ||
ptNextStart.x < ptNextEnd.x)
return true ;
}
else if ( pNextCurve->GetType() == CRV_ARC) {
@@ -77,6 +78,9 @@ double
CAvToolTriangle( const Tool& tlTool, const Point3d& ptToolOrig, const Vector3d& vtToolAx,
const Triangle3d& trTria, const Vector3d& vtMove)
{
// Non ha senso che il movimento sia in direzione "opposta" a quella dell'asse utensile
if ( vtMove * vtToolAx < - EPS_ZERO)
return -1. ;
// Se avvicinamento non devo fare nulla
if ( vtMove * trTria.GetN() < - EPS_ZERO)
return 0. ;
@@ -85,9 +89,15 @@ CAvToolTriangle( const Tool& tlTool, const Point3d& ptToolOrig, const Vector3d&
// parametri geometrici
double dHeigth = tlTool.GetHeigth() ;
double dRadius = tlTool.GetRadius() ;
// distanza di allontanamento del cilindro
double dDist = CAvCylinderTriangle( ptToolOrig, vtToolAx, dHeigth, dRadius, trTria, vtMove, false, false) ;
return dDist ;
// prima determino l'allontanamento del disco inferiore
double dDist = CAvDiskTriangle( ptToolOrig - dHeigth * vtToolAx, vtToolAx, dRadius, trTria, vtMove) ;
if ( dDist < - EPS_SMALL)
return dDist ;
// poi verifico quello del cilindro (tenendo conto di quanto è stata allontanato il disco)
double dDist2 = CAvCylinderTriangle( ptToolOrig + dDist * vtMove, vtToolAx, dHeigth, dRadius, trTria, vtMove, false, false) ;
if ( dDist2 < - EPS_SMALL)
return dDist2 ;
return ( dDist + dDist2) ;
}
// se utensile sferico
else if ( tlTool.GetType() == Tool::BALLMILL) {
@@ -102,7 +112,7 @@ CAvToolTriangle( const Tool& tlTool, const Point3d& ptToolOrig, const Vector3d&
// poi verifico quello del cilindro (tenendo conto di quanto è stata allontanata la sfera)
if ( dCylHeigth < EPS_SMALL)
return dDist ;
Point3d ptCylOrig = ptToolOrig + vtMove * max( dDist, 0.) ;
Point3d ptCylOrig = ptToolOrig + vtMove * dDist ;
double dDist2 = CAvCylinderTriangle( ptCylOrig, vtToolAx, dCylHeigth, dRadius, trTria, vtMove, false, true) ;
if ( dDist2 < - EPS_SMALL)
return dDist2 ;
@@ -111,21 +121,28 @@ CAvToolTriangle( const Tool& tlTool, const Point3d& ptToolOrig, const Vector3d&
// se utensile a naso di toro
else if ( tlTool.GetType() == Tool::BULLNOSEMILL) {
// parametri geometrici
double dCylHeigth = tlTool.GetHeigth() - tlTool.GetTipHeigth() ;
Point3d ptTorusCen = ptToolOrig - dCylHeigth * vtToolAx ;
// prima determino l'allontanamento del toro
double dDist = CAvTorusTriangle( ptTorusCen, vtToolAx, tlTool.GetRadius() - tlTool.GetCornRadius(), tlTool.GetCornRadius(),
trTria, vtMove, true, false) ;
double dCylHeigth = tlTool.GetHeigth() - tlTool.GetTipHeigth() ;
// prima determino l'allontanamento del disco inferiore
double dDist = CAvDiskTriangle( ptToolOrig - tlTool.GetHeigth() * vtToolAx, vtToolAx, tlTool.GetTipRadius(),
trTria, vtMove) ;
if ( dDist < - EPS_SMALL)
return dDist ;
// poi verifico quello del cilindro (tenendo conto di quanto è stata allontanato il toro)
if ( dCylHeigth < EPS_SMALL)
return dDist ;
Point3d ptCylOrig = ptToolOrig + vtMove * max( dDist, 0.) ;
double dDist2 = CAvCylinderTriangle( ptCylOrig, vtToolAx, dCylHeigth, tlTool.GetRadius(), trTria, vtMove, false, true) ;
// poi verifico quello del toro (tenendo conto di quanto è stata allontanato il disco)
Point3d ptTorusCen = ptToolOrig - dCylHeigth * vtToolAx ;
double dDist2 = CAvTorusTriangle( ptTorusCen + dDist * vtMove, vtToolAx,
tlTool.GetRadius() - tlTool.GetCornRadius(), tlTool.GetCornRadius(),
trTria, vtMove, true, false) ;
if ( dDist2 < - EPS_SMALL)
return dDist2 ;
return ( dDist + dDist2) ;
// infine verifico quello del cilindro (tenendo conto dei precedenti allontanamenti)
if ( dCylHeigth < EPS_SMALL)
return ( dDist + dDist2) ;
Point3d ptCylOrig = ptToolOrig + vtMove * ( dDist + dDist2) ;
double dDist3 = CAvCylinderTriangle( ptCylOrig, vtToolAx, dCylHeigth, tlTool.GetRadius(),
trTria, vtMove, false, true) ;
if ( dDist3 < - EPS_SMALL)
return dDist3 ;
return ( dDist + dDist2 + dDist3) ;
}
// se utensile conico
else if ( tlTool.GetType() == Tool::CONEMILL) {
@@ -143,18 +160,25 @@ CAvToolTriangle( const Tool& tlTool, const Point3d& ptToolOrig, const Vector3d&
double dMinR = min( tlTool.GetRadius(), tlTool.GetTipRadius()) ;
double dMaxR = max( tlTool.GetRadius(), tlTool.GetTipRadius()) ;
double dCylHeigth = tlTool.GetHeigth() - tlTool.GetTipHeigth() ;
// prima determino l'allontanamento del cono
double dDist = CAvTrConeTriangle( ptMinBase, vtConeAx, dMinR, dMaxR, tlTool.GetTipHeigth(), trTria, vtMove, true, false) ;
// prima determino l'allontanamento del disco inferiore
double dDist = CAvDiskTriangle( ptToolOrig - tlTool.GetHeigth() * vtToolAx, vtToolAx, tlTool.GetTipRadius(),
trTria, vtMove) ;
if ( dDist < - EPS_SMALL)
return dDist ;
// poi verifico quello del cilindro (tenendo conto di quanto è stata allontanato il cono)
if ( dCylHeigth < EPS_SMALL)
return dDist ;
Point3d ptCylOrig = ptToolOrig + vtMove * max( dDist, 0.) ;
double dDist2 = CAvCylinderTriangle( ptCylOrig, vtToolAx, dCylHeigth, tlTool.GetRadius(), trTria, vtMove, false, true) ;
// poi verifico quello del cono (tenendo conto di quanto è stata allontanato il disco)
double dDist2 = CAvTrConeTriangle( ptMinBase + dDist * vtMove, vtConeAx, dMinR, dMaxR, tlTool.GetTipHeigth(),
trTria, vtMove, true, false) ;
if ( dDist2 < - EPS_SMALL)
return dDist2 ;
return ( dDist + dDist2) ;
// infine verifico quello del cilindro (tenendo conto dei precedenti allontanamenti)
if ( dCylHeigth < EPS_SMALL)
return ( dDist + dDist2) ;
Point3d ptCylOrig = ptToolOrig + vtMove * ( dDist + dDist2) ;
double dDist3 = CAvCylinderTriangle( ptCylOrig, vtToolAx, dCylHeigth, tlTool.GetRadius(),
trTria, vtMove, false, true) ;
if ( dDist3 < - EPS_SMALL)
return dDist3 ;
return ( dDist + dDist2 + dDist3) ;
}
// se utensile generico
else if ( tlTool.GetType() == Tool::GEN) {
@@ -164,13 +188,14 @@ CAvToolTriangle( const Tool& tlTool, const Point3d& ptToolOrig, const Vector3d&
Point3d ptCompOrig = ptToolOrig - tlTool.GetHeigth() * vtToolAx ;
// analizzo le curve del profilo a partire dall'ultima
const CurveComposite* pToolProfile = tlTool.GetOutline() ;
const ICurve* pCurve = pToolProfile->GetLastCurve() ;
int nCrv = pToolProfile->GetCurveCount() - 1 ;
const ICurve* pCurve = pToolProfile->GetCurve( nCrv) ;
const ICurve* pNextCurve = nullptr ;
while ( pCurve != nullptr) {
// distanza di allontanamento del tratto corrente
double dDist2 = 0 ;
// curva precedente
const ICurve* pPrevCurve = pToolProfile->GetPrevCurve() ;
const ICurve* pPrevCurve = pToolProfile->GetCurve( -- nCrv) ;
// Se segmento
if ( pCurve->GetType() == CRV_LINE) {
// Recupero gli estremi
@@ -179,7 +204,14 @@ CAvToolTriangle( const Tool& tlTool, const Point3d& ptToolOrig, const Vector3d&
const Point3d& ptEnd = pLine->GetEnd() ;
// Ne determino l'altezza
double dHeight = abs( ptStart.y - ptEnd.y) ;
if ( dHeight > EPS_SMALL) {
if ( dHeight <= EPS_SMALL) {
// solo se disco verso il basso dell'utensile
if ( ptStart.x > ptEnd.x) {
double dRadius = max( ptStart.x, ptEnd.x) ;
dDist2 = CAvDiskTriangle( ptCompOrig, vtToolAx, dRadius, trTria, vtMove) ;
}
}
else {
// Verifiche curva precedente per eventuale tappo sopra
bool bTop = GetTopTapFromPrevCurve( pPrevCurve) ;
// Verifiche curva successiva per eventuale tappo sotto
@@ -361,7 +393,7 @@ SphereSegmentLeakDist( const Point3d& ptSpheCen, double dSpheRad,
{
// Controllo con l'interno del segmento
double dU[2] ;
int nTanPointNum = SphereLineTangentPoints( ptSpheCen, dSpheRad, ptSeg, vtSegDir, dSegLen, vtMove, dU[0], dU[1]) ;
int nTanPointNum = SphereLineTangentPoints( ptSpheCen, dSpheRad - EPS_SMALL, ptSeg, vtSegDir, dSegLen, vtMove, dU[0], dU[1]) ;
double dLeakDistIn = 0. ;
for ( int nSol = 0 ; nSol < nTanPointNum && nTanPointNum != 3 ; ++ nSol) {
if ( dU[nSol] < 0.)
@@ -404,71 +436,14 @@ double
CAvCylinderTriangle( const Point3d& ptCylOrig, const Vector3d& vtCylAx, double dHeigth, double dRad,
const Triangle3d& trTria, const Vector3d& vtMove, bool bTop, bool bBot)
{
// Classificazione del moto
int nMotionType = 0 ;
if ( AreSameVectorApprox( vtCylAx, vtMove))
nMotionType = 1 ;
else if ( AreOppositeVectorApprox( vtCylAx, vtMove))
nMotionType = 2 ;
else if ( AreOrthoApprox( vtCylAx, vtMove))
nMotionType = 3 ;
// Movimento lungo la direzione dell'asse del cilindro
if ( nMotionType == 1 || nMotionType == 2) {
// In questo caso il problema si riduce alla determinazione della distanza di allontanamento
// del disco all'estremità opposta rispetto alla direzione di moto.
// Il punto base di questo disco viene così calcolato
Point3d ptBase = ptCylOrig ;
if ( nMotionType == 1)
ptBase -= dHeigth * vtCylAx ;
// Valuto le distanze con segno dei vertici dal piano del disco :
// se sono tutte negative non interferiscono.
double dDistV[3] ;
dDistV[0] = PointPlaneSignedDist( trTria.GetP( 0), ptBase, vtMove) ;
dDistV[1] = PointPlaneSignedDist( trTria.GetP( 1), ptBase, vtMove) ;
dDistV[2] = PointPlaneSignedDist( trTria.GetP( 2), ptBase, vtMove) ;
double dMaxDistV = max( dDistV[0], max( dDistV[1], dDistV[2])) ;
if ( dMaxDistV < 0.)
return 0. ;
// Se tutti i punti distano dall'asse di movimento meno del raggio, l'ultimo
// punto di contatto deve essere un vertice del triangolo.
double dSqRad = dRad * dRad ;
bool bInV[3] ;
bInV[0] = ( GetPointLineSqDist( trTria.GetP( 0), ptBase, vtMove) < dSqRad) ;
bInV[1] = ( GetPointLineSqDist( trTria.GetP( 1), ptBase, vtMove) < dSqRad) ;
bInV[2] = ( GetPointLineSqDist( trTria.GetP( 2), ptBase, vtMove) < dSqRad) ;
if ( bInV[0] && bInV[1] && bInV[2])
return max( dMaxDistV, 0.) ;
// Distanza di allontanamento dall'interno del triangolo
double dMaxDistI = DiskTriaInteriorLeakDistLongMot( ptBase, dRad, trTria, vtMove) ;
if ( dMaxDistI > EPS_SMALL)
return dMaxDistI ;
// Ciclo sui segmenti del triangolo e calcolo la loro distanza di allontanamento, calcolo
// anche la distanza di allontanamento dai vertici distanti dall'asse meno del raggio.
double dMaxDistVS = 0. ;
for ( int nVS = 0 ; nVS < 3 ; ++ nVS) {
// Vertici
if ( bInV[nVS] && dDistV[nVS] > dMaxDistVS)
dMaxDistVS = dDistV[nVS] ;
// Se un lato del triangolo ha entrambi gli estremi con distanza negativa dal piano del disco,
// non può interferire con esso.
int nVE = ( nVS + 1) % 3 ;
if ( dDistV[nVS] < 0 && dDistV[nVE] < 0)
continue ;
// Versore e lunghezza del segmento
Vector3d vtSeg = trTria.GetP( nVE) - trTria.GetP( nVS) ;
double dSegLen = vtSeg.Len() ;
vtSeg /= dSegLen ;
// Distanza dal piano del segmento corrente
double dCurDist = DiskSegmentLeakDistLongMot( ptBase, dRad, trTria.GetP( nVS), vtSeg, dSegLen, vtMove) ;
if ( dCurDist > dMaxDistVS)
dMaxDistVS = dCurDist ;
}
return dMaxDistVS ;
if ( AreSameVectorApprox( vtCylAx, vtMove)) {
// la distanza di fuga è determinata dal disco
// o dai componenti sotto il cilindro.
return 0. ;
}
// Movimento perpendicolare all'asse del cilindro
else if ( nMotionType == 3) {
else if ( AreOrthoApprox( vtCylAx, vtMove)) {
double dLeakDist = 0. ;
// INTERNO : se distanza di allontanamento da interno è positiva, abbiamo finito
Point3d ptTopCont, ptBotCont ;
@@ -516,9 +491,11 @@ CAvCylinderTriangle( const Point3d& ptCylOrig, const Vector3d& vtCylAx, double d
}
return dLeakDist ;
}
// Movimento generico
else
else if ( vtMove * vtCylAx > 0)
return 0. ;
// Errore
else
return -1. ;
}
@@ -649,14 +626,19 @@ CAvTrConeTriangle( const Point3d& ptMinBase, const Vector3d& vtTrConeAx, double
if ( AreSameOrOppositeVectorApprox( vtTrConeAx, vtMove)) {
// Verifica preliminare che la fetta di spazio delimitata dal piano sotto del cono rispetto alla direzione
// di allontanamento non sia già sopra al triangolo (tutti i vertici del triangolo sono sotto).
Point3d ptBase = ptMinBase ;
Point3d ptInfLim = ptMinBase ;
if ( AreOppositeVectorApprox( vtTrConeAx, vtMove))
ptBase += dTrConeH * vtTrConeAx ;
double dMaxDistV = PointPlaneSignedDist( trTria.GetP( 0), ptBase, vtMove) ;
dMaxDistV = max( dMaxDistV, PointPlaneSignedDist( trTria.GetP( 1), ptBase, vtMove)) ;
dMaxDistV = max( dMaxDistV, PointPlaneSignedDist( trTria.GetP( 2), ptBase, vtMove)) ;
ptInfLim += dTrConeH * vtTrConeAx ;
double dMaxDistV = PointPlaneSignedDist( trTria.GetP( 0), ptInfLim, vtMove) ;
dMaxDistV = max( dMaxDistV, PointPlaneSignedDist( trTria.GetP( 1), ptInfLim, vtMove)) ;
dMaxDistV = max( dMaxDistV, PointPlaneSignedDist( trTria.GetP( 2), ptInfLim, vtMove)) ;
if ( dMaxDistV < 0.)
return 0. ;
bool bInside[3] = { GetPointLineSqDist( trTria.GetP( 0), ptMinBase, vtMove) < dMinBaseR * dMinBaseR,
GetPointLineSqDist( trTria.GetP( 1), ptMinBase, vtMove) < dMinBaseR * dMinBaseR,
GetPointLineSqDist( trTria.GetP( 2), ptMinBase, vtMove) < dMinBaseR * dMinBaseR} ;
if ( bInside[0] && bInside[1] && bInside[2])
return 0. ;
// Distanza di allontanamento dall'interno
double dInnLeakDist = TrConeTriangleInteriorLeakDistLongMot( ptMinBase, vtTrConeAx, dMinBaseR, dMaxBaseR, dTrConeH,
trTria, vtMove) ;
@@ -665,10 +647,12 @@ CAvTrConeTriangle( const Point3d& ptMinBase, const Vector3d& vtTrConeAx, double
// Distanza di allontanamento dai vertici e lati
double dOutLeakDist = 0 ;
for ( int nV = 0 ; nV < 3 ; ++ nV) {
if ( bInside[nV] && bInside[( nV + 1) % 3])
continue ;
// dal vertice
double dCurVertDist = TrConePointLeakDistLongMot( ptMinBase, vtTrConeAx, dMinBaseR, dMaxBaseR, dTrConeH,
trTria.GetP( nV), vtMove) ;
dOutLeakDist = max( dCurVertDist, dOutLeakDist) ;
dOutLeakDist = max( dCurVertDist, dOutLeakDist) ;
// dal lato
Vector3d vtSeg = trTria.GetP( ( nV + 1) % 3) - trTria.GetP( nV) ;
double dSegLen = vtSeg.Len() ;
@@ -706,8 +690,8 @@ CAvTrConeTriangle( const Point3d& ptMinBase, const Vector3d& vtTrConeAx, double
return dLeakDist ;
}
// Movimento generico
else
return -1 ;
else
return 0. ;
}
//----------------------------------------------------------------------------
@@ -716,9 +700,9 @@ TrConePointLeakDistLongMot( const Point3d& ptMinBase, const Vector3d& vtTrConeAx
double dTrConeH, const Point3d& ptP, const Vector3d& vtMove)
{
double dPointAxisSqDist = GetPointLineSqDist( ptP, ptMinBase, vtTrConeAx) ;
if ( dPointAxisSqDist > dMaxBaseR * dMaxBaseR + 2 * dMaxBaseR * EPS_SMALL)
if ( dPointAxisSqDist > dMaxBaseR * dMaxBaseR || dPointAxisSqDist < dMinBaseR * dMinBaseR)
return 0. ;
else if ( dPointAxisSqDist > dMinBaseR * dMinBaseR + 2 * dMinBaseR * EPS_SMALL) {
else {
double dMinBaseLeakDist = PointPlaneSignedDist( ptP, ptMinBase, vtMove) ;
double dMaxBaseLeakDist = PointPlaneSignedDist( ptP, ptMinBase + dTrConeH * vtTrConeAx, vtMove) ;
if ( dMinBaseLeakDist < - EPS_SMALL && dMaxBaseLeakDist < - EPS_SMALL)
@@ -735,11 +719,7 @@ TrConePointLeakDistLongMot( const Point3d& ptMinBase, const Vector3d& vtTrConeAx
else
return max( PointPlaneSignedDist( ptP, ptMinBase + dTrConeH * vtTrConeAx, vtMove), 0.) ;
}
else {
double dMinBaseLeakDist = PointPlaneSignedDist( ptP, ptMinBase, vtMove) ;
double dMaxBaseLeakDist = PointPlaneSignedDist( ptP, ptMinBase + dTrConeH * vtTrConeAx, vtMove) ;
return max( max( dMinBaseLeakDist, dMaxBaseLeakDist), 0.) ;
}
}
//----------------------------------------------------------------------------
@@ -869,6 +849,11 @@ TrConeSegmentLeakDistOrtMot( const Point3d& ptMinBase, const Vector3d& vtTrConeA
{
double dTopTol = bTop ? EPS_SMALL : - EPS_SMALL ;
double dBotTol = bBot ? - EPS_SMALL : EPS_SMALL ;
double dStH = ( ptSeg - ptMinBase) * vtTrConeAx ;
double dEnH = ( ptSeg + dSegLen * vtSeg - ptMinBase) * vtTrConeAx ;
if ( ( dStH < dBotTol && dEnH < dBotTol) ||
( dStH > dTrConeH + dTopTol && dEnH > dTrConeH + dTopTol))
return 0. ;
// Distanza di allontanamento delle basi
Point3d ptMaxBase = ptMinBase + dTrConeH * vtTrConeAx ;
double dMinBaseLeakDist = DiskSegmentLeakDistOrtMot( ptMinBase, vtTrConeAx, dMinBaseR, ptSeg, vtSeg, dSegLen, vtMove) ;
@@ -1047,6 +1032,21 @@ CAvTorusTriangle( const Point3d& ptTorusCen, const Vector3d& vtTorusAx, double d
return -1 ;
}
//----------------------------------------------------------------------------
double
EvalLeakDist( const Point3d& ptTorusCen, double dMaxRad, double dMinRad,
const Point3d& ptSeg, const Vector3d& vtSeg, double dPar, const Vector3d& vtMove)
{
double dSqMinRad = dMinRad * dMinRad ;
Point3d ptCurPoint = ptSeg + dPar * vtSeg ;
double dPointAxSqLen = GetPointLineSqDist( ptCurPoint, ptTorusCen, vtMove) ;
double dDeltaRad = sqrt( dPointAxSqLen) - dMaxRad ;
double dSQAddLeakDist = dSqMinRad - dDeltaRad * dDeltaRad ;
double dAddLeakDist = ( dSQAddLeakDist > 0. ? sqrt( dSQAddLeakDist) : 0.) ;
double dLeakDist = ( ptCurPoint - ptTorusCen) * vtMove + dAddLeakDist ;
return dLeakDist ;
}
//----------------------------------------------------------------------------
double
TorusSegmentLeakDistLongMot( const Point3d& ptTorusCen, double dMaxRad, double dMinRad,
@@ -1071,6 +1071,8 @@ TorusSegmentLeakDistLongMot( const Point3d& ptTorusCen, double dMaxRad, double d
dOutLen1, dOutLen2) ;
if ( nOutInters == CC_TWO_INT || nOutInters == CC_ONE_INT_TAN)
SegLimits.Intersect( dOutLen1, dOutLen2) ;
else if ( nOutInters == CC_NO_INTERS)
SegLimits.Reset() ;
if ( SegLimits.IsEmpty())
return 0. ;
// Tolgo eventuale cilindro interno alla corona del toro
@@ -1083,32 +1085,39 @@ TorusSegmentLeakDistLongMot( const Point3d& ptTorusCen, double dMaxRad, double d
}
// Eseguo controllo sugli intervalli
double dSqMinRad = dMinRad * dMinRad ;
double dSqMaxRad = dMaxRad * dMaxRad ;
double dSqTotRad = ( dMaxRad + dMinRad) * ( dMaxRad + dMinRad) ;
double dMaxLeakDist = 0.0 ;
double dMaxLeakDist = 0. ;
double dLen1, dLen2 ;
bool bFound = SegLimits.GetFirst( dLen1, dLen2) ;
while ( bFound) {
// verifico l'intervallo
Point3d ptStart = ptSeg + vtSeg * dLen1 ;
double dLen = dLen2 - dLen1 ;
double dStep = max( 0.1 * dMinRad, EPS_SMALL) ; // !!! USARE ALGORITMO GOLDEN SECTION !!!
int nStepNum = int( dLen / dStep) + 1 ;
dStep = dLen / nStepNum ;
for ( int n = 0 ; n <= nStepNum ; ++ n) {
double dPar = n * dStep ;
Point3d ptCurPoint = ptStart + dPar * vtSeg ;
double dPointAxSqLen = GetPointLineSqDist( ptCurPoint, ptTorusCen, vtMove) ;
if ( dPointAxSqLen > dSqMaxRad && dPointAxSqLen < dSqTotRad) {
double dDeltaRad = sqrt( dPointAxSqLen) - dMaxRad ;
double dSQAddLeakDist = dSqMinRad - dDeltaRad * dDeltaRad ;
double dAddLeakDist = ( dSQAddLeakDist > 0. ? sqrt( dSQAddLeakDist) : 0.) ;
double dLeakDist = ( ptCurPoint - ptTorusCen) * vtMove + dAddLeakDist ;
if ( dLeakDist > dMaxLeakDist)
dMaxLeakDist = dLeakDist ;
double dLen = dLen2 - dLen1 ;
const double INV_GOLDEN_RATIO = ( sqrt( 5.) - 1.) / 2. ;
double dTol = max( 0.05 * dMinRad, EPS_SMALL) ;
double dPSt = 0 ;
double dPEn = dLen ;
double dPIn1 = dPEn - ( dPEn - dPSt) * INV_GOLDEN_RATIO ;
double dPIn2 = dPSt + ( dPEn - dPSt) * INV_GOLDEN_RATIO ;
double dLeakDist1 = EvalLeakDist( ptTorusCen, dMaxRad, dMinRad, ptStart, vtSeg, dPIn1, vtMove) ;
double dLeakDist2 = EvalLeakDist( ptTorusCen, dMaxRad, dMinRad, ptStart, vtSeg, dPIn2, vtMove) ;
while ( dPEn - dPSt > dTol) {
if ( dLeakDist1 > dLeakDist2) {
dPEn = dPIn2 ;
dPIn2 = dPIn1 ;
dLeakDist2 = dLeakDist1 ;
dPIn1 = dPEn - ( dPEn - dPSt) * INV_GOLDEN_RATIO ;
dLeakDist1 = EvalLeakDist( ptTorusCen, dMaxRad, dMinRad, ptStart, vtSeg, dPIn1, vtMove) ;
}
else {
dPSt = dPIn1 ;
dPIn1 = dPIn2 ;
dLeakDist1 = dLeakDist2 ;
dPIn2 = dPSt + ( dPEn - dPSt) * INV_GOLDEN_RATIO ;
dLeakDist2 = EvalLeakDist( ptTorusCen, dMaxRad, dMinRad, ptStart, vtSeg, dPIn2, vtMove) ;
}
}
double dPMax = 0.5 * ( dPSt + dPEn) ;
dMaxLeakDist = max( dMaxLeakDist, EvalLeakDist( ptTorusCen, dMaxRad, dMinRad, ptStart, vtSeg, dPMax, vtMove)) ;
// passo al successivo intervallo
bFound = SegLimits.GetNext( dLen1, dLen2) ;
}
@@ -1228,7 +1237,7 @@ TorusSegmentLeakDistOrtMot( const Point3d& ptTorusCen, const Vector3d& vtTorusAx
double dMaxLeakDist = 0. ;
if ( bInsideLateral && bInsideOrizontal) {
double dSqMinRad = dMinRad * dMinRad ;
double dStep = max( 0.1 * dMinRad, EPS_SMALL) ;
double dStep = max( /*0.1*/0.05 * dMinRad, EPS_SMALL) ;
int nStepNum = int( dMySegLen / dStep) ;
for ( int n = 0 ; n <= nStepNum ; ++ n) {
Point3d ptCurPoint = ptMySeg + ( n * dStep) * vtSeg ;
@@ -1245,7 +1254,7 @@ TorusSegmentLeakDistOrtMot( const Point3d& ptTorusCen, const Vector3d& vtTorusAx
double dCurDist = dL + sqrt( dSqDeltaL) ;
if ( dCurDist > dMaxLeakDist)
dMaxLeakDist = dCurDist ;
}
}
}
}
return dMaxLeakDist ;
@@ -1332,6 +1341,23 @@ CAvConcaveTorusTriangle( const Point3d& ptTorusCen, const Vector3d& vtTorusAx, d
return 0. ;
}
//----------------------------------------------------------------------------
double
ConcaveEvalLeakDist( const Point3d& ptTorusCen, double dMaxRad, double dMinRad,
const Point3d& ptSeg, const Vector3d& vtSeg, double dPar, const Vector3d& vtMove)
{
double dSqMinRad = dMinRad * dMinRad ;
double dSqMaxRad = dMaxRad * dMaxRad ;
double dSqInnRad = ( dMaxRad - dMinRad) * ( dMaxRad - dMinRad) ;
Point3d ptCurPoint = ptSeg + dPar * vtSeg ;
double dPointAxSqLen = Clamp( GetPointLineSqDist( ptCurPoint, ptTorusCen, vtMove), dSqInnRad, dSqMaxRad) ;
double dDeltaRad = dMaxRad - sqrt( dPointAxSqLen) ;
double dSqDeltaLeakDist = dSqMinRad - dDeltaRad * dDeltaRad ;
double dDeltaLeakDist = ( dSqDeltaLeakDist > 0. ? sqrt( dSqDeltaLeakDist) : 0.) ;
double dLeakDist = ( ptCurPoint - ptTorusCen) * vtMove - dDeltaLeakDist ;
return dLeakDist ;
}
//----------------------------------------------------------------------------
double
ConcaveTorusSegmentLeakDistLongMot( const Point3d& ptTorusCen, double dMaxRad, double dMinRad,
@@ -1357,6 +1383,8 @@ ConcaveTorusSegmentLeakDistLongMot( const Point3d& ptTorusCen, double dMaxRad, d
dOutLen1, dOutLen2) ;
if ( nOutInters == CC_TWO_INT || nOutInters == CC_ONE_INT_TAN)
SegLimits.Intersect( dOutLen1, dOutLen2) ;
else if ( nOutInters == CC_NO_INTERS)
SegLimits.Reset() ;
if ( SegLimits.IsEmpty())
return 0. ;
// Tolgo eventuale cilindro interno alla corona del toro
@@ -1368,33 +1396,29 @@ ConcaveTorusSegmentLeakDistLongMot( const Point3d& ptTorusCen, double dMaxRad, d
SegLimits.Subtract( dIntLen1, dIntLen2) ;
}
// Eseguo controllo sugli intervalli
double dSqMinRad = dMinRad * dMinRad ;
double dSqMaxRad = dMaxRad * dMaxRad ;
double dSqInnRad = ( dMaxRad - dMinRad) * ( dMaxRad - dMinRad) ;
double dMaxLeakDist = 0.0 ;
double dLen1, dLen2 ;
bool bFound = SegLimits.GetFirst( dLen1, dLen2) ;
while ( bFound) {
// verifico l'intervallo
Point3d ptStart = ptSeg + vtSeg * dLen1 ;
double dLen = dLen2 - dLen1 ;
double dStep = max( 0.1 * dMinRad, EPS_SMALL) ; // !!! USARE ALGORITMO GOLDEN SECTION !!!
int nStepNum = int( dLen / dStep) + 1 ;
dStep = dLen / nStepNum ;
for ( int n = 0 ; n <= nStepNum ; ++ n) {
double dPar = n * dStep ;
Point3d ptCurPoint = ptStart + dPar * vtSeg ;
double dPointAxSqLen = GetPointLineSqDist( ptCurPoint, ptTorusCen, vtMove) ;
if ( dPointAxSqLen > dSqInnRad && dPointAxSqLen < dSqMaxRad) {
double dDeltaRad = dMaxRad - sqrt( dPointAxSqLen) ;
double dSqDeltaLeakDist = dSqMinRad - dDeltaRad * dDeltaRad ;
double dDeltaLeakDist = ( dSqDeltaLeakDist > 0. ? sqrt( dSqDeltaLeakDist) : 0.) ;
double dLeakDist = ( ptCurPoint - ptTorusCen) * vtMove - dDeltaLeakDist ;
if ( dLeakDist > dMaxLeakDist)
dMaxLeakDist = dLeakDist ;
}
double dLen = dLen2 - dLen1 ;
const double GOLDEN_RATIO = ( sqrt( 5) - 1) * 0.5 ;
double dTol = max( /*0.1*/0.05 * dMinRad, EPS_SMALL) ;
double dPSt = 0 ;
double dPEn = dLen ;
while ( dPEn - dPSt > dTol) {
double dPIn1 = dPEn - ( dPEn - dPSt) * GOLDEN_RATIO ;
double dPIn2 = dPSt + ( dPEn - dPSt) * GOLDEN_RATIO ;
double dLeakDist1 = ConcaveEvalLeakDist( ptTorusCen, dMaxRad, dMinRad, ptStart, vtSeg, dPIn1, vtMove) ;
double dLeakDist2 = ConcaveEvalLeakDist( ptTorusCen, dMaxRad, dMinRad, ptStart, vtSeg, dPIn2, vtMove) ;
if ( dLeakDist1 > dLeakDist2)
dPEn = dPIn2 ;
else
dPSt = dPIn1 ;
}
double dMaxPar = 0.5 * ( dPSt + dPEn) ;
dMaxLeakDist = max( dMaxLeakDist, ConcaveEvalLeakDist( ptTorusCen, dMaxRad, dMinRad, ptStart, vtSeg, dMaxPar, vtMove)) ;
// passo al successivo intervallo
bFound = SegLimits.GetNext( dLen1, dLen2) ;
}
@@ -1498,7 +1522,7 @@ ConcaveTorusSegmentLeakDistOrtMot( const Point3d& ptTorusCen, const Vector3d& vt
double dMaxLeakDist = 0. ;
if ( bInsideLateral && bInsideOrizontal) {
double dSqMinRad = dMinRad * dMinRad ;
double dStep = max( 0.1 * dMinRad, EPS_SMALL) ;
double dStep = max( /*0.1*/0.05 * dMinRad, EPS_SMALL) ;
int nStepNum = int( dMySegLen / dStep) ;
for ( int n = 0 ; n <= nStepNum ; ++ n) {
Point3d ptCurPoint = ptMySeg + ( n * dStep) * vtSeg ;
@@ -1549,24 +1573,94 @@ ConcaveTorusTriangleInteriorLeakDistOrtMot( const Point3d& ptTorusCen, const Vec
// DISTANZA DI ALLONTANAMENTO PER DISCHI
//----------------------------------------------------------------------------
double
CAvDiskTriangle( const Point3d& ptDiskCen, const Vector3d& vtDiskAx, double dDiskRad,
const Triangle3d& trTria, const Vector3d& vtMove)
{
// Direzione di allontanamento diretta come normale al disco
if ( AreSameVectorApprox( vtDiskAx, vtMove)) {
// Valuto le distanze con segno dei vertici dal piano del disco :
// se sono tutte negative non interferiscono.
double dDistV[3] ;
dDistV[0] = PointPlaneSignedDist( trTria.GetP( 0), ptDiskCen, vtMove) ;
dDistV[1] = PointPlaneSignedDist( trTria.GetP( 1), ptDiskCen, vtMove) ;
dDistV[2] = PointPlaneSignedDist( trTria.GetP( 2), ptDiskCen, vtMove) ;
double dMaxDistV = max( dDistV[0], max( dDistV[1], dDistV[2])) ;
if ( dMaxDistV < 0.)
return 0. ;
// Se tutti i punti distano dall'asse di movimento meno del raggio, l'ultimo
// punto di contatto deve essere un vertice del triangolo.
double dSqRad = dDiskRad * dDiskRad ;
bool bInV[3] ;
bInV[0] = ( GetPointLineSqDist( trTria.GetP( 0), ptDiskCen, vtMove) < dSqRad) ;
bInV[1] = ( GetPointLineSqDist( trTria.GetP( 1), ptDiskCen, vtMove) < dSqRad) ;
bInV[2] = ( GetPointLineSqDist( trTria.GetP( 2), ptDiskCen, vtMove) < dSqRad) ;
if ( bInV[0] && bInV[1] && bInV[2])
return max( dMaxDistV, 0.) ;
// Distanza di allontanamento dall'interno del triangolo
double dMaxDistI = DiskTriaInteriorLeakDistLongMot( ptDiskCen, dDiskRad, trTria, vtMove) ;
if ( dMaxDistI > EPS_SMALL)
return dMaxDistI ;
// Se disco è un punto, inutile fare controlli con i lati e i vertici del triangolo
if ( dDiskRad < EPS_SMALL)
return 0. ;
// Ciclo sui segmenti del triangolo e calcolo la loro distanza di allontanamento, calcolo
// anche la distanza di allontanamento dai vertici distanti dall'asse meno del raggio.
double dMaxDistVS = 0. ;
for ( int nVS = 0 ; nVS < 3 ; ++ nVS) {
// Vertici
if ( bInV[nVS] && dDistV[nVS] > dMaxDistVS)
dMaxDistVS = dDistV[nVS] ;
// Se un lato del triangolo ha entrambi gli estremi con distanza negativa dal piano del disco,
// non può interferire con esso.
int nVE = ( nVS + 1) % 3 ;
if ( dDistV[nVS] < 0 && dDistV[nVE] < 0)
continue ;
// Versore e lunghezza del segmento
Vector3d vtSeg = trTria.GetP( nVE) - trTria.GetP( nVS) ;
double dSegLen = vtSeg.Len() ;
vtSeg /= dSegLen ;
// Distanza dal piano del segmento corrente
double dCurDist = DiskSegmentLeakDistLongMot( ptDiskCen, dDiskRad, trTria.GetP( nVS), vtSeg, dSegLen, vtMove) ;
if ( dCurDist > dMaxDistVS)
dMaxDistVS = dCurDist ;
}
return dMaxDistVS ;
}
// Direzione di allontanamento perpendicolare all'asse del disco
else if ( AreOrthoApprox( vtDiskAx, vtMove)) {
return 0. ;
}
// Direzione di allontanamento generica
else if ( vtDiskAx * vtMove > 0.) {
// Non trattato al momento
return - 1. ;
}
// Errore
else
return -1. ;
}
//----------------------------------------------------------------------------
double
DiskPointLeakDistLongMot( const Point3d& ptDiskCen, double dDiskRad,
const Point3d& ptP, const Vector3d& vtMove)
{
if ( GetPointLineSqDist( ptP, ptDiskCen, vtMove) < dDiskRad * dDiskRad)
if ( GetPointLineSqDist( ptP, ptDiskCen, vtMove) < dDiskRad * dDiskRad - 2 * dDiskRad * EPS_SMALL)
return PointPlaneSignedDist( ptP, ptDiskCen, vtMove) ;
return 0. ;
}
//----------------------------------------------------------------------------
double
double
DiskSegmentLeakDistLongMot( const Point3d& ptDiskCen, double dDiskRad,
const Point3d& ptSeg, const Vector3d& vtSeg, double dSegLen, const Vector3d& vtMove)
const Point3d& ptSeg, const Vector3d& vtSeg, double dSegLen,
const Vector3d& vtMove)
{
// Il disco non può interferire col segmento nel suo moto, se la distanza del
// segmento dall'asse di traslazione è maggiore del raggio.
if ( LineSegmentSqDist( ptDiskCen, vtMove, ptSeg, vtSeg, dSegLen) > dDiskRad * dDiskRad)
// segmento dall'asse di traslazione è maggiore del raggio.
if ( LineSegmentSqDist( ptDiskCen, vtMove, ptSeg, vtSeg, dSegLen) > dDiskRad * dDiskRad - 2 * dDiskRad * EPS_SMALL)
return 0. ;
// Imposto l'equazione: la distanza quadrata del generico punto della retta associata al
@@ -1579,92 +1673,65 @@ DiskSegmentLeakDistLongMot( const Point3d& ptDiskCen, double dDiskRad,
vdCoef[1] = 2 * vtLineSegOrt * vtSegOrt ;
vdCoef[2] = vtSegOrt.SqLen() ;
// Segmento e asse paralleli
if ( vdCoef[2] < SQ_EPS_ZERO) {
if ( abs( vdCoef[0]) < 2 * dDiskRad * EPS_SMALL) {
double dLenSt = PointPlaneSignedDist( ptSeg, ptDiskCen, vtMove) ;
double dLenEn = PointPlaneSignedDist( ptSeg + dSegLen * vtSeg, ptDiskCen, vtMove) ;
return max( max( dLenSt, dLenEn), 0.) ;
}
else
return 0. ;
}
if ( vdCoef[2] < SQ_EPS_ZERO)
return 0. ;
// Soluzione dell'equazione
else {
int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ;
// Ciclo sulle soluzioni per trovare la distanza di allontanamento
double dSegDist = 0. ;
for ( int nSol = 0 ; nSol < nRoot ; ++ nSol) {
// Soluzione interna al segmento
if ( vdRoots[nSol] > 0. && vdRoots[nSol] < dSegLen) {
Point3d ptC = ptSeg + vdRoots[nSol] * vtSeg ;
// Distanza del punto soluzione dal piano del disco nella posizione iniziale
double dCurDist = PointPlaneSignedDist( ptC, ptDiskCen, vtMove) ;
if ( dCurDist > dSegDist)
dSegDist = dCurDist ;
}
int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ;
// Ciclo sulle soluzioni per trovare la distanza di allontanamento
double dSegDist = 0. ;
for ( int nSol = 0 ; nSol < nRoot ; ++ nSol) {
// Soluzione interna al segmento
if ( vdRoots[nSol] > 0. && vdRoots[nSol] < dSegLen) {
Point3d ptC = ptSeg + vdRoots[nSol] * vtSeg ;
// Distanza del punto soluzione dal piano del disco nella posizione iniziale
double dCurDist = PointPlaneSignedDist( ptC, ptDiskCen, vtMove) ;
if ( dCurDist > dSegDist)
dSegDist = dCurDist ;
}
return dSegDist ;
}
return dSegDist ;
}
//----------------------------------------------------------------------------
// Determina la distanza di allontanamento di un disco, che trasla lungo il suo asse di simmetria,
// dall'interno di un triangolo. Il disco è descritto dal suo raggio e il moto dal
// centro nella posizione iniziale e dal versore del suo asse di simmetria
// (COINCIDENTE CON IL VERSORE DELLA DIREZIONE DI ALLONTANAMENTO).
double
//----------------------------------------------------------------------------
double
DiskTriaInteriorLeakDistLongMot( const Point3d& ptDiskCen, double dDiskRad,
const Triangle3d& trTria, const Vector3d& vtMove)
const Triangle3d& trTria, const Vector3d& vtMove)
{
// Se disco e triangolo sono complanari
if ( AreSameVectorApprox( vtMove, trTria.GetN())) {
// verifico solo il centro, se centro esterno non più del raggio sicuramente toccherebbe i lati
double dDist = PointPlaneSignedDist( ptDiskCen, trTria.GetP( 0), trTria.GetN()) ;
if ( IsPointInsideTriangle( ptDiskCen - dDist * trTria.GetN(), trTria))
return max( -dDist, 0.) ;
double dDist = max( PointPlaneSignedDist( ptDiskCen, trTria.GetP( 0), trTria.GetN()), 0.) ;
if ( CoplanarDiscTriangleInterferance( ptDiskCen + dDist * vtMove, dDiskRad, trTria))
return dDist ;
}
// Cerco un punto di contatto nell'interno del triangolo. Se tale punto
// esiste, la retta intersezione fra il piano del triangolo e quello del
// disco è tangente alla circonferenza.
// Vettore tangente alla circonferenza e vettore radiale
Vector3d vtRadLine = vtMove * ( trTria.GetN() * vtMove) - trTria.GetN() ;
vtRadLine.Normalize() ;
// Se disco e triangolo sono ortogonali non può esserci contatto con interno
if ( AreOrthoApprox( vtMove, trTria.GetN()))
return 0. ;
// Cerco un punto di contatto nell'interno del triangolo.
double dLeakDist = 0. ;
// Vettore radiale
Vector3d vtRad = trTria.GetN() - ( trTria.GetN() * vtMove) * vtMove ;
vtRad.Normalize() ;
// Punti delle due rette candidate all'intersezione col triangolo
Point3d ptStPlus = ptDiskCen + dDiskRad * vtRadLine ;
Point3d ptStMinus = ptDiskCen - dDiskRad * vtRadLine ;
// Intersezioni con la prima retta
double dDistPlus = 0. ;
Point3d ptIntPlus1, ptIntPlus2 ;
int nIntPlus = IntersLineTria( ptStPlus, vtMove, 10, trTria, ptIntPlus1, ptIntPlus2, false) ;
if ( nIntPlus != ILTT_NO) {
double dDist1 = PointPlaneSignedDist( ptIntPlus1, ptDiskCen, vtMove) ;
// Se l'intersezione è doppia, ha senso anche dDist2.
if ( nIntPlus == ILTT_SEGM ||
nIntPlus == ILTT_SEGM_ON_EDGE) {
double dDist2 = PointPlaneSignedDist( ptIntPlus2, ptDiskCen, vtMove) ;
dDistPlus = max( dDist1, dDist2) ;
}
// Altrimenti ha senso solo dDist1
else
dDistPlus = dDist1 ;
Point3d ptStPlus = ptDiskCen + dDiskRad * vtRad ;
Point3d ptStMinus = ptDiskCen - dDiskRad * vtRad ;
// Intersezioni con le rette
double dDistPlus = ( ( trTria.GetP( 0) - ptStPlus) * trTria.GetN()) / ( vtMove * trTria.GetN()) ;
double dDistMinus = ( ( trTria.GetP( 0) - ptStMinus) * trTria.GetN()) / ( vtMove * trTria.GetN()) ;
if ( dDistPlus > dDistMinus) {
if ( IsPointInsideTriangle( ptStPlus + dDistPlus * vtMove, trTria))
dLeakDist = max( dLeakDist, dDistPlus) ;
}
// Intersezioni con la seconda retta
double dDistMinus = 0. ;
Point3d ptIntMinus1, ptIntMinus2 ;
int nIntMinus = IntersLineTria( ptStMinus, vtMove, 10, trTria, ptIntMinus1, ptIntMinus2, false) ;
if ( nIntMinus != ILTT_NO) {
double dDist1 = PointPlaneSignedDist( ptIntMinus1, ptDiskCen, vtMove) ;
// Se l'intersezione è doppia, ha senso anche dDist2.
if ( nIntMinus == ILTT_SEGM ||
nIntMinus == ILTT_SEGM_ON_EDGE) {
double dDist2 = PointPlaneSignedDist( ptIntMinus2, ptDiskCen, vtMove) ;
dDistMinus = max( dDist1, dDist2) ;
}
// Altrimenti ha senso solo dDist1
else
dDistMinus = dDist1 ;
}
return max( dDistPlus, dDistMinus) ;
else if ( IsPointInsideTriangle( ptStMinus + dDistMinus * vtMove, trTria))
dLeakDist = max( dLeakDist, dDistMinus) ;
return dLeakDist ;
}
//----------------------------------------------------------------------------
@@ -1696,7 +1763,7 @@ DiskPlaneLeakDistLongMot( const Point3d& ptDiskCen, double dDiskRad,
else {
ptTouch = ptStMinus + dLeakMinus * vtMove ;
return dLeakMinus ;
}
}
}
//----------------------------------------------------------------------------
@@ -1758,11 +1825,6 @@ DiskSegmentLeakDistOrtMot( const Point3d& ptDiskCen, const Vector3d& vtDiskAx, d
}
//----------------------------------------------------------------------------
// Restituisce la distanza di allontanamento di un disco, che trasla ortogonalmente al suo asse
// di simmetria, da un piano.
// Il disco è descritto dal suo raggio. Il moto è descritto dal centro nella posizione
// iniziale, dal versore (NORMA UNITARIA) dell'asse di simmetria del disco e dal versore
// della direzione del moto.
double
DiskPlaneLeakDistOrtMot( const Point3d& ptDiscCen, const Vector3d& vtDiskAx, double dDiskRad,
const Point3d& ptPlane, const Vector3d& vtPlane,
@@ -1770,6 +1832,13 @@ DiskPlaneLeakDistOrtMot( const Point3d& ptDiscCen, const Vector3d& vtDiskAx, dou
{
Vector3d vtLine = vtPlane ^ vtDiskAx ;
if ( vtLine.Normalize()) {
// Se il raggio è minore di epsilon, lo consideriamo un punto
if ( dDiskRad < EPS_SMALL) {
// Denominatore sempre diverso da zero
double dDesplacement = ( ( ptPlane - ptDiscCen)) * vtPlane / ( vtMove * vtPlane) ;
ptContact = ptDiscCen + dDesplacement * vtMove ;
return dDesplacement ;
}
Vector3d vtRad = dDiskRad * vtLine ^ vtDiskAx ;
if ( vtRad * vtMove > 0)
vtRad *= - 1 ;
@@ -1777,7 +1846,7 @@ DiskPlaneLeakDistOrtMot( const Point3d& ptDiscCen, const Vector3d& vtDiskAx, dou
double dRadCos = abs( vtRad * vtMove) ;
// Se la retta intersezione fra i piani è parallela alla direzione di
// allontanamento la distanza di fuga è determinata da punti e segmenti.
if ( dRadCos < EPS_SMALL)
if ( dDiskRad && dRadCos < EPS_SMALL)
return 0. ;
double dDeltaPar = dDiskRad * dDiskRad / dRadCos ;
double dDesplacement = max( dPar + dDeltaPar, 0.) ;
@@ -1787,7 +1856,6 @@ DiskPlaneLeakDistOrtMot( const Point3d& ptDiscCen, const Vector3d& vtDiskAx, dou
return 0. ;
}
// FUNZIONI GEOMETRICHE DI BASE PER IL CALCOLO DELLA DISTANZA DI ALLONTANAMENTO
//----------------------------------------------------------------------------