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:
+301
-233
@@ -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
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user