diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index e229ca9..430adc4 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/VolZmapCalculus.cpp b/VolZmapCalculus.cpp index 0768267..157ba9c 100644 --- a/VolZmapCalculus.cpp +++ b/VolZmapCalculus.cpp @@ -1133,48 +1133,66 @@ VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& double dObCoef = dOrtMvLen / dLongMvLen ; double dSqCoef = dObCoef * dObCoef ; - + // Punto e vettore individuanti la retta Point3d ptP = ptLineSt ; Vector3d vtV = vtLineDir ; - // Asse cilindro ellittico Vector3d vtAx( dOrtMvLen, 0, dLongMvLen) ; vtAx.Normalize() ; - + // Se il cilindro ellittico degenera in una superficie, + // non bisogna tagliare + if ( abs( vtAx.z) < EPS_SMALL) + return false ; // Trasformazione delle coordinate ptP.ToLoc( CircFrame) ; vtV.ToLoc( CircFrame) ; + // Retta parallela all'asse del cilindro + if ( AreSameOrOppositeVectorApprox( vtV, vtAx)) { + // Interseco la retta con i piani delle circonferenze + 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 ; + if ( ( ptInt1 - ORIG).SqLenXY() < dSafeSqRad && + ( ptInt2 - ptOLsCirc).SqLenXY() < dSafeSqRad) { + vtN1 = Z_AX ; + vtN2 = - Z_AX ; + ptInt1.ToGlob( CircFrame) ; + ptInt2.ToGlob( CircFrame) ; + vtN1.ToGlob( CircFrame) ; + vtN2.ToGlob( CircFrame) ; + return true ; + } + else + return false ; + } vector vdCoef(3) ; vector vdRoots ; - + // 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 ; - + // Numero di soluzioni int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + // L'equazione ammette o due soluzioni (eventualmente + // coincidenti) oppure nessuna o infinite se la la retta + // appartiene alla superficie - - // Nessuna soluzione - if ( nRoot == 0 || nRoot == 1) { - - if ( abs( vtV.z) > EPS_ZERO) { - + // 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 @@ -1184,91 +1202,73 @@ VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& // Nessuna intersezione else return false ; - } - - double dEpsLow = ( bTapLow ? - EPS_SMALL : EPS_SMALL) ; - double dEpsUp = ( bTapUp ? EPS_SMALL : - EPS_SMALL) ; - - // L'equazione ammette o due soluzioni (eventualmente - // coincidenti) oppure nessuna o infinite se la la retta - // appartiene alla superficie - - Vector3d vtMv( dOrtMvLen, 0, dLongMvLen) ; - + }// Fine sperimentale + if ( nRoot == 2) { - + // Flag per i tappi + double dEpsLow = ( bTapLow ? - EPS_SMALL : EPS_SMALL) ; + double dEpsUp = ( bTapUp ? EPS_SMALL : - EPS_SMALL) ; + // Vettore di movimento + Vector3d vtMv( dOrtMvLen, 0, dLongMvLen) ; + // Punti di intersezione ptInt1 = ptP + vdRoots[0] * vtV ; ptInt2 = ptP + vdRoots[1] * vtV ; - - - if ( ptInt1.z > ptInt2.z) - + // Simmetria del problema + if ( ptInt1.z > ptInt2.z) swap( ptInt1, ptInt2) ; - + // Determino le normali alla superficie nei punti d'intersezione Vector3d vtTest1 = ( ptInt1 - ORIG) - ( ptInt1 - ORIG) * vtAx * vtAx ; Vector3d vtTest2 = ( ptInt2 - ORIG) - ( ptInt2 - ORIG) * vtAx * vtAx ; - - double dX0_1, dX0_2 ; - + double dX0_1, dX0_2 ; if ( vtTest1.x > 0) { - dX0_1 = ( dSqRad - ptInt1.y * ptInt1.y > 0 ? sqrt( dSqRad - ptInt1.y * ptInt1.y) : 0) ; } - else { - + else { dX0_1 = ( dSqRad - ptInt1.y * ptInt1.y > 0 ? - sqrt( dSqRad - ptInt1.y * ptInt1.y) : 0) ; } - Vector3d vtCirc1( - dX0_1, - ptInt1.y, 0) ; Vector3d vtTan1( vtCirc1.y, - vtCirc1.x, 0) ; Vector3d vtCross1 = vtTan1 ^ vtMv ; - + // Vettore 1 vtN1 = ( vtCross1 * vtCirc1 > - EPS_ZERO ? vtCross1 : - vtCross1) ; - if ( vtTest2.x > 0) { - dX0_2 = ( dSqRad - ptInt2.y * ptInt2.y > 0 ? sqrt( dSqRad - ptInt2.y * ptInt2.y) : 0) ; } - else { - + else { dX0_2 = ( dSqRad - ptInt2.y * ptInt2.y > 0 ? - sqrt( dSqRad - ptInt2.y * ptInt2.y) : 0) ; } - Vector3d vtCirc2( - dX0_2, - ptInt2.y, 0) ; Vector3d vtTan2( vtCirc2.y, - vtCirc2.x, 0) ; Vector3d vtCross2 = vtTan2 ^ vtMv ; - + // Vettore 2 vtN2 = ( vtCross2 * vtCirc2 > - EPS_ZERO ? vtCross2 : - vtCross2) ; + // Normalizzo i vettori + vtN1.Normalize() ; + vtN2.Normalize() ; - - - if ( ptInt1.z < dLongMvLen + dEpsUp) { - + // Studio le soluzioni: se ua è fuori dalla regione + // ammissibile, vuol dire che la retta esce da un tappo. + if ( ptInt1.z < dLongMvLen + dEpsUp) { if ( ptInt1.z > + dEpsLow) { - + // ptInt2 è sul tappo if ( ptInt2.z > dLongMvLen + dEpsUp) { - ptInt2 = ptP + ( ( dLongMvLen - ptP.z) / vtV.z) * vtV ; vtN2 = - Z_AX ; } } else { - - if ( ptInt2.z > dLongMvLen + dEpsUp) { - + // Entrambe le soluzioni sono su un tappo + if ( ptInt2.z > dLongMvLen + dEpsUp) { ptInt1 = ptP - ( ptP.z / vtV.z) * vtV ; ptInt2 = ptP + ( ( dLongMvLen - ptP.z) / vtV.z) * vtV ; - vtN1.Set( 0, 0, 1) ; vtN2.Set( 0, 0, -1) ; - if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y > dSqRad && ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y > dSqRad) - return false ; } - else if ( ptInt2.z > dEpsLow) { - + // La prima soluzione è sul tappo + else if ( ptInt2.z > dEpsLow) { ptInt1 = ptP - ( ptP.z / vtV.z) * vtV ; vtN1.Set( 0, 0, 1) ; } @@ -1279,18 +1279,13 @@ VolZmap::IntersLineEllipticalCylinder( const Vector3d& vtLineDir, const Point3d& else return false ; - // Riporto le coordinate nel sistema di riferimento - // griglia + // Riporto le coordinate nel sistema + // di riferimento griglia. ptInt1.ToGlob( CircFrame) ; ptInt2.ToGlob( CircFrame) ; - vtN1.ToGlob( CircFrame) ; - vtN2.ToGlob( CircFrame) ; - - vtN1.Normalize() ; - vtN2.Normalize() ; + vtN2.ToGlob( CircFrame) ; } - return true ; } @@ -1340,12 +1335,20 @@ VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLine ptP.x > dLenX - EPS_SMALL)) return false ; // Controllo sulle facce 5 e 6 - Vector3d vtW( 0, dLenX, dDeltaZ) ; + /*Vector3d vtW( 0, dLenX, dDeltaZ) ; vtW.Normalize() ; Vector3d vtU = vtV - vtV.y * Y_AX - vtV * vtW * vtW ; if ( vtU.Len() < EPS_ZERO && ( ptP.z * dLenX < dDeltaZ * ptP.x + dLenX * EPS_SMALL || ptP.z * dLenX > dDeltaZ * ptP.x + dLenX * ( dLenY - EPS_SMALL))) + return false ;*/ + double dDotObV = abs( vtV * vtOb) ; + Vector3d vtP1 = ptFacet135 - ptP ; + Vector3d vtP2 = ptFacet246 - ptP ; + double dP1 = abs ( vtP1 * vtOb) ; + double dP2 = abs ( vtP2 * vtOb) ; + if ( dDotObV < EPS_ZERO && + ( dP1 < EPS_SMALL || dP2 < EPS_SMALL)) return false ; // Ricerca intersezioni con le facce diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index 0f85b95..ac0007e 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -4110,10 +4110,7 @@ VolZmap::CompCyl_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& Vector3d vtV2 = vtMoveOrt ; vtV2.Normalize() ; Vector3d vtV3 = vtV1 ^ vtV2 ; Frame3d CylFrame ; CylFrame.Set( ptITip, vtV2, vtV3, vtV1) ; - - // Verifica se movimento lungo Z - bool bMoveOnZ = ( vtMove.IsZplus() || vtMove.IsZminus()) ; - + // Parametri geometrici di moto e cilindro double dSqRad = dRad * dRad ; double dLongLen = vtMoveLong.Len() ; @@ -4175,7 +4172,8 @@ VolZmap::CompCyl_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& } // Poliedro interno - if ( ! bMoveOnZ && IntersLineMyPolyhedron( ptC, Z_AX, CylFrame, dOrtLen, 2 * dRad, dHei, dLongLen, ptInt1, ptInt2, vtN1, vtN2)) { + if ( IntersLineMyPolyhedron( ptC, Z_AX, CylFrame, dOrtLen, 2 * dRad, dHei, + dLongLen, ptInt1, ptInt2, vtN1, vtN2)) { double dMin, dMax ; Vector3d vtNmin, vtNmax ; if ( ptInt1.z < ptInt2.z) { @@ -4194,8 +4192,8 @@ VolZmap::CompCyl_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& } // Cilindro ellittico di punta - if ( ! bMoveOnZ && IntersLineEllipticalCylinder( Z_AX, ptC, CylFrame, dSqRad, - dLongLen, dOrtLen, bElpsT, bElpsT, ptInt1, ptInt2, vtN1, vtN2)) { + if ( IntersLineEllipticalCylinder( Z_AX, ptC, CylFrame, dSqRad, + dLongLen, dOrtLen, bElpsT, bElpsT, ptInt1, ptInt2, vtN1, vtN2)) { double dMin, dMax ; Vector3d vtNmin, vtNmax ; if ( ptInt1.z < ptInt2.z) { @@ -4216,7 +4214,7 @@ 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 ( ! bMoveOnZ && IntersLineEllipticalCylinder( Z_AX, ptC - dHei * vtV1, CylFrame, dSqRad, + if ( IntersLineEllipticalCylinder( Z_AX, ptC - dHei * vtV1, CylFrame, dSqRad, dLongLen, dOrtLen, bElpsB, bElpsB, ptInt1, ptInt2, vtN1, vtN2)) { double dMin, dMax ; Vector3d vtNmin, vtNmax ; @@ -4271,10 +4269,7 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point Vector3d vtMove = ptF - ptI ; Vector3d vtMvLong = ( vtMove * vtToolDir) * vtToolDir ; Vector3d vtMvOrt = vtMove - vtMvLong ; - - // Verifica se movimento lungo Z - bool bMoveOnZ = ( vtMove.IsZplus() || vtMove.IsZminus()) ; - + // Terna destrorsa e unitaria Vector3d vtV1 = vtToolDir ; Vector3d vtV2 = vtMvOrt ; vtV2.Normalize() ; @@ -4542,7 +4537,7 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point } // Traslazione ellisse di punta - if ( ! bMoveOnZ && IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dl, ConusFrame, dSqMinRad, + if ( IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dl, ConusFrame, dSqMinRad, dLongLen, dOrtLen, bElpsT, bElpsT, ptInt1, ptInt2, vtN1, vtN2)) { double dMin, dMax ; Vector3d vtNmin, vtNmax ; @@ -4562,8 +4557,8 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point } // Traslazione ellisse di base - if ( ! bMoveOnZ && IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dL, ConusFrame, dSqMaxRad, - dLongLen, dOrtLen, bElpsB, bElpsB, ptInt1, ptInt2, vtN1, vtN2)) { + if ( IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dL, ConusFrame, dSqMaxRad, + dLongLen, dOrtLen, bElpsB, bElpsB, ptInt1, ptInt2, vtN1, vtN2)) { double dMin, dMax ; Vector3d vtNmin, vtNmax ; if ( ptInt1.z < ptInt2.z) { @@ -4617,8 +4612,8 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point } // Traslazione ellisse - if ( ! bMoveOnZ && IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dL, ConusFrame, dSqMaxRad, - dLongLen, dOrtLen, bConeB, bConeB, ptInt1, ptInt2, vtN1, vtN2)) { + if ( IntersLineEllipticalCylinder( Z_AX, ptC - vtV1 * dL, ConusFrame, dSqMaxRad, + dLongLen, dOrtLen, bConeB, bConeB, ptInt1, ptInt2, vtN1, vtN2)) { double dMin, dMax ; Vector3d vtNmin, vtNmax ; if( ptInt1.z < ptInt2.z) { @@ -4694,7 +4689,7 @@ VolZmap::CompPar_Milling( unsigned int nGrid, double dLenX, double dLenY, double vtU2.Normalize() ; Vector3d vtU3 = vtU1 ^ vtU2 ; - Point3d ptOMotion = ( vtMv * vtU1 > 0 ? ptDiagMin : ptDiagMin + vtMv) + vtU3 * ( 0.5 * dLenZ) ; + Point3d ptOMotion = ( bSymmetry2 ? ptDiagMin : ptDiagMin + vtMv) + vtU3 * ( 0.5 * dLenZ) ; MotionFrame.Set( ptOMotion, vtU2, vtU3, vtU1) ;