diff --git a/CAvToolSurfTm.cpp b/CAvToolSurfTm.cpp index 9457671..da9b55a 100644 --- a/CAvToolSurfTm.cpp +++ b/CAvToolSurfTm.cpp @@ -164,14 +164,38 @@ CAvToolSurfTm::MyTestPosition( Point3d& ptT, const Vector3d& vtDir) double CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir) { - double dTotDist = 0 ; // calcolo box utensile nel riferimento di movimento BBox3d b3Tool ; - b3Tool.Add( ptT) ; - b3Tool.Add( ptT + vtDir * m_Tool.GetHeigth()) ; - b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ; - b3Tool.ToLoc( m_frMove) ; - // recupero indici triangoli che intersecano box in 2d + if ( AreSameOrOppositeVectorApprox( vtDir, m_frMove.VersX())) { + Point3d ptTL = ptT ; ptTL.ToLoc( m_frMove) ; + Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ; + b3Tool.Add( ptTL) ; + b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ; + b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ; + } + else if ( AreSameOrOppositeVectorApprox( vtDir, m_frMove.VersY())) { + Point3d ptTL = ptT ; ptTL.ToLoc( m_frMove) ; + Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ; + b3Tool.Add( ptTL) ; + b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ; + b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ; + } + else if ( AreSameOrOppositeVectorApprox( vtDir, m_frMove.VersZ())) { + Point3d ptTL = ptT ; ptTL.ToLoc( m_frMove) ; + Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ; + b3Tool.Add( ptTL) ; + b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ; + b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ; + } + else { + b3Tool.Add( ptT) ; + b3Tool.Add( ptT - vtDir * m_Tool.GetHeigth()) ; + b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ; + b3Tool.ToLoc( m_frMove) ; + } + b3Tool.Expand( 10 * EPS_SMALL) ; + // ciclo sui triangoli che intersecano box in 2d + double dTotDist = 0 ; INTVECTOR vnIds ; if ( m_HGrids.Find( b3Tool, vnIds)) { for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) { diff --git a/CAvToolTriangle.cpp b/CAvToolTriangle.cpp index b45c5e8..302b627 100644 --- a/CAvToolTriangle.cpp +++ b/CAvToolTriangle.cpp @@ -30,30 +30,65 @@ CAvToolTriangle( const Tool& tlTool, const Point3d& ptToolOrig, const Vector3d& const Triangle3d& trTria, const Vector3d& vtMove) { // se utensile cilindrico - if ( tlTool.GetType() == Tool::CYLMILL) { + if ( tlTool.GetType() == Tool::CYLMILL) { // parametri geometrici double dHeigth = tlTool.GetHeigth() ; - double dRadius = tlTool.GetRadius() ; - // distanza di allontanamento del cilindro - double dDist = CAvCylinderTriangle( ptToolOrig, vtToolAx, dHeigth, dRadius, trTria, vtMove) ; - return dDist ; + double dRadius = tlTool.GetRadius() ; + // distanza di allontanamento del cilindro + double dDist = CAvCylinderTriangle( ptToolOrig, vtToolAx, dHeigth, dRadius, trTria, vtMove) ; + return dDist ; } // se utensile sferico else if ( tlTool.GetType() == Tool::BALLMILL) { // parametri geometrici double dCylHeigth = tlTool.GetHeigth() - tlTool.GetTipHeigth() ; - double dRadius = tlTool.GetRadius() ; + double dRadius = tlTool.GetRadius() ; // prima determino l'allontanamento della sfera Point3d ptSpheOrig = ptToolOrig - dCylHeigth * vtToolAx ; double dDist = CAvSphereTriangle( ptSpheOrig, dRadius, trTria, vtMove) ; - // poi verifico quello del cilindro (tenendo conto di quanto è stata allontanata la sfera + if ( dDist < - EPS_SMALL) + return dDist ; + // 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.) ; double dDist2 = CAvCylinderTriangle( ptCylOrig, vtToolAx, dCylHeigth, dRadius, trTria, vtMove) ; - return ( max( dDist, 0.) + max( dDist2, 0.)) ; + if ( dDist2 < - EPS_SMALL) + return dDist2 ; + return ( dDist + dDist2) ; + } + // se utensile conico + else if ( tlTool.GetType() == Tool::CONEMILL) { + // parametri geometrici + Point3d ptMinBase ; + Vector3d vtConeAx ; + if ( tlTool.GetRadius() > tlTool.GetTipRadius()) { + ptMinBase = ptToolOrig - tlTool.GetHeigth() * vtToolAx ; + vtConeAx = vtToolAx ; + } + else { + ptMinBase = ptToolOrig - ( tlTool.GetHeigth() - tlTool.GetTipHeigth()) * vtToolAx ; + vtConeAx = - vtToolAx ; + } + 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) ; + 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) ; + if ( dDist2 < - EPS_SMALL) + return dDist2 ; + return ( dDist + dDist2) ; } // altrimenti utensile di tipo non gestito - else - return - 1. ; + else + return - 1. ; } //---------------------------------------------------------------------------- @@ -68,7 +103,7 @@ CAvSphereTriangle( const Point3d& ptSpheCen, double dSpheRad, const Triangle3d& Vector3d vtVert0 = ptSpheCen - trTria.GetP( 0) ; Vector3d vtVert1 = ptSpheCen - trTria.GetP( 1) ; Vector3d vtVert2 = ptSpheCen - trTria.GetP( 2) ; - if ( vtVert0 * vtMove > dSpheRad - EPS_SMALL && + if ( vtVert0 * vtMove > dSpheRad - EPS_SMALL && vtVert1 * vtMove > dSpheRad - EPS_SMALL && vtVert2 * vtMove > dSpheRad - EPS_SMALL) return 0. ; @@ -83,15 +118,15 @@ CAvSphereTriangle( const Point3d& ptSpheCen, double dSpheRad, const Triangle3d& return dPlaneLeakDist ; } - // Valuto le distanze di allontanamento dai segmenti (con i loro estremi) e prendo la maggiore + // Valuto le distanze di allontanamento dai segmenti (con i loro estremi) e prendo la maggiore double dLeakDist = 0. ; for ( int nSeg = 0 ; nSeg < 3 ; ++ nSeg) { Vector3d vtSeg = trTria.GetP( ( nSeg + 1) % 3) - trTria.GetP( nSeg) ; double dSegLen = vtSeg.Len() ; vtSeg /= dSegLen ; double dCurLeakDist = SphereSegmentLeakDist( ptSpheCen, dSpheRad, trTria.GetP( nSeg), vtSeg, dSegLen, vtMove) ; - if ( dCurLeakDist > dLeakDist) - dLeakDist = dCurLeakDist ; + if ( dCurLeakDist > dLeakDist) + dLeakDist = dCurLeakDist ; } return dLeakDist ; } @@ -105,11 +140,11 @@ SpherePlaneLeakDist( const Point3d& ptSpheCen, double dSpheRad, // Se la direzione di allontanamento sta nel piano if ( abs( vtPlaneN * vtMove) < EPS_SMALL) { if ( abs( ( ptSpheCen - ptPlane) * vtPlaneN) > dSpheRad) - return 0. ; + return 0. ; else return -1. ; } - // altrimenti ... + // altrimenti ... else { double dLeakDist = ( dSpheRad - ( ptSpheCen - ptPlane) * vtPlaneN) / ( vtMove * vtPlaneN) ; return max( dLeakDist, 0.) ; @@ -132,21 +167,21 @@ SphereSegmentLeakDist( const Point3d& ptSpheCen, double dSpheRad, if ( dU[nSol] < 0.) continue ; Point3d ptC = ptSpheCen + dU[nSol] * vtMove ; - double dSegPar = ( ptC - ptSeg) * vtSegDir ; + double dSegPar = ( ptC - ptSeg) * vtSegDir ; if ( dSegPar > 0 && dSegPar < dSegLen) - dLeakDistIn = dU[nSol] ; + dLeakDistIn = dU[nSol] ; } // Controllo con gli estremi Point3d ptSegEnd = ptSeg + dSegLen * vtSegDir ; double dDistStart = SpherePointLeakDist( ptSpheCen, dSpheRad, ptSeg, vtMove) ; double dDistEnd = SpherePointLeakDist( ptSpheCen, dSpheRad, ptSegEnd, vtMove) ; // Restituisco il massimo - return max( dLeakDistIn, max( dDistStart, dDistEnd)) ; + return max( dLeakDistIn, max( dDistStart, dDistEnd)) ; } //---------------------------------------------------------------------------- // Calcola la distanza di allontanamento lungo una direzione fissata di una sfera da un punto. -double +double SpherePointLeakDist( const Point3d& ptSpheCen, double dSpheRad, const Point3d ptP, const Vector3d& vtMove) { Vector3d vtOR = ptP - ptSpheCen ; @@ -156,8 +191,8 @@ SpherePointLeakDist( const Point3d& ptSpheCen, double dSpheRad, const Point3d pt double dSqSphRad = dSpheRad * dSpheRad ; if ( dSqOROrtLen > dSqSphRad + 2 * dSpheRad * EPS_SMALL) return 0. ; - else - return max( dDotORMot + sqrt( max( dSpheRad * dSpheRad - dSqOROrtLen, 0.)), 0.) ; + else + return max( dDotORMot + sqrt( max( dSpheRad * dSpheRad - dSqOROrtLen, 0.)), 0.) ; } //---------------------------------------------------------------------------- @@ -165,7 +200,7 @@ SpherePointLeakDist( const Point3d& ptSpheCen, double dSpheRad, const Point3d pt //---------------------------------------------------------------------------- // La funzione determina la minima distanza di allontanamento lungo una direzione fissata // per evitare la collisione tra un cilindro ed un triangolo. -double +double CAvCylinderTriangle( const Point3d& ptCylOrig, const Vector3d& vtCylAx, double dHeigth, double dRad, const Triangle3d& trTria, const Vector3d& vtMove) { @@ -173,22 +208,19 @@ CAvCylinderTriangle( const Point3d& ptCylOrig, const Vector3d& vtCylAx, double d int nMotionType = 0 ; if ( AreSameVectorApprox( vtCylAx, vtMove)) nMotionType = 1 ; - else if ( AreOppositeVectorApprox( vtCylAx, vtMove)) + else if ( AreOppositeVectorApprox( vtCylAx, vtMove)) nMotionType = 2 ; - else if ( AreOrthoApprox( vtCylAx, vtMove)) + else if ( AreOrthoApprox( vtCylAx, vtMove)) nMotionType = 3 ; - // Moto lungo la direzione dell'asse del cilindro + // 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 ; - // La sua normale vale - // Nel Caso 1 coincide con quella dell'utensile, nel caso 2 è opposta - // !!!!! DA FARE !!!!! + ptBase -= dHeigth * vtCylAx ; // Valuto le distanze con segno dei vertici dal piano del disco : // se sono tutte negative non interferiscono. double dDistV[3] ; @@ -197,137 +229,98 @@ CAvCylinderTriangle( const Point3d& ptCylOrig, const Vector3d& vtCylAx, double d dDistV[2] = PointPlaneSignedDist( trTria.GetP( 2), ptBase, vtCylAx) ; double dMaxDistV = max( dDistV[0], max( dDistV[1], dDistV[2])) ; if ( dMaxDistV < 0.) - return 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 ; + 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[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.) ; - // Ciclo sui segmenti del triangolo e calcolo la loro distanza di allontanamento, calcolo + // 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. ; + double dMaxDistVS = 0. ; for ( int nVS = 0 ; nVS < 3 ; ++ nVS) { // Vertici if ( bInV[nVS] && dDistV[nVS] > dMaxDistVS) - dMaxDistVS = dDistV[nVS] ; + dMaxDistVS = dDistV[nVS] ; // Se un lato del triangolo ha entrambi gli estremi con distanza negativa dal piano del disco, - // non può interferire con esso. + // non può interferire con esso. int nVE = ( nVS + 1) % 3 ; if ( dDistV[nVS] < 0 && dDistV[nVE] < 0) continue ; - // Versore e lunghezza del segmento + // 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 = DiskSegmentLeakDistLongMotion( ptBase, vtCylAx, dRad, trTria.GetP( nVS), vtSeg, dSegLen) ; + double dCurDist = DiskSegmentLeakDistLongMotion( ptBase, dRad, trTria.GetP( nVS), vtSeg, dSegLen, vtMove) ; if ( dCurDist > dMaxDistVS) dMaxDistVS = dCurDist ; } // Distanza di allontanamento dall'interno del triangolo - double dMaxDistI = DiskTriaInteriorLeakDistLongMot( ptBase, vtCylAx, dRad, trTria) ; + double dMaxDistI = DiskTriaInteriorLeakDistLongMot( ptBase, dRad, trTria, vtMove) ; return max( dMaxDistVS, dMaxDistI) ; } - // Moto perpendicolare all'asse del cilindro + // Movimento perpendicolare all'asse del cilindro else if ( nMotionType == 3) { // PROVE PUNTI E SEGMENTI - double dLeakDist = - DBL_MAX ; - for ( int nVrt = 0 ; nVrt < 3 ; ++ nVrt) { - double dCurDist = CylPointLeakDistOrtMotion( trTria.GetP( nVrt), ptCylOrig, vtCylAx, vtMove, dHeigth, dRad) ; + double dLeakDist = 0. ; + for ( int nVrt = 0 ; nVrt < 3 ; ++ nVrt) { + double dCurDist = CylPointLeakDistOrtMotion( ptCylOrig, vtCylAx, dHeigth, dRad, trTria.GetP( nVrt), vtMove) ; if ( dLeakDist < dCurDist) dLeakDist = dCurDist ; } // FINE PROVE PUNTI // INIZIO PROVA SEGMENTI - for ( int nVrtS = 0 ; nVrtS < 3 ; ++ nVrtS) { + for ( int nVrtS = 0 ; nVrtS < 3 ; ++ nVrtS) { int nVrtE = ( nVrtS + 1) % 3 ; - Vector3d vtSeg = trTria.GetP( nVrtE) - trTria.GetP( nVrtS) ; + Vector3d vtSeg = trTria.GetP( nVrtE) - trTria.GetP( nVrtS) ; double dSegLen = vtSeg.Len() ; vtSeg /= dSegLen ; - double dCurDist = CylSegmentLeakDistOrtMotion( trTria.GetP( nVrtS), ptCylOrig, vtSeg, - vtCylAx, vtMove, dSegLen, dHeigth, dRad) ; + double dCurDist = CylSegmentLeakDistOrtMotion( ptCylOrig, vtCylAx, dHeigth, dRad, + trTria.GetP( nVrtS), vtSeg, dSegLen, vtMove) ; if ( dLeakDist < dCurDist) dLeakDist = dCurDist ; } // FINE PROVA SEGMENTI // PROVA INTERNO Point3d ptBaseCont, ptBottomCont ; - double dBaseLeak = DiskPlaneLeakDistOrtMot( trTria, ptCylOrig, vtCylAx, vtMove, dRad, ptBaseCont) ; - double dBottomLeak = DiskPlaneLeakDistOrtMot( trTria, ptCylOrig - dHeigth * vtCylAx, vtCylAx, vtMove, dRad, ptBottomCont) ; + double dBaseLeak = DiskPlaneLeakDistOrtMot( ptCylOrig, vtCylAx, dRad, trTria.GetP( 0), trTria.GetN(), + vtMove, ptBaseCont) ; + double dBottomLeak = DiskPlaneLeakDistOrtMot( ptCylOrig - dHeigth * vtCylAx, vtCylAx, dRad, + trTria.GetP( 0), trTria.GetN(), vtMove, ptBottomCont) ; if ( ! IsPointInsideTriangle( ptBaseCont, trTria)) dBaseLeak = 0. ; if ( ! IsPointInsideTriangle( ptBottomCont, trTria)) dBottomLeak = 0. ; - double dInnerLeak = max( dBaseLeak , dBottomLeak) ; + double dInnerLeak = max( dBaseLeak, dBottomLeak) ; if ( dLeakDist < dInnerLeak) - dLeakDist = dInnerLeak ; + dLeakDist = dInnerLeak ; // FINE PROVA INTERNO return dLeakDist ; } - // Moto generico - else + // Movimento generico + else return -1. ; } //---------------------------------------------------------------------------- -// Determina la distanza di fuga di un disco, che trasla lungo il suo asse di simmetria, da -// un segmento. Il disco è descritto dal quadrato del suo raggio, il moto dal centro nella -// posizione di partenza e il versore di traslazione. Il segmento è -// descritto da un punto suo estremo, dal versore direzione diretto verso -// l'altro estremo e dalla sua lunghezza. -//double -//DiskSegmentLeakDistLongMotion( const Point3d& ptDisc, const Point3d& ptSeg, -// const Vector3d& vtDiscLeak, const Vector3d& vtSeg, -// double dSegLen, double dDiscSqRad) -//{ -// // Il disco non può interferire col segmento nel suo moto, se la distanza del -// // segmento dall'asse di traslazione è maggiore del raggio. -// if ( LineSegmentSqDist( ptDisc, ptSeg, vtDiscLeak, vtSeg, dSegLen) > dDiscSqRad) -// return 0. ; -// -// // Imposto l'equazione: la distanza quadrata del generico punto della retta associata al -// // segmento dall'asse lungo cui si sposta il disco deve valere raggio quadrato del disco. -// Vector3d vtLineSegOrt = ( ptSeg - ptDisc) - ( ptSeg - ptDisc) * vtDiscLeak * vtDiscLeak ; -// Vector3d vtSegOrt = vtSeg - vtSeg * vtDiscLeak * vtDiscLeak ; -// DBLVECTOR vdCoef( 3) ; -// DBLVECTOR vdRoots ; -// vdCoef[0] = vtLineSegOrt.SqLen() - dDiscSqRad ; -// vdCoef[1] = 2 * vtLineSegOrt * vtSegOrt ; -// vdCoef[2] = vtSegOrt.SqLen() ; -// // Soluzione dell'equazione -// int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; -// // Ciclo sulle soluzioni per trovare la distanza di allontanamento -// double dSegDist = - DBL_MAX ; -// 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, ptDisc, vtDiscLeak) ; -// if ( dSegDist < dCurDist) -// dSegDist = dCurDist ; -// } -// } -// return dSegDist ; -//} -///// ALTRA VERSIONE SPERIMENTALE DELLA PRECEDNTE double -DiskSegmentLeakDistLongMotion( const Point3d& ptDisc, const Vector3d& vtDiscLeak, double dDiscRad, - const Point3d& ptSeg, const Vector3d& vtSeg, double dSegLen) +DiskSegmentLeakDistLongMotion( const Point3d& ptDiskCen, double dDiscRad, + 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( ptDisc, vtDiscLeak, ptSeg, vtSeg, dSegLen) > dDiscRad * dDiscRad) + if ( LineSegmentSqDist( ptDiskCen, vtMove, ptSeg, vtSeg, dSegLen) > dDiscRad * dDiscRad) return 0. ; // Imposto l'equazione: la distanza quadrata del generico punto della retta associata al // segmento dall'asse lungo cui si sposta il disco deve valere raggio quadrato del disco. - Vector3d vtLineSegOrt = ( ptSeg - ptDisc) - ( ptSeg - ptDisc) * vtDiscLeak * vtDiscLeak ; - Vector3d vtSegOrt = vtSeg - vtSeg * vtDiscLeak * vtDiscLeak ; + Vector3d vtLineSegOrt = ( ptSeg - ptDiskCen) - ( ptSeg - ptDiskCen) * vtMove * vtMove ; + Vector3d vtSegOrt = vtSeg - vtSeg * vtMove * vtMove ; DBLVECTOR vdCoef(3) ; DBLVECTOR vdRoots ; vdCoef[0] = vtLineSegOrt.SqLen() - dDiscRad * dDiscRad ; @@ -336,167 +329,179 @@ DiskSegmentLeakDistLongMotion( const Point3d& ptDisc, const Vector3d& vtDiscLeak // Segmento e asse paralleli if ( vdCoef[2] < SQ_EPS_ZERO) { if ( abs( vdCoef[0]) < 2 * dDiscRad * EPS_SMALL) { - double dLenSt = PointPlaneSignedDist( ptSeg, ptDisc, vtDiscLeak) ; - double dLenEn = PointPlaneSignedDist( ptSeg + dSegLen * vtSeg, ptDisc, vtDiscLeak) ; + double dLenSt = PointPlaneSignedDist( ptSeg, ptDiskCen, vtMove) ; + double dLenEn = PointPlaneSignedDist( ptSeg + dSegLen * vtSeg, ptDiskCen, vtMove) ; return max( max( dLenSt, dLenEn), 0.) ; } - else + else return 0. ; } - // Soluzione dell'equazione + // 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) { + 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, ptDisc, vtDiscLeak) ; + double dCurDist = PointPlaneSignedDist( ptC, ptDiskCen, vtMove) ; if ( dCurDist > dSegDist) - dSegDist = dCurDist ; + dSegDist = dCurDist ; } } 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 +// 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 -DiskTriaInteriorLeakDistLongMot( const Point3d& ptDisk, const Vector3d& vtDiskAx, double dDiskRad, - const Triangle3d& trTria) +DiskTriaInteriorLeakDistLongMot( const Point3d& ptDiskCen, double dDiskRad, + const Triangle3d& trTria, const Vector3d& vtMove) { // Se disco e triangolo sono complanari - if ( AreSameVectorApprox( vtDiskAx, trTria.GetN())) { + if ( AreSameVectorApprox( vtMove, trTria.GetN())) { // verifico solo il centro, se centro esterno non più del raggio sicuramente toccherebbe i lati - double dDist = PointPlaneSignedDist( ptDisk, trTria.GetP( 0), trTria.GetN()) ; - if ( IsPointInsideTriangle( ptDisk - dDist * trTria.GetN(), trTria)) + double dDist = PointPlaneSignedDist( ptDiskCen, trTria.GetP( 0), trTria.GetN()) ; + if ( IsPointInsideTriangle( ptDiskCen - dDist * trTria.GetN(), trTria)) return max( -dDist, 0.) ; } - // Cerco un punto di contatto nell'interno del triangolo. Se tale punto - // esiste, la retta intersezione fra il piano del triangolo e quello del + // 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 = vtDiskAx * ( trTria.GetN() * vtDiskAx) - trTria.GetN() ; - vtRadLine.Normalize() ; + Vector3d vtRadLine = vtMove * ( trTria.GetN() * vtMove) - trTria.GetN() ; + vtRadLine.Normalize() ; // Punti delle due rette candidate all'intersezione col triangolo - Point3d ptStPlus = ptDisk + dDiskRad * vtRadLine ; - Point3d ptStMinus = ptDisk - dDiskRad * vtRadLine ; - // Intersezioni con la prima retta + 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, vtDiskAx, 10, trTria, ptIntPlus1, ptIntPlus2, false) ; + int nIntPlus = IntersLineTria( ptStPlus, vtMove, 10, trTria, ptIntPlus1, ptIntPlus2, false) ; if ( nIntPlus != ILTT_NO) { - double dDist1 = PointPlaneSignedDist( ptIntPlus1, ptDisk, vtDiskAx) ; + 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, ptDisk, vtDiskAx) ; + double dDist2 = PointPlaneSignedDist( ptIntPlus2, ptDiskCen, vtMove) ; dDistPlus = max( dDist1, dDist2) ; } // Altrimenti ha senso solo dDist1 - else + else dDistPlus = dDist1 ; } - // Intersezioni con la seconda retta + // Intersezioni con la seconda retta double dDistMinus = 0. ; Point3d ptIntMinus1, ptIntMinus2 ; - int nIntMinus = IntersLineTria( ptStMinus, vtDiskAx, 10, trTria, ptIntMinus1, ptIntMinus2, false) ; + int nIntMinus = IntersLineTria( ptStMinus, vtMove, 10, trTria, ptIntMinus1, ptIntMinus2, false) ; if ( nIntMinus != ILTT_NO) { - double dDist1 = PointPlaneSignedDist( ptIntMinus1, ptDisk, vtDiskAx) ; + 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, ptDisk, vtDiskAx) ; + double dDist2 = PointPlaneSignedDist( ptIntMinus2, ptDiskCen, vtMove) ; dDistMinus = max( dDist1, dDist2) ; } // Altrimenti ha senso solo dDist1 - else + else dDistMinus = dDist1 ; - } - return max( dDistPlus, dDistMinus) ; + } + return max( dDistPlus, dDistMinus) ; } //---------------------------------------------------------------------------- -// Restituisce la distanza di allontanamento di un cilindro, che trasla lungo il suo asse -// di simmetria, da un triangolo. -// Il cilindro è descritto da raggio e altezza. Il suo moto è descritto dalla -// posizione iniziale, dal versore dell'asse di simmetria -// e dal versore della direzione del moto. Il segmento è descritto da punto -// iniziale, versore direzione e lunghezza. -double -CylTriaSegmentLeakDistLongMot( const Triangle3d& trTria, const Vector3d& vtMotion, - const Point3d& ptCylBase, double dCylRad) +// Valuta l'allontanamento di un disco, che trasla lungo il proprio asse di simmetria, +// da un piano. Il disco è descritto dal suo centro nella posizione iniziale e dal raggio. +// Il piano è descritto da un suo punto e dal suo versore normale. Il moto è descritto +// dal versore di traslazione. +// La funzione restituisce un intero che descrive la situazione di allontanamento e, +// nel caso che abbia senso, per referenza restituisce il punto in cui avviene +// l'estremo contatto. +// 0: Nessun contatto +// 1: Un contatto +// 2: Disco e piano ortogonali, il contatto è una semiretta +// 3: Disco e piano paralleli, la superficie di contatto è il disco intero +// Nel caso 0 il parametro ptTouch non ha senso, così come nel caso 2. +// Nel caso 3 ptTouch è il centro del disco nella posizione finale. +int +DiskPlaneLastContactLongMot( const Point3d& ptDiskCen, double dDiskRad, + const Point3d& ptPlane, const Vector3d& vtPlane, + const Vector3d& vtMove, Point3d& ptTouch) { - // Cerco i punti di contatto sui segmenti - double dSegDist = - DBL_MIN ; - // Ciclo sui segmenti - for ( int nVS = 0 ; nVS < 3 ; ++ nVS) { - int nVE = ( nVS + 1) % 3 ; - // Versore del segmento - Vector3d vtSeg = trTria.GetP( nVE) - trTria.GetP( nVS) ; - double dSegLen = vtSeg.Len() ; - vtSeg /= dSegLen ; - // Vettore punto retta - Vector3d vtPointLine = trTria.GetP( nVS) - ptCylBase ; - // Componenti dei vettori ortogonali all'asse del cilindro - Vector3d vtSegOrt = vtSeg - vtSeg * vtMotion * vtMotion ; - Vector3d vtPointLineOrt = vtPointLine - vtPointLine * vtMotion * vtMotion ; - - DBLVECTOR vdCoef(3) ; - DBLVECTOR vdRoots ; - vdCoef[0] = vtPointLineOrt.SqLen() - dCylRad * dCylRad ; - vdCoef[1] = 2 * vtPointLineOrt * vtSegOrt ; - vdCoef[2] = vtSegOrt.SqLen() ; - - // Soluzione dell'equazione - int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; - for ( int nSol = 0 ; nSol < nRoot ; ++ nSol) { - Point3d ptInt = trTria.GetP( nVS) + vdRoots[nSol] * vtSegOrt ; - if ( ( ptInt - trTria.GetP( nVS)) * vtSeg > 0 && - ( ptInt - trTria.GetP( nVS)) * vtSeg < dSegLen) { - double dCurDist = ( ptInt - ptCylBase) * vtMotion ; - if ( dSegDist < dCurDist) - dSegDist = dCurDist ; - } + // Se disco e piano sono paralleli + if ( AreSameOrOppositeVectorApprox( vtMove, vtPlane)) { + double dDist = PointPlaneSignedDist( ptPlane, ptDiskCen, vtMove) ; + if ( dDist > - EPS_SMALL) { + ptTouch = ptDiskCen + dDist * vtMove ; + return 3 ; } + return 0 ; } - return dSegDist ; + // Vettore radiale + Vector3d vtRadLine = vtMove * ( vtPlane * vtMove) - vtPlane ; + // Disco e piano ortogonali + if ( vtRadLine.IsNormalized()) { + if ( abs( PointPlaneSignedDist( ptPlane, ptDiskCen, vtMove) - dDiskRad) < EPS_SMALL) + return 2 ; + return 0 ; + } + // 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. + vtRadLine.Normalize() ; + // Punti delle due rette candidate all'intersezione col triangolo + Point3d ptStPlus = ptDiskCen + dDiskRad * vtRadLine ; + Point3d ptStMinus = ptDiskCen - dDiskRad * vtRadLine ; + // Parametri d'intersezione delle rette col piano + double dDistPlus = ( ( ptPlane - ptStPlus) * vtPlane) / ( vtMove * vtPlane) ; + double dDistMinus = ( ( ptPlane - ptStMinus) * vtPlane) / ( vtMove * vtPlane) ; + double dDist ; + if ( dDistPlus > dDistMinus) { + dDist = dDistPlus ; + ptTouch = ptStPlus + dDist * vtMove ; + } + else { + dDist = dDistMinus ; + ptTouch = ptStMinus + dDist * vtMove ; + } + if ( dDist > - EPS_SMALL) + return 1 ; + return 0 ; } //---------------------------------------------------------------------------- // Restituisce la distanza di fuga di un cilindro da un punto nel caso di moto // ortogonale all'asse di simmetria. Il cilindro è descritto da raggio e altezza. -// Il suo moto è descritto dalla posizione iniziale, dal versore (NORMA UNITARIA) +// Il suo moto è descritto dalla posizione iniziale, dal versore (NORMA UNITARIA) // dell'asse di simmetria e dal versore della direzione del moto. double -CylPointLeakDistOrtMotion( const Point3d& ptP, const Point3d& ptCylOrig, - const Vector3d& vtCylAx, const Vector3d& vtMove, - double dCylHei, double dCylRad) +CylPointLeakDistOrtMotion( const Point3d& ptCylOrig, const Vector3d& vtCylAx, double dCylHei, double dCylRad, + const Point3d& ptP, const Vector3d& vtMove) { - double dSqRad = dCylRad * dCylRad ; + double dSqRad = dCylRad * dCylRad ; Vector3d vtRP = ptP - ptCylOrig ; // Se il punto sta al di sopra o al di sotto rispetto al cilindro abbiamo finito double dDotRPCylAx = vtRP * vtCylAx ; if ( dDotRPCylAx > EPS_SMALL || dDotRPCylAx < - dCylHei - EPS_SMALL) return 0. ; - Vector3d vtPlaneRP = vtRP - dDotRPCylAx * vtCylAx ; + Vector3d vtPlaneRP = vtRP - dDotRPCylAx * vtCylAx ; // Se il punto sta dietro al cilindro abbiamo finito double dDotPlaneRPRemDir = vtPlaneRP * vtMove ; if ( dDotPlaneRPRemDir < 0. && vtPlaneRP.SqLen() > dSqRad) return 0. ; - Vector3d vtPlaneOrtRP = vtPlaneRP - vtPlaneRP * vtMove * vtMove ; + Vector3d vtPlaneOrtRP = vtPlaneRP - vtPlaneRP * vtMove * vtMove ; // Se il punto è a destra o sinistra del cilindro abbiamo finito double dSqOrtLen = vtPlaneOrtRP.SqLen() ; if ( dSqOrtLen > dSqRad + 2 * dCylRad * EPS_SMALL) return 0. ; // Calcolo e restituisco la distanza - return dDotPlaneRPRemDir + sqrt( max( dSqRad - dSqOrtLen, 0.)) ; + return dDotPlaneRPRemDir + sqrt( max( dSqRad - dSqOrtLen, 0.)) ; } //---------------------------------------------------------------------------- @@ -507,31 +512,30 @@ CylPointLeakDistOrtMotion( const Point3d& ptP, const Point3d& ptCylOrig, // versore della direzione del moto. Il segmento è descritto da punto iniziale, // versore direzione e lunghezza. double -DiskSegmentLeakDistOrtMot( const Point3d& ptSeg, const Point3d& ptDiscOrig, - const Vector3d& vtSeg, const Vector3d& vtDiscAx, const Vector3d& vtMove, - double dSegLen, double dDiscRad) +DiskSegmentLeakDistOrtMot( const Point3d& ptDiscCen, const Vector3d& vtDiscAx, double dDiscRad, + const Point3d& ptSeg, const Vector3d& vtSeg, double dSegLen, const Vector3d& vtMove) { - // Se il segmento non è nel piano, il più remoto punto di contatto è, + // Se il segmento non è nel piano, il più remoto punto di contatto è, // se esiete, l'intersezione fra piano e segmento. Il caso in cui il // segmento giace nel piano non ci interessa if ( ! ( abs( vtSeg * vtDiscAx) < EPS_ZERO)) { Point3d ptSegEnd = ptSeg + dSegLen * vtSeg ; - double dDotStart = ( ptSeg - ptDiscOrig) * vtDiscAx ; - double dDotEnd = ( ptSegEnd - ptDiscOrig) * vtDiscAx ; + double dDotStart = ( ptSeg - ptDiscCen) * vtDiscAx ; + double dDotEnd = ( ptSegEnd - ptDiscCen) * vtDiscAx ; if ( dDotStart * dDotEnd < 0.) { - double dS = ( ptDiscOrig - ptSeg) * vtDiscAx / ( vtSeg * vtDiscAx) ; + double dS = ( ptDiscCen - ptSeg) * vtDiscAx / ( vtSeg * vtDiscAx) ; Point3d ptInt = ptSeg + dS * vtSeg ; - Vector3d vtOI = ( ptInt - ptDiscOrig) ; + Vector3d vtOI = ( ptInt - ptDiscCen) ; double dLongCord = vtOI * vtMove ; Vector3d vtLong = dLongCord * vtMove ; Vector3d vtOrt = vtOI - vtLong ; double dSqOrtLen = vtOrt.SqLen() ; if ( dSqOrtLen > dDiscRad * dDiscRad + 2 * dDiscRad * EPS_SMALL) return 0. ; - else + else return max( dLongCord + sqrt( max( dDiscRad * dDiscRad - dSqOrtLen, 0.)), 0.) ; } - else + else return 0. ; } return 0. ; @@ -540,14 +544,13 @@ DiskSegmentLeakDistOrtMot( const Point3d& ptSeg, const Point3d& ptDiscOrig, //---------------------------------------------------------------------------- // Restituisce la distanza di allontanamento di un cilindro da un segmento. // Il cilindro è descritto da raggio e altezza. -// Il suo moto è descritto dalla posizione iniziale, dal versore (NORMA UNITARIA) -// dell'asse di simmetria e dal versore della direzione del moto. +// Il suo moto è descritto dalla posizione iniziale, dal versore (NORMA UNITARIA) +// dell'asse di simmetria e dal versore della direzione del moto. double -CylSegmentLeakDistOrtMotion( const Point3d& ptSeg, const Point3d& ptCylOrig, - const Vector3d& vtSeg, const Vector3d& vtCylAx, const Vector3d& vtMove, - double dSegLen, double dCylHei, double dCylRad) +CylSegmentLeakDistOrtMotion( const Point3d& ptCylOrig, const Vector3d& vtCylAx, double dCylHei, double dCylRad, + const Point3d& ptSeg, const Vector3d& vtSeg, double dSegLen, const Vector3d& vtMove) { - // Le variabili fanno rifermiento a un sistema di riferimento + // Le variabili fanno rifermiento a un sistema di riferimento // con origine nel centro del disco nella posizione iniziale. // X := vtCylAx, Y:= vtMove, Z:= vtCylAx ^ vtMove. Vector3d vtPlane = vtCylAx ^ vtMove ; @@ -560,8 +563,8 @@ CylSegmentLeakDistOrtMotion( const Point3d& ptSeg, const Point3d& ptCylOrig, Vector3d vtSegStart1 = dCordStart1 * vtCylAx ; Vector3d vtSegEnd1 = dCordEnd1 * vtCylAx ; Vector3d vtSegStart23 = vtSegStart - vtSegStart1 ; - Vector3d vtSegEnd23 = vtSegEnd - vtSegEnd1 ; - // Se entrambi gli estremi del segmento sono a un lato + Vector3d vtSegEnd23 = vtSegEnd - vtSegEnd1 ; + // Se entrambi gli estremi del segmento sono a un lato // del cilindro non vi può essere interferenza. double dCordStart2 = vtSegStart23 * vtPlane ; double dCordEnd2 = vtSegEnd23 * vtPlane ; @@ -569,12 +572,11 @@ CylSegmentLeakDistOrtMotion( const Point3d& ptSeg, const Point3d& ptCylOrig, ( dCordStart2 < - dCylRad && dCordEnd2 < - dCylRad)) return 0. ; // Verifico la distanza di fuga di superficie laterale e dischi di base e fondo. - double dBaseLeakDist = DiskSegmentLeakDistOrtMot( ptSeg, ptCylOrig, vtSeg, vtCylAx, - vtMove, dSegLen, dCylRad) ; - double dBottomLeakDist = DiskSegmentLeakDistOrtMot( ptSeg, ptCylOrig - dCylHei * vtCylAx, - vtSeg, vtCylAx, vtMove, dSegLen, dCylRad) ; - - double dSurfLeakDist = - DBL_MAX ; + double dBaseLeakDist = DiskSegmentLeakDistOrtMot( ptCylOrig, vtCylAx, dCylRad, ptSeg, vtSeg, dSegLen, vtMove) ; + double dBottomLeakDist = DiskSegmentLeakDistOrtMot( ptCylOrig - dCylHei * vtCylAx, vtCylAx, dCylRad, + ptSeg, vtSeg, dSegLen, vtMove) ; + + double dSurfLeakDist = 0. ; if ( ( dCordStart1 < 0. && dCordStart1 > - dCylHei) || ( dCordEnd1 < 0. && dCordEnd1 > - dCylHei)) { // Se il vettore del segmento è parallelo all'asse del cilindro, @@ -582,27 +584,27 @@ CylSegmentLeakDistOrtMotion( const Point3d& ptSeg, const Point3d& ptCylOrig, Vector3d vtRad = vtCylAx ^ vtSeg ; if ( ! vtRad.Normalize()) { dSurfLeakDist = max( ( ptSeg - ptCylOrig) * vtMove, 0.) ; - } + } // Se il versore radiale NON è ortogonale a quello di movimento può esserci tangenza, - // altrimenti il versore del segmento non ha componenti ortogonali al piano + // altrimenti il versore del segmento non ha componenti ortogonali al piano // generato da asse cilindro e moto e non può esserci tangenza. else if ( ! ( abs( vtRad * vtMove) < EPS_SMALL)) { // Nella posizione finale il cilindro e la retta del segmento sono tangenti. // Vettore che spicca dal punto di tangenza fra cilindro e retta - // associata al segmento e termina sull'asse del cilindro. + // associata al segmento e termina sull'asse del cilindro. vtRad *= dCylRad ; // Lunghezza della componente del vettore radiale ortogonale alla linea di movimento double dDotRemRad = abs( vtRad * vtMove) ; double dOrtLen = sqrt( max( dCylRad * dCylRad - dDotRemRad * dDotRemRad, 0.)) ; - // Cerco lungo la retta un punto che stia nel segmento e abbia distanza dal piano + // Cerco lungo la retta un punto che stia nel segmento e abbia distanza dal piano // abbia distanza dal piano +/- dOrtLen. Vector3d vtPlane = vtMove ^ vtCylAx ; vtPlane.Normalize() ; Vector3d vtD = ptSeg - ptCylOrig ; double dDotPlaneD = vtD * vtPlane ; - double dDotPlaneSeg = vtSeg * vtPlane ; - double dPlusU = ( dOrtLen - dDotPlaneD) / dDotPlaneSeg ; - double dMinusU = ( - dOrtLen - dDotPlaneD) / dDotPlaneSeg ; + double dDotPlaneSeg = vtSeg * vtPlane ; + double dPlusU = ( dOrtLen - dDotPlaneD) / dDotPlaneSeg ; + double dMinusU = ( - dOrtLen - dDotPlaneD) / dDotPlaneSeg ; Point3d ptTanPlus = ptSeg + dPlusU * vtSeg ; Point3d ptTanMinus = ptSeg + dMinusU * vtSeg ; double dTanCordPlus1 = ( ptTanPlus - ptCylOrig) * vtCylAx ; @@ -614,67 +616,207 @@ CylSegmentLeakDistOrtMotion( const Point3d& ptSeg, const Point3d& ptCylOrig, if ( dMinusU > - EPS_SMALL && dMinusU < dSegLen + EPS_SMALL && ( dTanCordMinus1 < 0 && dTanCordMinus1 > - dCylHei)) { double dNewDist = max( ( ( ptSeg - ptCylOrig) + dMinusU * vtSeg) * vtMove + dDotRemRad, 0.) ; - dSurfLeakDist = max( dNewDist, dSurfLeakDist) ; - } + dSurfLeakDist = max( dNewDist, dSurfLeakDist) ; + } } } return max( max( dBaseLeakDist, dBottomLeakDist), max( dSurfLeakDist, 0.)) ; } //---------------------------------------------------------------------------- -// Restituisce la distanza di allontanamento di un disco, che trasla ortogonalmente al suo asse +// 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 +// 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 Triangle3d& trTria, const Point3d& ptDiscOrig, const Vector3d& vtDiscAx, - const Vector3d& vtMotion, double dCylRad, Point3d& ptContact) +DiskPlaneLeakDistOrtMot( const Point3d& ptDiscCen, const Vector3d& vtDiscAx, double dDiscRad, + const Point3d& ptPlane, const Vector3d& vtPlane, + const Vector3d& vtMove, Point3d& ptContact) { - Vector3d vtLine = trTria.GetN() ^ vtDiscAx ; - if ( vtLine.Normalize() && abs( vtMotion * vtLine) < 1 - EPS_ZERO) { - // Definisco l'equazione - DBLVECTOR vdCoef( 3) ; - DBLVECTOR vdRoots ; - double dP = ( trTria.GetP( 0) - ptDiscOrig) * trTria.GetN() / ( vtMotion * trTria.GetN()) ; - Point3d ptLine = ptDiscOrig + dP * vtMotion ; - Vector3d vtMotOrt = vtMotion - vtMotion * vtLine * vtLine ; - Vector3d vtDist = ptLine - ptDiscOrig ; - Vector3d vtDistOrt = vtDist - vtDist * vtLine * vtLine ; - // Setto i coefficienti dell'equazione - vdCoef[0] = vtDistOrt.SqLen() - dCylRad * dCylRad ; - vdCoef[1] = - 2 * vtMotOrt * vtDistOrt ; - vdCoef[2] = vtMotOrt.SqLen() ; - // Risolvo l'equazione - int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; - // Studio le soluzioni - double dLeakDist = - DBL_MAX ; - for ( int nS = 0 ; nS < nRoot ; ++ nS) { - if ( dLeakDist < vdRoots[nS]) { - double dLinePar = vdRoots[nS] * vtMotion * vtLine - vtDist * vtLine ; - ptContact = ptLine + dLinePar * vtLine ; - dLeakDist = vdRoots[nS] ; - } - } - return max( dLeakDist, 0.) ; - } + Vector3d vtLine = vtPlane ^ vtDiscAx ; + if ( vtLine.Normalize() && ! AreSameOrOppositeVectorApprox( vtMove, vtLine)) { + Vector3d vtRad = dDiscRad * vtLine ^ vtDiscAx ; + if ( vtRad * vtMove > 0) + vtRad *= - 1 ; + double dPar = ( ptPlane - ptDiscCen) * vtPlane / ( vtMove * vtPlane) ; + double dDeltaPar = dDiscRad * dDiscRad / abs( vtRad * vtMove) ; + double dDesplacement = max( dPar + dDeltaPar, 0.) ; + ptContact = ptDiscCen + dDesplacement * vtMove + vtRad ; + return dDesplacement ; + } return 0. ; } +//---------------------------------------------------------------------------- +// **** CONO **** +//---------------------------------------------------------------------------- +double +CAvTrConeTriangle( const Point3d& ptMinBase, const Vector3d& vtTrConeAx, double dMinBaseR, double dMaxBaseR, + double dTrConeH, const Triangle3d& trTria, const Vector3d& vtMove) +{ + // Allontanamento con direzione coincidente con l'asse del cono + if ( AreSameOrOppositeVectorApprox( vtTrConeAx, vtMove)) { + // Distanza di allontanamento dai vertici e lati + double dOutLeakDist = 0 ; + for ( int nV = 0 ; nV < 3 ; ++ nV) { + // dal vertice + double dCurVertDist = TrConePointLeakDistLongMot( ptMinBase, vtTrConeAx, dMinBaseR, dMaxBaseR, dTrConeH, + trTria.GetP( nV), vtMove) ; + dOutLeakDist = max( dCurVertDist, dOutLeakDist) ; + // dal lato + Vector3d vtSeg = trTria.GetP( ( nV + 1) % 3) - trTria.GetP( nV) ; + double dSegLen = vtSeg.Len() ; + vtSeg /= dSegLen ; + double dCurSegDist = TrConeSegmentLeakDistLongMot( ptMinBase, vtTrConeAx, dMinBaseR, dMaxBaseR, + dTrConeH, trTria.GetP( nV), vtSeg, dSegLen, vtMove) ; + dOutLeakDist = max( dCurSegDist, dOutLeakDist) ; + } + double dInnLeakDist = TrConeTriangleInteriorLeakDistLongMot( ptMinBase, vtTrConeAx, dMinBaseR, dMaxBaseR, dTrConeH, + trTria, vtMove) ; + return max( dOutLeakDist, dInnLeakDist) ; + } + // altri casi + else + return 0. ; +} + +//---------------------------------------------------------------------------- +double +TrConePointLeakDistLongMot( const Point3d& ptMinBase, const Vector3d& vtTrConeAx, double dMinBaseR, double dMaxBaseR, + double dTrConeH, const Point3d& ptP, const Vector3d& vtMove) +{ + double dPointAxisSqDist = GetPointLineSqDist( ptP, ptMinBase, vtTrConeAx) ; + if ( dPointAxisSqDist > dMaxBaseR * dMaxBaseR + 2 * dMaxBaseR * EPS_SMALL) + return 0. ; + else if ( dPointAxisSqDist > dMinBaseR * dMinBaseR + 2 * dMinBaseR * EPS_SMALL) { + double dMinBaseLeakDist = PointPlaneSignedDist( ptP, ptMinBase, vtMove) ; + double dMaxBaseLeakDist = PointPlaneSignedDist( ptP, ptMinBase + dTrConeH * vtTrConeAx, vtMove) ; + if ( dMinBaseLeakDist < - EPS_SMALL && dMaxBaseLeakDist < - EPS_SMALL) + return 0. ; + double dDistMinBaseV = dTrConeH * dMinBaseR / ( dMaxBaseR - dMinBaseR) ; + Point3d ptConeV = ptMinBase - dDistMinBaseV * vtTrConeAx ; + Vector3d vtVertP = ptP - ptConeV ; + double dVertPLongCord = vtMove * vtVertP ; + if ( vtMove * vtTrConeAx > 0.) { + double dPointAxisDist = sqrt( GetPointLineSqDist( ptP, ptMinBase, vtMove)) ; + double dLateralSurfLeakDist = dVertPLongCord - dPointAxisDist * dTrConeH / ( dMaxBaseR - dMinBaseR) ; + return max( dLateralSurfLeakDist, 0.) ; + } + 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.) ; + } +} + +//---------------------------------------------------------------------------- +double +TrConeSegmentLeakDistLongMot( const Point3d& ptMinBase, const Vector3d& vtTrConeAx, double dMinBaseR, double dMaxBaseR, + double dTrConeH, const Point3d& ptSeg, const Vector3d& vtSeg, double dSegLen, + const Vector3d& vtMove) +{ + // Distanza di allontanamento delle basi + Point3d ptMaxBase = ptMinBase + dTrConeH * vtTrConeAx ; + double dMinBaseLeakDist = DiskSegmentLeakDistLongMotion( ptMinBase, dMinBaseR, ptSeg, vtSeg, dSegLen, vtMove) ; + double dMaxBaseLeakDist = DiskSegmentLeakDistLongMotion( ptMaxBase, dMaxBaseR, ptSeg, vtSeg, dSegLen, vtMove) ; + double dBasesLeakDist = max( max( dMinBaseLeakDist, dMaxBaseLeakDist), 0.) ; + // Distanza di allontanamento della superficie laterale + double dDistMinBaseV = dTrConeH * dMinBaseR / ( dMaxBaseR - dMinBaseR) ; + Point3d ptConeV = ptMinBase - dDistMinBaseV * vtTrConeAx ; + Frame3d frConusFrame ; + frConusFrame.Set( ptConeV, vtTrConeAx) ; + Point3d ptSegNew = ptSeg ; + Vector3d vtSegNew = vtSeg ; + ptSegNew.ToLoc( frConusFrame) ; + vtSegNew.ToLoc( frConusFrame) ; + double dAngCoef = ( dDistMinBaseV + dTrConeH) / dMaxBaseR ; + double dAlpha = vtSegNew.z * vtSegNew.z - dAngCoef * dAngCoef * ( vtSegNew.x * vtSegNew.x + vtSegNew.y * vtSegNew.y) ; + double dBeta = ptSegNew.z * vtSegNew.z - dAngCoef * dAngCoef * ( ptSegNew.x * vtSegNew.x + ptSegNew.y * vtSegNew.y) ; + double dGamma = ptSegNew.z * ptSegNew.z - dAngCoef * dAngCoef * ( ptSegNew.x * ptSegNew.x + ptSegNew.y * ptSegNew.y) ; + // Se l'equazione è di primo grado, non serve risolvere (si trova altrimenti con i punti estremi del segmento) + if ( abs( dAlpha) < EPS_ZERO) + return 0. ; + // Impongo il determinante nullo, ne deriva una nuova equazione da risolvere + DBLVECTOR vdDeltaCoef( 3) ; + DBLVECTOR vdDeltaRoots ; + vdDeltaCoef[0] = dBeta * dBeta - dAlpha * dGamma ; + vdDeltaCoef[1] = 2 * ( dBeta * vtSegNew.z - dAlpha * ptSegNew.z) ; + vdDeltaCoef[2] = ( vtSegNew.z * vtSegNew.z - dAlpha) ; + int nRoot = PolynomialRoots( 2, vdDeltaCoef, vdDeltaRoots) ; + // Studio le soluzioni + double dLateralSurfLeakDist = 0. ; + for ( int nS = 0 ; nS < nRoot ; ++ nS) { + // Queste soluzioni sono gli spostamenti lungo z del segmento che, lo portano in + // una configurazione di tangenza col cono (delta = 0). Ora risolviamo l'equazione + // dell'intersezione in corrispondenza del parametro di spostamento trovato. + // Essendo il delta nullo la sola soluzione è - b/2a. + double dT = - ( dBeta + vtSegNew.z * vdDeltaRoots[nS]) / dAlpha ; + Point3d ptTan( ptSegNew.x, ptSegNew.y, ptSegNew.z + vdDeltaRoots[nS]) ; + ptTan += dT * vtSegNew ; + if ( ptTan.z > dDistMinBaseV - EPS_SMALL && + ptTan.z < dDistMinBaseV + dTrConeH + EPS_SMALL && + dT > - EPS_SMALL && dT < dSegLen + EPS_SMALL) { + if ( ( vtTrConeAx * vtMove > 0 && vdDeltaRoots[nS] < 0.) || + ( vtTrConeAx * vtMove < 0 && vdDeltaRoots[nS] > 0.)) + dLateralSurfLeakDist = abs( vdDeltaRoots[nS]) ; + } + } + return max( dBasesLeakDist, dLateralSurfLeakDist) ; +} + +//---------------------------------------------------------------------------- +double +TrConeTriangleInteriorLeakDistLongMot( const Point3d& ptMinBase, const Vector3d& vtTrConeAx, double dMinBaseR, double dMaxBaseR, + double dTrConeH, const Triangle3d& trTria, const Vector3d& vtMove) +{ + // Distanza di allontanamento del disco minore + Point3d ptMinTouch ; + int nMinLeakType = DiskPlaneLastContactLongMot( ptMinBase, dMinBaseR, trTria.GetP( 0), trTria.GetN(), + vtMove, ptMinTouch) ; + double dMinLeakDist = ( ptMinTouch - ptMinBase) * vtMove ; + // Distanza di allontanamento del disco maggiore + Point3d ptMaxTouch ; + Point3d ptMaxBase = ptMinBase + dTrConeH * vtTrConeAx ; + int nMaxLeakType = DiskPlaneLastContactLongMot( ptMaxBase, dMaxBaseR, trTria.GetP( 0), trTria.GetN(), + vtMove, ptMaxTouch) ; + double dMaxLeakDist = ( ptMaxTouch - ptMaxBase) * vtMove ; + // se le due distanze sono uguali e tipo di contatto 1, allora superficie laterale cono tangente a piano + if ( abs( dMaxLeakDist - dMinLeakDist) < EPS_SMALL) { + Point3d ptInt1, ptInt2 ; + int nRes = IntersLineTria( ptMinTouch, ptMaxTouch, trTria, ptInt1, ptInt2) ; + if ( nRes != ILTT_NO) + return max( ( dMaxLeakDist + dMinLeakDist) / 2, 0.) ; + } + // altrimenti sono i dischi a determinare l'allontanamento + double dMove = 0 ; + if ( ( nMinLeakType == 1 && IsPointInsideTriangle( ptMinTouch, trTria)) || + ( nMinLeakType == 3 && CoplanarDiscTriangleInterferance( ptMinTouch, dMinBaseR, trTria))) + dMove = max( dMinLeakDist, 0.) ; + if ( ( nMaxLeakType == 1 && IsPointInsideTriangle( ptMaxTouch, trTria)) || + ( nMaxLeakType == 3 && CoplanarDiscTriangleInterferance( ptMaxTouch, dMaxBaseR, trTria))) + dMove = max( dMove, dMaxLeakDist) ; + return dMove ; +} + + // FUNZIONI GEOMETRICHE DI BASE PER IL CALCOLO DELLA DISTANZA DI ALLONTANAMENTO //---------------------------------------------------------------------------- // Dati un punto e una retta, restituisce il quadrato della loro distanza. // La retta è descritta da un suo punto e dal suo versore tangente. -double +double GetPointLineSqDist( const Point3d& ptP, const Point3d& ptLine, const Vector3d& vtLine) { return ( ( ptP - ptLine) - ( ptP - ptLine) * vtLine * vtLine).SqLen() ; } //---------------------------------------------------------------------------- -// Dati un punto e un piano, ne restituisce la distanza con segno. -// Il piano è descritto da un suo punto e dal suo versore normale. +// Dati un punto e un piano, ne restituisce la distanza con segno. +// Il piano è descritto da un suo punto e dal suo versore normale. double PointPlaneSignedDist( const Point3d& ptP, const Point3d& ptPlane, const Vector3d& vtNorm) { @@ -682,18 +824,18 @@ PointPlaneSignedDist( const Point3d& ptP, const Point3d& ptPlane, const Vector3d } //---------------------------------------------------------------------------- -// Dati un sistema di tre punti e un piano, ne calcola le tre distanze con segno e ne restituisce la -// maggiore. I tre punti sono passati mediante un triangolo, il piano è descritto da un suo punto e +// Dati un sistema di tre punti e un piano, ne calcola le tre distanze con segno e ne restituisce la +// maggiore. I tre punti sono passati mediante un triangolo, il piano è descritto da un suo punto e // dal suo versore normale. double ThreePointPlaneSignedDist( const Triangle3d& trTria, const Point3d& ptPlane, const Vector3d& vtNorm) { double dMaxSgnDist = - INFINITO ; for ( int nV = 0 ; nV < 3 ; ++ nV) { - double dCurrSgnDist = PointPlaneSignedDist( trTria.GetP( nV), ptPlane, vtNorm) ; + double dCurrSgnDist = PointPlaneSignedDist( trTria.GetP( nV), ptPlane, vtNorm) ; if ( dCurrSgnDist > dMaxSgnDist) dMaxSgnDist = dCurrSgnDist ; - } + } return dMaxSgnDist ; } @@ -712,23 +854,23 @@ int LinePlaneDDistPar( const Point3d& ptPlane, const Vector3d& vtPlane, const Point3d& ptLine, const Vector3d& vtLine, double dDist, double& dPar) { - // Vettore congiungente il punto del piano con il punto iniziale della retta + // Vettore congiungente il punto del piano con il punto iniziale della retta Vector3d vtPlLn = ptLine - ptPlane ; // Distanza con segno del punto iniziale della retta dal piano - double dSgnDist0 = vtPlLn * vtPlane ; + double dSgnDist0 = vtPlLn * vtPlane ; // Prodotto scalare fra versore della direzione della retta e versore normale al piano - double dDotDirNorm = vtLine * vtPlane ; - // Retta parallela al piano - if ( abs( dDotDirNorm) < EPS_ZERO) { - if ( abs( dSgnDist0 - dDist) < EPS_SMALL) + double dDotDirNorm = vtLine * vtPlane ; + // Retta parallela al piano + if ( abs( dDotDirNorm) < EPS_ZERO) { + if ( abs( dSgnDist0 - dDist) < EPS_SMALL) return 2 ; else return 0 ; } // Caso generale else { - dPar = ( dDist - dSgnDist0) / dDotDirNorm ; - return 1 ; + dPar = ( dDist - dSgnDist0) / dDotDirNorm ; + return 1 ; } } @@ -736,16 +878,16 @@ LinePlaneDDistPar( const Point3d& ptPlane, const Vector3d& vtPlane, const Point3 // Date due rette nello spazio restituisce il quadrato della loro distanza. // Le rette vengono descritte da punto di passaggio e versore direzione. double -LineLineSqDist( const Point3d& ptP1, const Vector3d& vtD1, const Point3d& ptP2, const Vector3d& vtD2) -{ - // Caso di rette parallele - if ( abs( 1. - abs( vtD1 * vtD2)) < EPS_SMALL) - return ( ( ptP2 - ptP1) - ( ptP2 - ptP1) * vtD1 * vtD1).SqLen() ; +LineLineSqDist( const Point3d& ptP1, const Vector3d& vtD1, const Point3d& ptP2, const Vector3d& vtD2) +{ + // Caso di rette parallele + if ( abs( 1. - abs( vtD1 * vtD2)) < EPS_SMALL) + return ( ( ptP2 - ptP1) - ( ptP2 - ptP1) * vtD1 * vtD1).SqLen() ; // Caso generale else { Vector3d vtOrtD2 = vtD2 - vtD2 * vtD1 * vtD1 ; Vector3d vtOrtP1P2 = ( ptP2 - ptP1) - ( ptP2 - ptP1) * vtD1 * vtD1 ; - double dD = ( vtOrtD2 * vtOrtP1P2) / vtOrtP1P2.SqLen() ; + double dD = ( vtOrtD2 * vtOrtP1P2) / vtOrtP1P2.SqLen() ; return vtOrtP1P2.SqLen() + dD * dD * vtOrtD2.SqLen() + 2 * dD * vtOrtD2 * vtOrtP1P2 ; } } @@ -760,8 +902,8 @@ LineSegmentSqDist( const Point3d& ptPLn, const Vector3d& vtDLn, const Point3d& ptPSg, const Vector3d& vtDSg, double dSgLen) { // Caso di parallelismo - if ( AreSameOrOppositeVectorApprox( vtDLn, vtDSg)) - return ( ( ptPSg - ptPLn) - ( ptPSg - ptPLn) * vtDLn * vtDLn).SqLen() ; + if ( AreSameOrOppositeVectorApprox( vtDLn, vtDSg)) + return ( ( ptPSg - ptPLn) - ( ptPSg - ptPLn) * vtDLn * vtDLn).SqLen() ; // Caso generale else { double dDLn = ( ptPSg - ptPLn) * vtDLn ; @@ -778,17 +920,17 @@ LineSegmentSqDist( const Point3d& ptPLn, const Vector3d& vtDLn, // altrimenti, determino i due punti a minima distanza else { double dLnPar = ( dDLn - dDSg * dDLnSg) / ( 1. - dDLnSg * dDLnSg) ; - Point3d ptMinLn = ptPLn + dLnPar * vtDLn ; - Point3d ptMinSg = ptPSg + dSgPar * vtDSg ; + Point3d ptMinLn = ptPLn + dLnPar * vtDLn ; + Point3d ptMinSg = ptPSg + dSgPar * vtDSg ; return SqDist( ptMinLn, ptMinSg) ; - } + } } } //---------------------------------------------------------------------------- // Stabilisce se un punto appartiene a un triangolo interno o frontiera. bool -IsPointInsideTriangle( const Point3d& ptP, const Triangle3d& trTria) +IsPointInsideTriangle( const Point3d& ptP, const Triangle3d& trTria) { // Se il punto non sta sul piano del triangolo ho finito if ( abs( ( ptP - trTria.GetP( 0)) * trTria.GetN()) > EPS_SMALL) @@ -816,6 +958,35 @@ IsPointInsideTriangle( const Point3d& ptP, const Triangle3d& trTria) return true ; } +//---------------------------------------------------------------------------- +// Valuta l'interferenza di un disco e un triangolo complanari. +bool +CoplanarDiscTriangleInterferance( const Point3d& ptCen, double dRad, const Triangle3d& trTria) +{ + // Se il centro del disco non sta sul piano del triangolo, non sono complanari + if ( abs( PointPlaneSignedDist( ptCen, trTria.GetP( 0), trTria.GetN())) > EPS_SMALL) + return false ; + // Se il centro giace nel triangolo + if ( IsPointInsideTriangle( ptCen, trTria)) + return true ; + double dSqMinDist = dRad * dRad + 2 * dRad * EPS_SMALL ; + Vector3d vtSeg0 = ( trTria.GetP(1) - trTria.GetP(0)) / Dist( trTria.GetP(1), trTria.GetP(0)) ; + Vector3d vtSeg1 = ( trTria.GetP(2) - trTria.GetP(1)) / Dist( trTria.GetP(2), trTria.GetP(1)) ; + Vector3d vtSeg2 = ( trTria.GetP(0) - trTria.GetP(2)) / Dist( trTria.GetP(0), trTria.GetP(2)) ; + // Se il centro non si avvicina più del raggio dalle rette associate ai segmenti, non c'è interferenza + if ( GetPointLineSqDist( ptCen, trTria.GetP(0), vtSeg0) > dSqMinDist && + GetPointLineSqDist( ptCen, trTria.GetP(1), vtSeg1) > dSqMinDist && + GetPointLineSqDist( ptCen, trTria.GetP(2), vtSeg2) > dSqMinDist) + return false ; + // Se il centro non si avvicina più del raggio ai vertici, non c'è interferenza + if ( SqDist( ptCen, trTria.GetP(0)) > dSqMinDist && + SqDist( ptCen, trTria.GetP(1)) > dSqMinDist && + SqDist( ptCen, trTria.GetP(2)) > dSqMinDist) + return false ; + // interferenza + return true ; +} + //---------------------------------------------------------------------------- // Date due rette, descritte da un punto e un vettore direzione, // trova i parametri corrispondenti ai punti di minima distanza. @@ -830,27 +1001,27 @@ FindMinDistPar( const Point3d& ptL1, const Point3d& ptL2, double& dU1, double& dU2) { // Se le rette sono parallele - if ( abs( abs( vtV1 * vtV2) - 1) < EPS_ZERO) + if ( abs( abs( vtV1 * vtV2) - 1) < EPS_ZERO) return false ; // Vettore congiungente i punti iniziali Vector3d vtD = ptL2 - ptL1 ; // Proiezioni di vtD sui versori direzione - double dD1 = vtD * vtV1 ; + double dD1 = vtD * vtV1 ; double dD2 = vtD * vtV2 ; // Prodotto scalare fra i versori direzione double dV = vtV1 * vtV2 ; // Se le rette sono perpendicolari - if ( abs( vtV1 * vtV2) < EPS_ZERO) { + if ( abs( vtV1 * vtV2) < EPS_ZERO) { dU1 = dD1 ; dU2 = - dD2 ; } // Caso generale else { - dU1 = ( dD1 - dD2 * dV) / ( 1 - dV * dV) ; - dU2 = ( - dD2 + dD1 * dV) / ( 1 - dV * dV) ; - } + dU1 = ( dD1 - dD2 * dV) / ( 1 - dV * dV) ; + dU2 = ( - dD2 + dD1 * dV) / ( 1 - dV * dV) ; + } return true ; } @@ -869,9 +1040,9 @@ SphereLineTangentPoints( const Point3d& ptSpheCen, double dSpheRad, const Vector3d& vtMove, double& dU1, double& dU2) { // Definisco l'equazione - Vector3d vtMotOrt = vtMove - vtMove * vtSegDir * vtSegDir ; + Vector3d vtMotOrt = vtMove - vtMove * vtSegDir * vtSegDir ; Vector3d vtLineSeg = ptSeg - ptSpheCen ; - Vector3d vtLineSegOrt = vtLineSeg - vtLineSeg * vtSegDir * vtSegDir ; + Vector3d vtLineSegOrt = vtLineSeg - vtLineSeg * vtSegDir * vtSegDir ; // Setto i coefficienti dell'equazione DBLVECTOR vdCoeff( 3) ; vdCoeff[0] = vtLineSegOrt.SqLen() - dSpheRad * dSpheRad ; @@ -880,9 +1051,9 @@ SphereLineTangentPoints( const Point3d& ptSpheCen, double dSpheRad, if ( vdCoeff[2] < EPS_ZERO * EPS_ZERO) { if ( abs( vdCoeff[0]) < EPS_SMALL) return 3 ; - else - return 0 ; - } + else + return 0 ; + } // Risolvo l'equazione DBLVECTOR vdRoots ; int nRoots = PolynomialRoots( 2, vdCoeff, vdRoots) ; @@ -890,13 +1061,8 @@ SphereLineTangentPoints( const Point3d& ptSpheCen, double dSpheRad, if ( nRoots == 1) dU1 = vdRoots[0] ; else if ( nRoots == 2) { - dU1 = min( vdRoots[0], vdRoots[1]) ; - dU2 = max( vdRoots[0], vdRoots[1]) ; + dU1 = min( vdRoots[0], vdRoots[1]) ; + dU2 = max( vdRoots[0], vdRoots[1]) ; } return nRoots ; } - - - - - diff --git a/CAvToolTriangle.h b/CAvToolTriangle.h index 7f2c91d..9657888 100644 --- a/CAvToolTriangle.h +++ b/CAvToolTriangle.h @@ -17,7 +17,7 @@ #include "/EgtDev/Include/EGkTriangle3d.h" double CAvToolTriangle( const Tool& tlTool, const Point3d& ptToolOrig, const Vector3d& vtToolAx, - const Triangle3d& trTria, const Vector3d& vtMove) ; + const Triangle3d& trTria, const Vector3d& vtMove) ; // Componenti: // Sfera @@ -29,23 +29,31 @@ double SphereSegmentLeakDist( const Point3d& ptSpheCen, double dSpheRad, const Vector3d& vtMove) ; double SpherePointLeakDist( const Point3d& ptSpheCen, double dSpheRad, const Point3d ptP, const Vector3d& vtMove) ; // Cilindro -double CAvCylinderTriangle( const Point3d& ptCompOrig, const Vector3d& vtCompAx, double dHeigth, double dRad, - const Triangle3d& trTria, const Vector3d& vtMove) ; -double DiskSegmentLeakDistLongMotion( const Point3d& ptDisk, const Vector3d& vtDiscLeak, double dDiscRad, - const Point3d& ptSeg, const Vector3d& vtSeg, double dSegLen) ; -double DiskTriaInteriorLeakDistLongMot( const Point3d& ptDisk, const Vector3d& vtDiskAx, double dDiskRad, - const Triangle3d& trTria) ; -double CylPointLeakDistOrtMotion( const Point3d& ptP, const Point3d& ptCompOrig, - const Vector3d& vtCylAx, const Vector3d& vtRemDir, - double dCylHei, double dCylRad) ; -double DiskSegmentLeakDistOrtMot( const Point3d& ptSeg, const Point3d& ptDiscOrig, - const Vector3d& vtSeg, const Vector3d& vtDiscAx, const Vector3d& vtRemDir, - double dSegLen, double dDiscRad) ; -double CylSegmentLeakDistOrtMotion( const Point3d& ptSeg, const Point3d& ptCylOrig, - const Vector3d& vtSeg, const Vector3d& vtCylAx, const Vector3d& vtRemDir, - double dSegLen, double dCylHei, double dCylRad) ; -double DiskPlaneLeakDistOrtMot( const Triangle3d& trTria, const Point3d& ptDiscOrig, const Vector3d& vtDiscAx, - const Vector3d& vtMotion, double dCylRad, Point3d& ptContact) ; +double CAvCylinderTriangle( const Point3d& ptCylOrig, const Vector3d& vtCylAx, double dHeigth, double dRad, + const Triangle3d& trTria, const Vector3d& vtMove) ; +double DiskSegmentLeakDistLongMotion( const Point3d& ptDiskCen, double dDiscRad, + const Point3d& ptSeg, const Vector3d& vtSeg, double dSegLen, const Vector3d& vtMove) ; +double DiskTriaInteriorLeakDistLongMot( const Point3d& ptDiskCen, double dDiskRad, + const Triangle3d& trTria, const Vector3d& vtMove) ; +double CylPointLeakDistOrtMotion( const Point3d& ptCylOrig, const Vector3d& vtCylAx, double dCylHei, double dCylRad, + const Point3d& ptP, const Vector3d& vtMove) ; +double DiskSegmentLeakDistOrtMot( const Point3d& ptDiscCen, const Vector3d& vtDiscAx, double dDiscRad, + const Point3d& ptSeg, const Vector3d& vtSeg, double dSegLen, const Vector3d& vtMove) ; +double CylSegmentLeakDistOrtMotion( const Point3d& ptCylOrig, const Vector3d& vtCylAx, double dCylHei, double dCylRad, + const Point3d& ptSeg, const Vector3d& vtSeg, double dSegLen, const Vector3d& vtMove) ; +double DiskPlaneLeakDistOrtMot( const Point3d& ptDiscCen, const Vector3d& vtDiscAx, double dDiscRad, + const Point3d& ptPlane, const Vector3d& vtPlane, + const Vector3d& vtMotion, Point3d& ptContact) ; +// Cono +double CAvTrConeTriangle( const Point3d& ptMinBase, const Vector3d& vtTrConeAx, double dMinBaseR, double dMaxBaseR, + double dTrConeH, const Triangle3d& trTria, const Vector3d& vtMove) ; +double TrConePointLeakDistLongMot( const Point3d& ptMinBase, const Vector3d& vtTrConeAx, double dMinBaseR, double dMaxBaseR, + double dTrConeH, const Point3d& ptP, const Vector3d& vtMove) ; +double TrConeSegmentLeakDistLongMot( const Point3d& ptMinBase, const Vector3d& vtTrConeAx, double dMinBaseR, double dMaxBaseR, + double dTrConeH, const Point3d& ptSeg, const Vector3d& vtSeg, double dSegLen, + const Vector3d& vtMove) ; +double TrConeTriangleInteriorLeakDistLongMot( const Point3d& ptMinBase, const Vector3d& vtTrConeAx, double dMinBaseR, double dMaxBaseR, + double dTrConeH, const Triangle3d& trTria, const Vector3d& vtMove) ; // Funzioni geometriche di base double GetPointLineSqDist( const Point3d& ptP, const Point3d& ptLine, const Vector3d& vtLine) ; double PointPlaneSignedDist( const Point3d& ptP, const Point3d& ptPlane, const Vector3d& vtNorm) ; @@ -56,17 +64,10 @@ double LineLineSqDist( const Point3d& ptP1, const Vector3d& vtD1, const Point3d& double LineSegmentSqDist( const Point3d& ptPLn, const Vector3d& vtDLn, const Point3d& ptPSg, const Vector3d& vtDSg, double dSgLen) ; bool IsPointInsideTriangle( const Point3d& ptP, const Triangle3d& trTria) ; +bool CoplanarDiscTriangleInterferance( const Point3d& ptCen, double dRad, const Triangle3d& trTria) ; bool FindMinDistPar( const Point3d& ptL1, const Point3d& ptL2, const Vector3d& vtV1, const Vector3d& vtV2, double& dU1, double& dU2) ; int SphereLineTangentPoints( const Point3d& ptSpheCen, double dSpheRad, const Point3d& ptSeg, const Vector3d& vtSegDir, double dSegLen, const Vector3d& vtMove, double& dU1, double& dU2) ; - - - - - - - - \ No newline at end of file diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 6736088..49b4931 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/Tool.cpp b/Tool.cpp index 5782277..3ecca21 100644 --- a/Tool.cpp +++ b/Tool.cpp @@ -132,7 +132,7 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR, // Se raggio corner nullo, allora utensile conico if ( dCornR < EPS_SMALL) { - m_nType = CONUSMILL ; + m_nType = CONEMILL ; m_dRCorner = 0 ; return true ; } diff --git a/Tool.h b/Tool.h index 725155c..262a1ae 100644 --- a/Tool.h +++ b/Tool.h @@ -61,10 +61,10 @@ class Tool public : enum ToolType { UNDEF = 0, // Utensile indefinito GEN = 1, // Generico da profilo -> usare SetTool - CYLMILL = 2, // Cilindrica - BALLMILL = 3, // Sferica + CYLMILL = 2, // Cilindrico + BALLMILL = 3, // Sferico BULLNOSEMILL = 4, // Naso di toro - CONUSMILL = 5, // Con parte terminale conica + CONEMILL = 5, // Con parte terminale conica MORTISER = 6, // Mortasatrice CHISEL = 7} ; // Scalpello diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index e672cab..c27a461 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -651,7 +651,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& case Tool::BALLMILL : CylBall_ZDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; - case Tool::CONUSMILL : + case Tool::CONEMILL : Conus_ZDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; case Tool::MORTISER : @@ -673,7 +673,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& case Tool::BALLMILL : CylBall_ZPerp( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; - case Tool::CONUSMILL : + case Tool::CONEMILL : Conus_ZPerp( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; case Tool::MORTISER : @@ -695,7 +695,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& case Tool::BALLMILL : CylBall_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; - case Tool::CONUSMILL : + case Tool::CONEMILL : Conus_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; } } @@ -721,7 +721,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& case Tool::BALLMILL : CylBall_XYDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; - case Tool::CONUSMILL : + case Tool::CONEMILL : Conus_XYDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; case Tool::MORTISER : @@ -742,7 +742,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& case Tool::BALLMILL : CylBall_XYPerp( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; - case Tool::CONUSMILL : + case Tool::CONEMILL : Conus_XYPerp( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; case Tool::MORTISER : @@ -763,7 +763,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& case Tool::BALLMILL : CylBall_XYMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; - case Tool::CONUSMILL : + case Tool::CONEMILL : Conus_XYMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; } @@ -788,7 +788,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& case Tool::BALLMILL : CylBall_Drilling( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; - case Tool::CONUSMILL : + case Tool::CONEMILL : Conus_Drilling( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; case Tool::MORTISER : @@ -809,7 +809,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& case Tool::BALLMILL : CylBall_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; - case Tool::CONUSMILL : + case Tool::CONEMILL : Conus_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ; break ; case Tool::MORTISER :