diff --git a/VolZmap.h b/VolZmap.h index 3268f3f..1e0e933 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -269,11 +269,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& CylFrame, double dL, double dR, bool bTapO, bool bTapL, Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2) ; - bool IntersZLineCylinder( const Point3d& ptLine, - const Point3d& ptBase, const Point3d& ptTop, double dCylR, - double& dInfZ, double& dSupZ) ; bool IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& ptLineSt, - const Frame3d& CircFrame, double dSqRad, double dLongMvLen, double dOrtMvLen, + const Frame3d& CircFrame, double dRad, double dLongMvLen, double dOrtMvLen, bool bTapLow, bool bTapUp, Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2) ; bool IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, diff --git a/VolZmapCalculus.cpp b/VolZmapCalculus.cpp index 157ba9c..6c5798b 100644 --- a/VolZmapCalculus.cpp +++ b/VolZmapCalculus.cpp @@ -808,111 +808,6 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, return true ; } -//---------------------------------------------------------------------------- -bool -VolZmap::IntersZLineCylinder( const Point3d& ptLine, - const Point3d& ptBase, const Point3d& ptTop, double dCylR, - double& dInfZ, double& dSupZ) -{ - // NB: Le coordinate sono espresse nel sistema griglia - // La funzione restituisce true in caso di intersezione, false altrimenti. - - double dSqRad = dCylR * dCylR ; - - // Cilindro verticale - if ( AreSamePointXYApprox( ptBase, ptTop)) { - - // Intersezione - if ( SqDistXY( ptLine, ptBase) < dSqRad) { - dInfZ = min( ptBase.z, ptTop.z) ; - dSupZ = max( ptBase.z, ptTop.z) ; - return true ; - } - - // Non vi è intersezione - else - return false ; - } - - // Cilindro non verticale - else { - - // Studio delle simmetrie - Point3d ptS = ( ptBase.z < ptTop.z ? ptBase : ptTop) ; - Point3d ptE = ( ptBase.z < ptTop.z ? ptTop : ptBase) ; - - Vector3d vtAx = ptE - ptS ; - - Vector3d vtV1( vtAx.x, vtAx.y, 0) ; - - double dLenXY = vtV1.LenXY() ; - double dSZ = ptS.z ; - double dEZ = ptE.z ; - double dDeltaZ = dEZ - dSZ ; - - Vector3d vtL( ptLine.x - ptS.x, ptLine.y - ptS.y, 0) ; - - // vtV1 e vtV2 formano un sistema ortonormale - // sul piano e insieme a ptSxy formano un sistema - // di riferimento bidimensionale - vtV1.Normalize() ; - Vector3d vtV2 = vtV1 ; - vtV2.Rotate( Z_AX, 90) ; - - double dLen = vtAx.Len() ; - - // Sono seno e coseno dell'angolo complementare - // rispetto a quello formato dal vettore movimento - // con il piano, per questo motivo si ha dCos con - // dDeltaZ e dSin con dLenXY - double dCos = dDeltaZ / dLen ; - double dSin = dLenXY / dLen ; - - // Nuove coordinate piane del punto - double dLocX1 = vtL * vtV1 ; - double dLocX2 = vtL * vtV2 ; - - double dSqRoot = sqrt( dSqRad - dLocX2 * dLocX2) ; - double dX1_0 = dCos * dSqRoot ; - - if ( dLocX1 >= - dX1_0 && dLocX1 <= dLenXY + dX1_0 && - abs( dLocX2) < dCylR) { - - // Minimi - if ( dLocX1 < dX1_0) { - - double dDotS = vtAx * ( ptS - ORIG) ; - // Qui usiamo ptLine perché servono coordinate griglia - dInfZ = ( dDotS - vtAx.x * ptLine.x - vtAx.y * ptLine.y) / vtAx.z ; - } - else { - - double dZ0 = - dSin * dSqRoot ; - - dInfZ = dSZ + dZ0 + ( dLocX1 - dX1_0) * dDeltaZ / dLenXY ; - } - - // Massimi - if ( dLocX1 <= dLenXY - dX1_0) { - - double dZ0 = dSin * dSqRoot ; - - dSupZ = dSZ + dZ0 + ( dLocX1 + dX1_0) * dDeltaZ / dLenXY ; - } - else { - - double dDotE = vtAx * ( ptE - ORIG) ; - // Qui usiamo ptLine perché servono coordinate griglia - dSupZ = ( dDotE - vtAx.x * ptLine.x - vtAx.y * ptLine.y) / vtAx.z ; - } - - return true ; - } - - return false ; - } -} - //---------------------------------------------------------------------------- bool VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, @@ -1115,24 +1010,23 @@ VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, } //---------------------------------------------------------------------------- +// NB: L'origine del sistema di riferimento deve essere +// nel centro della circonferenza di base, la cui traslazione obliqua +// genera il cilindro ellittico, e l'asse z deve essere l'asse +// di simmetria di tale circonferenza. +// La funzione restituisce true in caso di intersezione, false altrimenti. +// NB: dSqRad è il quadrato del raggio della circonferenza la cui +// traslazione obliqua genera il cilindro ellittico, dLongMvLen e +// dOrtMvLen sono rispettivamente le lunghezze delle proiezioni del +// movimento su z e x del sistema di riferimento CircFrame. bool VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& ptLineSt, - const Frame3d& CircFrame, double dSqRad, double dLongMvLen, double dOrtMvLen, + const Frame3d& CircFrame, double dRad, double dLongMvLen, double dOrtMvLen, bool bTapLow, bool bTapUp, Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2) { - // NB: L'origine del sistema di riferimento deve essere - // nel centro della circonferenza di base, la cui traslazione obliqua - // genera il cilindro ellittico, e l'asse z deve essere l'asse - // di simmetria di tale circonferenza. - // La funzione restituisce true in caso di intersezione, false altrimenti. - // NB: dSqRad è il quadrato del raggio della circonferenza la cui - // traslazione obliqua genera il cilindro ellittico, dLongMvLen e - // dOrtMvLen sono rispettivamente le lunghezze delle proiezioni del - // movimento su z e x del sistema di riferimento CircFrame. - - double dObCoef = dOrtMvLen / dLongMvLen ; - double dSqCoef = dObCoef * dObCoef ; + // Quadrato del raggio + double dSqRad = dRad * dRad ; // Punto e vettore individuanti la retta Point3d ptP = ptLineSt ; Vector3d vtV = vtLineDir ; @@ -1152,7 +1046,7 @@ VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& Point3d ptOLsCirc( dOrtMvLen, 0, dLongMvLen) ; ptInt1 = ptP - ( ptP.z / vtV.z) * vtV ; ptInt2 = ptP - ( ( ptP.z - dLongMvLen) / vtV.z) * vtV ; - double dSafeSqRad = dSqRad - 2 * sqrt( dSqRad) * EPS_SMALL ; + double dSafeSqRad = dSqRad - 2 * dRad * EPS_SMALL ; if ( ( ptInt1 - ORIG).SqLenXY() < dSafeSqRad && ( ptInt2 - ptOLsCirc).SqLenXY() < dSafeSqRad) { vtN1 = Z_AX ; @@ -1169,10 +1063,18 @@ VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& vector vdCoef(3) ; vector vdRoots ; + // Coefficiente angolare della retta di movimento nel + // piano ZX del sistema di riferimento del movimento + // e suo quadrato + double dObCoef = dOrtMvLen / dLongMvLen ; + double dSqCoef = dObCoef * dObCoef ; // Setto i coeficienti dell'equazione - vdCoef[0] = dSqCoef * ptP.z * ptP.z + ptP.x * ptP.x + ptP.y * ptP.y - 2 * dObCoef * ptP.z * ptP.x - dSqRad ; - vdCoef[1] = 2 * ( dSqCoef * vtV.z * ptP.z + vtV.x * ptP.x + vtV.y * ptP.y - dObCoef * ( vtV.z * ptP.x + vtV.x * ptP.z)) ; - vdCoef[2] = dSqCoef * vtV.z * vtV.z + vtV.x * vtV.x + vtV.y * vtV.y - 2 * dObCoef * vtV.z * vtV.x ; + vdCoef[0] = dSqCoef * ptP.z * ptP.z + ptP.x * ptP.x + ptP.y * ptP.y + - 2 * dObCoef * ptP.z * ptP.x - dSqRad ; + vdCoef[1] = 2 * ( dSqCoef * vtV.z * ptP.z + vtV.x * ptP.x + vtV.y * ptP.y + - dObCoef * ( vtV.z * ptP.x + vtV.x * ptP.z)) ; + vdCoef[2] = dSqCoef * vtV.z * vtV.z + vtV.x * vtV.x + vtV.y * vtV.y + - 2 * dObCoef * vtV.z * vtV.x ; // Numero di soluzioni int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; @@ -1180,31 +1082,13 @@ VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& // coincidenti) oppure nessuna o infinite se la la retta // appartiene alla superficie - // Sperimentale - if ( nRoot == 0 || nRoot == 1) { - if ( abs( vtV.z) > EPS_ZERO) { - ptInt1 = ptP - ( ptP.z / vtV.z) * vtV ; - ptInt2 = ptP + ( ( dLongMvLen - ptP.z) / vtV.z) * vtV ; - if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dSqRad && - ( ptInt2.x - dOrtMvLen) * ( ptInt2.x - dOrtMvLen) + ptInt2.y * ptInt2.y < dSqRad) { - ptInt1.ToGlob( CircFrame) ; - ptInt2.ToGlob( CircFrame) ; - vtN1 = Z_AX ; - vtN2 = - Z_AX ; - vtN1.ToGlob( CircFrame) ; - vtN2.ToGlob( CircFrame) ; - return true ; - } - // Nessuna intersezione - else - return false ; - } - // Nessuna intersezione - else - return false ; - }// Fine sperimentale - - if ( nRoot == 2) { + // Se ci sono intersezioni con i tappi o l'equazione + // degenera in una di primo grado, le eventuali + // soluzioni sono già state trovate. + if ( nRoot == 0 || nRoot == 1) + return false ; + // Due soluzioni trovate + else if ( nRoot == 2) { // Flag per i tappi double dEpsLow = ( bTapLow ? - EPS_SMALL : EPS_SMALL) ; double dEpsUp = ( bTapUp ? EPS_SMALL : - EPS_SMALL) ; @@ -1285,8 +1169,9 @@ VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& ptInt2.ToGlob( CircFrame) ; vtN1.ToGlob( CircFrame) ; vtN2.ToGlob( CircFrame) ; + return true ; } - return true ; + return false ; } //---------------------------------------------------------------------------- diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index ac0007e..297ce42 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -4112,7 +4112,6 @@ VolZmap::CompCyl_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& Frame3d CylFrame ; CylFrame.Set( ptITip, vtV2, vtV3, vtV1) ; // Parametri geometrici di moto e cilindro - double dSqRad = dRad * dRad ; double dLongLen = vtMoveLong.Len() ; double dOrtLen = vtMoveOrt.Len() ; @@ -4192,8 +4191,8 @@ VolZmap::CompCyl_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& } // Cilindro ellittico di punta - if ( IntersLineEllipticalCylinder( Z_AX, ptC, CylFrame, dSqRad, - dLongLen, dOrtLen, bElpsT, bElpsT, ptInt1, ptInt2, vtN1, vtN2)) { + if ( IntersLineEllipticalCylinder( Z_AX, ptC, CylFrame, dRad, dLongLen, dOrtLen, + bElpsT, bElpsT, ptInt1, ptInt2, vtN1, vtN2)) { double dMin, dMax ; Vector3d vtNmin, vtNmax ; if ( ptInt1.z < ptInt2.z) { @@ -4214,8 +4213,8 @@ VolZmap::CompCyl_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& // Cilindro ellittico di base: L'unica differenza rispetto a prima è l'origine // del sistema di riferimento, quindi usiamo lo stesso sistema sommando a ptC // il vettore che congiunge le due origini. - if ( IntersLineEllipticalCylinder( Z_AX, ptC - dHei * vtV1, CylFrame, dSqRad, - dLongLen, dOrtLen, bElpsB, bElpsB, ptInt1, ptInt2, vtN1, vtN2)) { + if ( IntersLineEllipticalCylinder( Z_AX, ptC - dHei * vtV1, CylFrame, dRad, dLongLen, dOrtLen, + bElpsB, bElpsB, ptInt1, ptInt2, vtN1, vtN2)) { double dMin, dMax ; Vector3d vtNmin, vtNmax ; if ( ptInt1.z < ptInt2.z) { @@ -4250,9 +4249,7 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point // Geometria del cono double dDeltaR = dMaxRad - dMinRad ; - double dSqMaxRad = dMaxRad * dMaxRad ; - double dSqMinRad = dMinRad * dMinRad ; - + // Studio simmetrie Point3d ptI = ( vtToolDir * ( ptE - ptS) > 0 ? ptS : ptE) ; Point3d ptF = ( vtToolDir * ( ptE - ptS) > 0 ? ptE : ptS) ; @@ -4537,8 +4534,8 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point } // Traslazione ellisse di punta - if ( IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dl, ConusFrame, dSqMinRad, - dLongLen, dOrtLen, bElpsT, bElpsT, ptInt1, ptInt2, vtN1, vtN2)) { + if ( IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dl, ConusFrame, dMinRad, dLongLen, dOrtLen, + bElpsT, bElpsT, ptInt1, ptInt2, vtN1, vtN2)) { double dMin, dMax ; Vector3d vtNmin, vtNmax ; if ( ptInt1.z < ptInt2.z) { @@ -4557,8 +4554,8 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point } // Traslazione ellisse di base - if ( IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dL, ConusFrame, dSqMaxRad, - dLongLen, dOrtLen, bElpsB, bElpsB, ptInt1, ptInt2, vtN1, vtN2)) { + if ( IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dL, ConusFrame, dMaxRad, dLongLen, dOrtLen, + bElpsB, bElpsB, ptInt1, ptInt2, vtN1, vtN2)) { double dMin, dMax ; Vector3d vtNmin, vtNmax ; if ( ptInt1.z < ptInt2.z) { @@ -4612,8 +4609,8 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point } // Traslazione ellisse - if ( IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dL, ConusFrame, dSqMaxRad, - dLongLen, dOrtLen, bConeB, bConeB, ptInt1, ptInt2, vtN1, vtN2)) { + if ( IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dL, ConusFrame, dMaxRad, dLongLen, dOrtLen, + bConeB, bConeB, ptInt1, ptInt2, vtN1, vtN2)) { double dMin, dMax ; Vector3d vtNmin, vtNmax ; if( ptInt1.z < ptInt2.z) {