//---------------------------------------------------------------------------- // EgalTech 2015-2016 //---------------------------------------------------------------------------- // File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 // Contenuto : Implementazione della classe Volume Zmap (tre griglie) // // // // Modifiche : 22.01.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "CurveLine.h" #include "VolZmap.h" #include "GeoConst.h" #include "IntersLineSurfTm.h" #include "\EgtDev\Include\EgtNumUtils.h" using namespace std ; // ------------------------- OPERAZIONI SU INTERVALLI -------------------------------------------------------------------------------------- //---------------------------------------------------------------------------- bool VolZmap::SubtractIntervals( unsigned int nGrid, unsigned int nI, unsigned int nJ, double dMin, double dMax) { // Controllo che dMin e dMax non siano quasi coincidenti if ( abs( dMax - dMin) < EPS_SMALL) return true ; // Controllo che il numero di griglia sia entro i limiti if ( nGrid < 0 || nGrid > 2) return false ; // Controllo che dMin < dMax if ( dMin > dMax) swap( dMin, dMax) ; // Controllo che indici nI, nJ siano entro i limiti if ( nI < 0 && nI >= m_nVNx[nGrid] && nJ < 0 && nJ >= m_nVNy[nGrid]) return false ; // Calcolo nPos unsigned int nPos = nJ * m_nVNx[nGrid] + nI ; // O nJ*m_Nx + nI + 1 ? /* Non serve: se size == 0 non entra nel ciclo // Se il dexel è vuoto non succede niente if ( m_TriZValues[nGrid][nPos].size() == 0) return true ; */ // Ciclo sugli intervalli del singolo dexel bool bModified = false ; unsigned int i = 0 ; while ( i + 1 < m_TriZValues[nGrid][nPos].size()) { // Casi: // Intervallo da sottrarre è tutto a sinistra di quello corrente, non vi è intersezione if ( m_TriZValues[nGrid][nPos][i] > dMax - EPS_SMALL) { ; } // Intersezione else if ( m_TriZValues[nGrid][nPos][i + 1] > dMax + EPS_SMALL) { // L'intervallo corrente corrente viene limitato a sinistra if ( m_TriZValues[nGrid][nPos][i] > dMin - EPS_SMALL) { bModified = true ; m_TriZValues[nGrid][nPos][i] = dMax ; } // L'intervallo si divide in due intervalli else { bModified = true ; m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() + 2) ; for ( size_t j = m_TriZValues[nGrid][nPos].size() - 1 ; j >= i + 3 ; -- j) m_TriZValues[nGrid][nPos][j] = m_TriZValues[nGrid][nPos][j - 2] ; m_TriZValues[nGrid][nPos][i + 1] = dMin ; m_TriZValues[nGrid][nPos][i + 2] = dMax ; i = i + 2 ; } } else { // L'intervallo corrente viene eliminato if ( m_TriZValues[nGrid][nPos][i] > dMin - EPS_SMALL) { bModified = true ; for ( unsigned int j = i ; j < m_TriZValues[nGrid][nPos].size() - 2 ; ++ j) m_TriZValues[nGrid][nPos][j] = m_TriZValues[nGrid][nPos][j + 2] ; m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() - 2) ; i = i - 2 ; } // L'intervallo corrente viene limitato a destra else if ( m_TriZValues[nGrid][nPos][i + 1] > dMin + EPS_SMALL) { bModified = true ; m_TriZValues[nGrid][nPos][i + 1] = dMin ; } // L'intervallo da sottrarre è tutto a destra di quello corrente, non vi è intersezione else { ; } } i = i + 2 ; } // Se eseguita modifica, imposto ricalcolo della grafica if ( bModified) m_OGrMgr.Reset() ; return true ; } //---------------------------------------------------------------------------- bool VolZmap::SubtractIntervals( unsigned int nGrid, const Point3d & ptP, double dMin, double dMax) { // Controllo che il numero di griglia sia entro i limiti. if ( nGrid < 0 || nGrid > 2) return false ; // ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame) Point3d ptPL = ptP ; ptPL.ToLoc( m_MapFrame[nGrid]) ; double dX, dY, dZ ; // Coordinate di ptPL nel sistema intrinseco double dhMin, dhMax ; // Altezze dMin e dMax RIESPRESSE nel sistema intrinseco (dMin e dMax sono altezze rispetto a ptP) dX = ptPL.x ; dY = ptPL.y ; dZ = ptPL.z ; dhMin = dZ + dMin ; dhMax = dZ + dMax ; // Cerco il punto della griglia più vicino double integerPartX = floor( dX / m_dStep) ; double integerPartY = floor( dY / m_dStep) ; unsigned int i = static_cast (integerPartX) ; // Indici del punto di griglia più vicino. unsigned int j = static_cast (integerPartY) ; // i = 0, 1, ..., m_Nx - 1 ; j = 0, 1, ..., m_Ny - 1 ; // Controllo che gli indici ottenuti siano nella griglia: // se sono dentro la griglia chiamo l'altra subtract if ( i >= 0 && i < m_nVNx[nGrid] && j >= 0 && j < m_nVNy[nGrid]) return SubtractIntervals( nGrid, i, j, dhMin, dhMax) ; // altrimenti non succede niente else return true ; } //---------------------------------------------------------------------------- bool VolZmap::AddIntervals( unsigned int nGrid, unsigned int nI, unsigned int nJ, double dMin, double dMax) { // Controllo che dMin e dMax non siano quasi coincidenti if ( abs( dMax - dMin) < EPS_SMALL) return true ; // Controllo che il numero di griglia sia entro i limiti if ( nGrid < 0 || nGrid > 2) return false ; // Controllo che indici nI, nJ siano entro i limiti if ( nI < 0 && nI >= m_nVNx[nGrid] && nJ < 0 && nJ >= m_nVNy[nGrid]) return false ; // Calcolo nPos unsigned int nPos = nJ * m_nVNx[nGrid] + nI ; // Controllo che dMin < dMax swap( dMin, dMax) ; // Se spillone vuoto if ( m_TriZValues[nGrid][nPos].size() == 0) { m_TriZValues[nGrid][nPos].resize( 2) ; m_TriZValues[nGrid][nPos][0] = dMin ; m_TriZValues[nGrid][nPos][1] = dMax ; if ( dMax > m_dVMaxZ[nGrid]) m_dVMinZ[nGrid] = dMax ; if ( dMin < m_dVMinZ[nGrid]) m_dVMinZ[nGrid] = dMin ; m_OGrMgr.Reset() ; return true ; } // Ciclo sugli intervalli dello spillone bool bModified = false ; unsigned int i = 0 ; while ( i + 1 < m_TriZValues[nGrid][nPos].size()) { // Eventuale aggiustamento di intervalli sovrapposti if ( i > 0) { if ( m_TriZValues[nGrid][nPos][i] < m_TriZValues[nGrid][nPos][i - 1] + EPS_SMALL) { // Se l'intervallo corrente non è contenuto totalmente si esegue l'istruzione successiva if ( m_TriZValues[nGrid][nPos][i - 1] < m_TriZValues[nGrid][nPos][i + 1] + EPS_SMALL) m_TriZValues[nGrid][nPos][i - 1] = m_TriZValues[nGrid][nPos][i + 1] ; for ( unsigned int j = i ; j < m_TriZValues[nGrid][nPos].size() - 2 ; ++ j) m_TriZValues[nGrid][nPos][j] = m_TriZValues[nGrid][nPos][j + 2] ; m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() - 2) ; i = i - 2 ; } } // Caso in cui devo aggiungere un intervallo a sinistra dell'intervallo corrente if ( m_TriZValues[nGrid][nPos][i] > dMax + EPS_SMALL) { bModified = true ; m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() + 2) ; for ( size_t j = m_TriZValues[nGrid][nPos].size() - 1 ; j >= i + 2 ; -- j) m_TriZValues[nGrid][nPos][j] = m_TriZValues[nGrid][nPos][j - 2] ; m_TriZValues[nGrid][nPos][i] = dMin ; m_TriZValues[nGrid][nPos][i + 1] = dMax ; i = i + 2 ; } // Casi d'intersezione: else if ( m_TriZValues[nGrid][nPos][i + 1] > dMax - EPS_SMALL) { // Se l'intervallo da aggiungere sconfina a sinistra modifico il minimo dell'intervalo corrente if ( m_TriZValues[nGrid][nPos][i] > dMin - EPS_SMALL) { bModified = true ; m_TriZValues[nGrid][nPos][i] = dMin ; } } else { // Se l'intervallo corrente è tutto contenuto nell'intervallo da aggungere modifico gli estremi if ( m_TriZValues[nGrid][nPos][i] > dMin + EPS_SMALL) { bModified = true ; m_TriZValues[nGrid][nPos][i] = dMin ; m_TriZValues[nGrid][nPos][i + 1] = dMax ; } // Se l'intervallo da aggiungere sconfina a destra modifico il massimo dell'intervallo corrente else if ( m_TriZValues[nGrid][nPos][i + 1] > dMin - EPS_SMALL) { bModified = true ; m_TriZValues[nGrid][nPos][i + 1] = dMax ; } else { // Aggiungo intervallo a destra dell'ultimo intervallo if ( i == m_TriZValues[nGrid][nPos].size() - 2) { bModified = true ; m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() + 2) ; m_TriZValues[nGrid][nPos][i + 2] = dMin ; m_TriZValues[nGrid][nPos][i + 3] = dMax ; i = i + 2 ; } } } i = i + 2 ; } // se eseguita modifica, imposto ricalcolo della grafica if ( bModified) { m_OGrMgr.Reset() ; if ( dMax > m_dVMaxZ[nGrid]) m_dVMinZ[nGrid] = dMax ; if ( dMin < m_dVMinZ[nGrid]) m_dVMinZ[nGrid] = dMin ; } return true ; } //---------------------------------------------------------------------------- bool VolZmap::AddIntervals( unsigned int nGrid, const Point3d & ptP, double dMin, double dMax) { // Controllo che il numero di griglia sia entro i limiti. if ( nGrid < 0 || nGrid > 2) return false ; // ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame) Point3d ptPL = ptP ; ptPL.ToLoc( m_MapFrame[nGrid]) ; double dX, dY, dZ ; // Coordinate di ptPL nel sistema intrinseco double dhMin, dhMax ; // Altezze dMin e dMax RIESPRESSE nel sistema intrinseco (dMin e dMax sono altezze rispetto a ptP) dX = ptPL.x ; dY = ptPL.y ; dZ = ptPL.z ; dhMin = dZ + dMin ; dhMax = dZ + dMax ; // Cerco il punto della griglia più vicino double integerPartX = floor( dX / m_dStep) ; double integerPartY = floor( dY / m_dStep) ; unsigned int i = static_cast (integerPartX) ; // Indici del punto di griglia più vicino. unsigned int j = static_cast (integerPartY) ; // i = 0, 1, ..., m_Nx - 1 ; j = 0, 1, ..., m_Ny - 1 // Controllo che gli indici ottenuti siano nella griglia: // se sono dentro la griglia chiamo l'altra add if ( i >= 0 && i < m_nVNx[nGrid] && j >= 0 && j < m_nVNy[nGrid]) return AddIntervals( nGrid, i, j, dhMin, dhMax) ; else // altrimenti non succede niente return false ; } // ------------------------- LAVORAZIONI -------------------------------------------------------------------------------------- //---------------------------------------------------------------------------- bool VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Point3d& ptPe, const Vector3d& vtDe) { // Controllo sull'effettiva esisenza del movimento if ( AreSamePointApprox( ptPs, ptPe) && AreSameVectorApprox( vtDs, vtDe)) return true ; // Punti nei sistemi di riferimento intrinseci dello Zmap Point3d ptLs[3] ; Point3d ptLe[3] ; ptLs[0] = ptPs ; ptLs[0].ToLoc( m_MapFrame[0]) ; ptLe[0] = ptPe ; ptLe[0].ToLoc( m_MapFrame[0]) ; if ( m_nMapNum > 1) { ptLs[1].x = ptLs[0].y ; ptLs[1].y = ptLs[0].z ; ptLs[1].z = ptLs[0].x ; ptLs[2].x = ptLs[0].z ; ptLs[2].y = ptLs[0].x ; ptLs[2].z = ptLs[0].y ; ptLe[1].x = ptLe[0].y ; ptLe[1].y = ptLe[0].z ; ptLe[1].z = ptLe[0].x ; ptLe[2].x = ptLe[0].z ; ptLe[2].y = ptLe[0].x ; ptLe[2].z = ptLe[0].y ; } else { ptLs[1].x = 0 ; ptLs[1].y = 0 ; ptLs[1].z = 0 ; ptLs[2].x = 0 ; ptLs[2].y = 0 ; ptLs[2].z = 0 ; ptLe[1].x = 0 ; ptLe[1].y = 0 ; ptLe[1].z = 0 ; ptLe[2].x = 0 ; ptLe[2].y = 0 ; ptLe[2].z = 0 ; } // Vettori nei sistemi di riferimento intrinseci dello Zmap Vector3d vtLs [3] ; Vector3d vtLe [3] ; vtLs[0] = vtDs ; vtLs[0].ToLoc( m_MapFrame[0]) ; vtLe[0] = vtDe ; vtLe[0].ToLoc( m_MapFrame[0]) ; if ( m_nMapNum > 1) { vtLs[1].x = vtLs[0].y ; vtLs[1].y = vtLs[0].z ; vtLs[1].z = vtLs[0].x ; vtLs[2].x = vtLs[0].z ; vtLs[2].y = vtLs[0].x ; vtLs[2].z = vtLs[0].y ; vtLe[1].x = vtLe[0].y ; vtLe[1].y = vtLe[0].z ; vtLe[1].z = vtLe[0].x ; vtLe[2].x = vtLe[0].z ; vtLe[2].y = vtLe[0].x ; vtLe[2].z = vtLe[0].y ; } else { vtLs[1].x = 0 ; vtLs[1].y = 0 ; vtLs[1].z = 0 ; vtLs[2].x = 0 ; vtLs[2].y = 0 ; vtLs[2].z = 0 ; vtLe[1].x = 0 ; vtLe[1].y = 0 ; vtLe[1].z = 0 ; vtLe[2].x = 0 ; vtLe[2].y = 0 ; vtLe[2].z = 0 ; } // Ciclo sulle mappe for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) { // Normalizzo i vettori vtLs[i].Normalize() ; vtLe[i].Normalize() ; // Direzione utensile costante: pura traslazione if ( AreSameVectorApprox( vtLs[i], vtLe[i])) { // Proiezione dei vettori sulle rispettive griglie Vector3d vtLsXY( vtLs[i].x, vtLs[i].y, 0) ; // Versore utensile parallelo all'asse Z if ( vtLsXY.SqLen() < EPS_SMALL * EPS_SMALL) { Vector3d vtMove = ptLe[i] - ptLs[i] ; vtMove.Normalize() ; // Foratura if ( vtMove.SqLenXY() < EPS_SMALL) { // Utensile generico if ( m_nToolType == 0) GenTool_ZDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ; // Fresa cilindrica o sferica else if ( m_nToolType == 1 || m_nToolType == 2) CylBall_ZDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ; // Fresa conica else if ( m_nToolType == 4) Conus_ZDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ; } // Fresatura con vettore movimento perpendicolare all'utensile else if ( abs( vtMove.z) < EPS_SMALL) { // Utensile generico if ( m_nToolType == 0) GenTool_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; // Fresa cilindrica o sferica else if ( m_nToolType == 1 || m_nToolType == 2) CylBall_ZPerp( i, ptLs[i], ptLe[i], vtLs[i]) ; // Fresa conica else if ( m_nToolType == 4) Conus_ZPerp( i, ptLs[i], ptLe[i], vtLs[i]) ; } // Fresatura con vettore movimento generico rispetto all'utensile else { // Utensile generico if ( m_nToolType == 0) GenTool_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; // Fresa cilindrica o sferica else if ( m_nToolType == 1 || m_nToolType == 2) CylBall_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; // Fresa conica else Conus_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; } } // Versore utensile nel piano else if ( abs( vtLs[i].z) < EPS_SMALL) { Vector3d vtMove = ptLe[i] - ptLs[i] ; vtMove.Normalize() ; Vector3d vtMLong = ( vtMove * vtLs[i]) * vtLs[i] ; Vector3d vtMOrt = vtMove - vtMLong ; double dSqLOrt = vtMOrt.SqLen() ; // Foratura if ( dSqLOrt < EPS_SMALL * EPS_SMALL) { // Utensile generico if ( m_nToolType == 0) GenTool_Drilling( i, ptLs[i], ptLe[i], vtLs[i]) ; // Fresa cilindrica o sferica else if ( m_nToolType == 1 || m_nToolType == 2) CylBall_XYDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ; // Fresa conica else Conus_XYDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ; } // Fresatura con vettore movimento perpendicolare all'utensile else if ( 1 - dSqLOrt < EPS_SMALL * EPS_SMALL) { // Utensile generico if ( m_nToolType == 0) GenTool_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ; // Fresa cilindrica o sferica else if ( m_nToolType == 1 || m_nToolType == 2) CylBall_XYPerp( i, ptLs[i], ptLe[i], vtLs[i]) ; // Fresa conica else if ( m_nToolType == 4) Conus_XYPerp( i, ptLs[i], ptLe[i], vtLs[i]) ; } // Fresatura con vettore movimento generico rispetto all'utensile else { // Utensile generico if ( m_nToolType == 0) GenTool_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ; // Fresa cilindrica o sferica else if ( m_nToolType == 1 || m_nToolType == 2) CylBall_XYMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; // Altri utensili else if ( m_nToolType == 4) Conus_XYMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; } } // Versore utensile con direzione generica else { Vector3d vtMove = ptLe[i] - ptLs[i] ; vtMove.Normalize() ; Vector3d vtMLong = ( vtMove * vtLs[i]) * vtLs[i] ; Vector3d vtMOrt = vtMove - vtMLong ; double dSqLOrt = vtMOrt.SqLen() ; // Foratura if ( dSqLOrt < EPS_SMALL * EPS_SMALL) { // Utensile generico if ( m_nToolType == 0) GenTool_Drilling( i, ptLs[i], ptLe[i], vtLs[i]) ; // Fresa cilindrica e sferica else if ( m_nToolType == 1 || m_nToolType == 2) CylBall_Drilling( i, ptLs[i], ptLe[i], vtLs[i]) ; else if ( m_nToolType == 4) Conus_Drilling( i, ptLs[i], ptLe[i], vtLs[i]) ; } else { // Utensile generico if ( m_nToolType == 0) GenTool_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ; // Fresa cilindrica e sferica else if ( m_nToolType == 1 || m_nToolType == 2) CylBall_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ; else if ( m_nToolType == 4) Conus_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ; } } } else ; // Altri casi al momento non gestiti // return false ; } return true ; } // ---------- VERSORE UTENSILE DERETTO COME Z -------------------------------- // ---------- Cilindro e sfera ----------------------------------------------- //---------------------------------------------------------------------------- bool VolZmap::CylBall_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza utensile Zmap bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; if ( ! bTest) return true ; // Proiezione dei punti sul piano Point3d ptSxy( ptS.x, ptS.y, 0) ; // Parametri geometrici dell'utensile double dStemHeigth = m_dHeight - m_dTipHeight ; double dSqRad = m_dRadius * m_dRadius ; // Punte del gambo Point3d ptTStemS = ptS - vtToolDir * dStemHeigth ; Point3d ptTStemE = ptE - vtToolDir * dStemHeigth ; // Quote estreme del gambo double dMinStemZ = min( min( ptS.z, ptTStemS.z), min( ptE.z, ptTStemE.z)) ; double dMaxStemZ = max( max( ptS.z, ptTStemS.z), max( ptE.z, ptTStemE.z)) ; for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptSxy ; double dSqLen = vtC.SqLen() ; // Se il punto si trova dentro il cerchio taglio if ( dSqLen < dSqRad) // utensile cilindrico if ( m_nToolType == CylindricalMill) SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ) ; // utensile sferico else if ( m_nToolType == BallEndMill) { double dH = sqrt( dSqRad - dSqLen) ; if ( vtToolDir.z > 0) SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ) ; else SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH) ; } } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::CylBall_ZPerp( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza utensile Zmap bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; if ( ! bTest) return true ; //Parametri geometrici dell'utensile double dStemHeigth = m_dHeight - m_dTipHeight ; double dSqRad = m_dRadius * m_dRadius ; // Punte del gambo Point3d ptTStemS = ptS - vtToolDir * dStemHeigth ; Point3d ptTStemE = ptE - vtToolDir * dStemHeigth ; // Quote estreme del gambo double dMinStemZ = min( min( ptS.z, ptTStemS.z), min( ptE.z, ptTStemE.z)) ; double dMaxStemZ = max( max( ptS.z, ptTStemS.z), max( ptS.z, ptTStemS.z)) ; // Vettore movimento e sua lunghezza Vector3d vtMove = ptE - ptS ; double dLen = vtMove.LenXY() ; // Definizione di un sistema di riferimento ad hoc Point3d ptSxy( ptS.x, ptS.y, 0) ; Vector3d vtV1 = vtMove ; vtV1.Normalize() ; // se |vtMove| < EPS è un buco con dz = 0 Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptSxy ; double dP1 = vtC * vtV1 ; double dP2 = vtC * vtV2 ; // Utensile cilindrico if ( m_nToolType == CylindricalMill) { // Se il punto cade nella zona di interesse taglio if ( ( dP1 * dP1 + dP2 * dP2 < dSqRad) || ( ( dP1 - dLen) * ( dP1 - dLen) + dP2 * dP2) < dSqRad || ( dP1 > 0 && dP1 < dLen && abs( dP2) < m_dRadius)) SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ) ; } // Utensile sferico else if ( m_nToolType == BallEndMill) { if ( dP1 < 0 && dP1 * dP1 + dP2 * dP2 < m_dRadius * m_dRadius) { double dH = sqrt( dSqRad - dP1 * dP1 - dP2 * dP2) ; if ( vtToolDir.z > 0) SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ) ; else SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH) ; } else if ( dP1 > dLen && ( dP1 - dLen) * ( dP1 - dLen) + dP2 * dP2 < dSqRad) { double dH = sqrt( dSqRad - ( dP1 - dLen) * ( dP1 - dLen) - dP2 * dP2) ; if ( vtToolDir.z > 0) SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ) ; else SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH) ; } else if ( dP1 > - EPS_SMALL && dP1 < dLen + EPS_SMALL && abs( dP2) < m_dRadius) { double dH = sqrt( dSqRad - dP2 * dP2) ; if ( vtToolDir.z > 0) SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ) ; else SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH) ; } } } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::CylBall_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza utensile Zmap bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; if ( ! bTest) return true ; // Parametri geometrici dell'utensile double dStemHeigth = m_dHeight - m_dTipHeight ; double dSqRad = m_dRadius * m_dRadius ; // Studio delle simmetrie Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ; Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ; Point3d ptIT = ptI - vtToolDir * dStemHeigth ; Point3d ptFT = ptF - vtToolDir * dStemHeigth ; Point3d ptIxy( ptI.x, ptI.y, 0) ; // Quote iniziali e finali massime e // minime del gambo dell'utensile e DeltaZ double dZMaxI = max( ptI.z, ptIT.z) ; double dZMaxF = max( ptF.z, ptFT.z) ; double dZMinI = dZMaxI - dStemHeigth ; double dZMinF = dZMaxF - dStemHeigth ; double dDeltaZ = dZMaxF - dZMaxI ; // Vettori caratterizzanti il moto Vector3d vtMove = ptF - ptI ; Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMove.Len() ; double dLenXY = vtMoveXY.LenXY() ; vtMove.Normalize() ; // Parametri per determinare l'ellisse proiettata double dCos = vtToolDir * vtMove ; double dSin = ( abs( dCos) < 1 ? 1 - dCos * dCos : 0) ; double dSemiAxMin = m_dRadius * dCos ; // x1^2 = a^2 - (a / b)^2 x2^2 ; a = r dCos e b = r; double dSqSemiAxMin = dSemiAxMin * dSemiAxMin ; // da cui si ottiene x1^2 = a^2 - dCos^2 x2^2 double dSqRatio = dSqSemiAxMin / dSqRad ; // Definizione di un sistema di riferimento ad hoc Vector3d vtV1, vtV2 ; // Se la lunghezza è troppo piccola lo allungo if ( dLenXY < EPS_SMALL) vtV1 = ( 1 / dLenXY) * vtMoveXY ; else vtV1 = vtMoveXY ; // Normalizzo vtV1 vtV1.Normalize() ; // Definisco vtV2 vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; double dMin, dMax ; for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; double dX1 = vtC * vtV1 ; double dX2 = vtC * vtV2 ; // Se il punto appartiene alla proiezione del volume spazzato valuto massimo e minimo if ( ( dX1 > 0 && dX1 < dLenXY && abs( dX2) < m_dRadius) || ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad || dX1 * dX1 + dX2 * dX2 < dSqRad) { if ( m_nToolType == CylindricalMill) { double dX1_0 = sqrt( dSqRad - dX2 * dX2) ; // Massimo if ( ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad) dMax = dZMaxF ; else dMax = dZMaxI + dDeltaZ * ( dX1 + dX1_0) / dLenXY ; // Minimo if ( dX1 * dX1 + dX2 * dX2 < dSqRad) dMin = dZMinI ; else dMin = dZMinI + dDeltaZ * ( dX1 - dX1_0) / dLenXY ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( m_nToolType == BallEndMill) { double dCylX1_0 = sqrt( dSqRad - dX2 * dX2) ; double dSqRoot = sqrt( dSqRad - dX2 * dX2) ; double dX1_0 = dCos * dSqRoot ; double dH0 = dSin * dSqRoot ; if ( vtToolDir.z > 0) { // Massimo if ( ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad) dMax = dZMaxF ; else dMax = dZMaxI + dDeltaZ * ( dX1 + dCylX1_0) / dLenXY ; // Minimo if ( dX1 < dX1_0) dMin = dZMinI - sqrt( dSqRad - dX1 * dX1 - dX2 * dX2) ; else if ( dX1 < dLenXY + dX1_0) dMin = dZMinI - dH0 + dDeltaZ * ( dX1 - dX1_0) / dLenXY ; else dMin = dZMinF - sqrt( dSqRad - ( dX1 - dLenXY) * ( dX1 - dLenXY) - dX2 * dX2) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else { // Massimo if ( dX1 < - dX1_0) dMax = dZMaxI + sqrt( dSqRad - dX1 * dX1 - dX2 * dX2) ; else if ( dX1 < dLenXY - dX1_0) dMax = dZMaxI + dH0 + dDeltaZ * ( dX1 - dX1_0) / dLenXY ; else dMax = dZMaxF + sqrt( dSqRad - ( dX1 - dLenXY) * ( dX1 - dLenXY) - dX2 * dX2) ; // Minimo if ( dX1 * dX1 + dX2 * dX2 < dSqRad) dMin = dZMinI ; else dMin = dZMinI + dDeltaZ * ( dX2 - dCylX1_0) / dLenXY ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } } } return true ; } // ---------- Coni ----------------------------------------------------------- //---------------------------------------------------------------------------- bool VolZmap::Conus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza utensile Zmap bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; if ( ! bTest) return true ; // Parametri geometrici dell'utensile double dStemHeigth = m_dHeight - m_dTipHeight ; double dMinRad = min( m_dRadius, m_dTipRadius) ; double dMaxRad = max( m_dRadius, m_dTipRadius) ; double dDeltaRad = dMaxRad - dMinRad ; double dSqMinRad = dMinRad * dMinRad ; double dSqMaxRad = dMaxRad * dMaxRad ; // Proiezione delle posizioni sul piano Point3d ptO( ptS.x, ptS.y, 0) ; // Quote massime e minime dell'utensile durante il moto double dZMax = max( max( ptS.z, ptS.z - vtToolDir.z * m_dHeight), max( ptE.z, ptE.z - vtToolDir.z * m_dHeight)) ; double dZMin = min( min( ptS.z, ptS.z - vtToolDir.z * m_dHeight), min( ptE.z, ptE.z - vtToolDir.z * m_dHeight)) ; // Trapano if ( m_dTipRadius < m_dRadius) { // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; double dSqDist = vtC.SqLenXY() ; if ( dSqDist < dSqMinRad) SubtractIntervals( nGrid, i, j, dZMin, dZMax) ; else if ( dSqDist < dSqMaxRad) { double dr = sqrt( dSqDist) ; if ( vtToolDir.z > 0) SubtractIntervals( nGrid, i, j, dZMin + m_dTipHeight * ( dr - dMinRad) / dDeltaRad, dZMax) ; else SubtractIntervals( nGrid, i, j, dZMin, dZMax - m_dTipHeight * ( dr - dMinRad) / dDeltaRad) ; } } } } // Coda di rondine else { // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; double dSqDist = vtC.SqLenXY() ; if ( dSqDist < dSqMinRad) SubtractIntervals( nGrid, i, j, dZMin, dZMax) ; else if ( dSqDist < dSqMaxRad) { double dr = sqrt( dSqDist) ; if ( vtToolDir.z > 0) SubtractIntervals( nGrid, i, j, dZMin, dZMax - dStemHeigth - m_dTipHeight * ( dr - dMinRad) / dDeltaRad) ; else SubtractIntervals( nGrid, i, j, dZMin + dStemHeigth + m_dTipHeight * ( dr - dMinRad) / dDeltaRad, dZMax) ; } } } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::Conus_ZPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza utensile Zmap bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; if ( ! bTest) return true ; // Parametri geometrici dell'utensile double dStemHeigth = m_dHeight - m_dTipHeight ; double dMinRad = min( m_dRadius, m_dTipRadius) ; double dMaxRad = max( m_dRadius, m_dTipRadius) ; double dDeltaRad = dMaxRad - dMinRad ; double dSqMinRad = dMinRad * dMinRad ; double dSqMaxRad = dMaxRad * dMaxRad ; // Quote fondo, punta e fine gambo double dBaseZ = ptS.z ; double dTipZ = ptS.z - m_dHeight * vtToolDir.z ; double dStemZ = ptS.z - dStemHeigth * vtToolDir.z ; double dZ1 = ( m_dRadius > m_dTipRadius ? dBaseZ : dTipZ) ; double dZ2 = ( m_dRadius > m_dTipRadius ? dTipZ : dStemZ) ; double dZ3 = ( m_dRadius > m_dTipRadius ? dStemZ : dTipZ) ; // Sistemi di riferimento sul piano Point3d ptIxy( ptS.x, ptS.y, 0) ; Point3d ptFxy( ptE.x, ptE.y, 0) ; Vector3d vtV1 = ptFxy - ptIxy ; double dLenXY = vtV1.LenXY() ; vtV1.Normalize() ; Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtCI = ptC - ptIxy ; Vector3d vtCF = ptC - ptFxy ; double dSqDistI = vtCI.SqLenXY() ; double dSqDistF = vtCF.SqLenXY() ; double dX1 = vtCI * vtV1 ; double dX2 = vtCI * vtV2 ; if ( dSqDistI < dSqMinRad || dSqDistF < dSqMinRad || ( dX1 > 0 && dX1 < dLenXY && abs( dX2) < dMinRad)) SubtractIntervals( nGrid, i, j, min( dBaseZ, dTipZ), max( dBaseZ, dTipZ)) ; else if ( dSqDistI < dSqMaxRad && dX1 < 0) { double dr = sqrt( dSqDistI) ; SubtractIntervals( nGrid, i, j, min( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad), max( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad)) ; } else if ( dX1 <= dLenXY && abs( dX2) < dMaxRad) { double dr = abs( dX2) ; SubtractIntervals( nGrid, i, j, min( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad), max( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad)) ; } else if ( dSqDistF < dSqMaxRad) { double dr = sqrt( dSqDistF) ; SubtractIntervals( nGrid, i, j, min( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad), max( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad)) ; } } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::Conus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { if ( m_dTipRadius < m_dRadius) Dr_ZMilling( nGrid, ptS, ptE, vtToolDir) ; else Sw_ZMilling( nGrid, ptS, ptE, vtToolDir) ; return true ; } //---------------------------------------------------------------------------- bool VolZmap::Dr_ZMilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza dell'utensile con lo Zmap bool bTest = BoundingBox( nGrid, ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; if ( ! bTest) return true ; // Punti iniziale e finale e proiezione sul piano del punto iniziale Point3d ptI, ptF, ptO ; if ( vtToolDir.z > 0) { ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; } else { ptI = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; ptF = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; } // Raggio minimo e massimo double dMaxRad = max( m_dRadius, m_dTipRadius) ; double dMinRad = min( m_dRadius, m_dTipRadius) ; // Quote iniziale e finale della base dell'utensile e DeltaZ double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; // Vettori di movimento Vector3d vtMove = ptF - ptI ; Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMoveXY.LenXY() ; // Sistema di riferimento sul cono e vertice del cono Vector3d vtV1 = vtToolDir ; Vector3d vtV2 = vtMoveXY ; vtV2.Normalize() ; Vector3d vtV3 = vtV1 ^ vtV2 ; Point3d ptV = ptI - ( m_dHeight + m_dTipHeight * dMinRad / ( dMaxRad - dMinRad)) * vtV1 ; // Apertura del cono e parametri per determinare i piani double dTanAlpha = ( dMaxRad - dMinRad) / m_dTipHeight ; double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; double dCos = dTanAlpha * dRatio ; double dSin = ( abs( dCos) < 1 ? sqrt( 1 - dCos * dCos) : 0) ; double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; // Versori normali e prodotti scalari per per determinare i piani Vector3d vtNs = - ( dTanAlpha / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; Vector3d vtNd = - ( dTanAlpha / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * vtV3 ; Vector3d vtR0 = ptV - ORIG ; double dDots = vtR0 * vtNs ; double dDotd = vtR0 * vtNd ; for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { // Grandezze per determinare la configurazione geometrica dell'utensile double dMin, dMax ; double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; Vector3d vtCf = vtC - vtMoveXY ; Vector3d vtUC = vtC ; vtUC.Normalize() ; Vector3d vtUCf = vtCf ; vtUCf.Normalize() ; double dCCos = vtUC * vtV2 ; double dCCosf = vtUCf * vtV2 ; double dProj = vtC * vtV2 ; Vector3d vtOrt = vtC - dProj * vtV2 ; double dSqDistI = vtC * vtC ; double dSqDistM = vtOrt * vtOrt ; double dSqDistF = vtCf * vtCf ; // Se dentro la zona interessata dalla lavorazione valuto // la tipologia di tale zona if ( ( dProj < 0 && dSqDistI < dMaxRad * dMaxRad) || ( dProj >= 0 && dProj < dLen && dSqDistM < dMaxRad * dMaxRad) || ( dProj >= dLen && dSqDistF < dMaxRad * dMaxRad)) { // Caso vettore utensile equiverso all'asse Z if ( vtToolDir.z > 0) { // Massimi double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; if ( dProj < dLen - dPMaxI) dMax = dZI + ( dDeltaZ / dLen) * ( dProj + dPMaxI) ; else dMax = dZF ; // Minimi if ( dSqDistI < dMinRad * dMinRad) dMin = dZI - m_dHeight ; else { if ( ( vtMove * vtV1) / ( vtMove * vtV2) <= 1 / dTanAlpha) { if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) dMin = dZI - m_dHeight + ( ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; if ( dSqDistM <= dMinSql) dMin = dZI - m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; else if ( dSqDistM < dMaxSql) { if ( vtC * vtV3 > 0) dMin = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; else dMin = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; } } else if ( dCCosf >= dCos) { double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; if ( dSqDistF < dMinRad * dMinRad) dMin = dZI - m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; else dMin = dZF - m_dHeight + ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; } else dMin = dZI - m_dHeight + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; } else { if ( dSqDistI < dMaxRad * dMaxRad) dMin = dZI - m_dHeight + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; else if ( dProj >= dPMaxI && dProj < dPMaxI + dLen) dMin = dZI - m_dHeight + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; } } } // Caso vettore utensile opposto all'asse Z else { // Massimi double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; if ( dSqDistI < dMinRad * dMinRad) dMax = dZI + m_dHeight ; else { if ( - ( vtMove * vtV1) / ( vtMove * vtV2) <= 1 / dTanAlpha) { if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) dMax = dZI + m_dHeight - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; if ( dSqDistM <= dMinSql) dMax = dZI + m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; else if ( dSqDistM < dMaxSql) { if ( vtC * vtV3 > 0) dMax = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; else dMax = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; } } else if ( dCCosf >= dCos) { double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; if ( dSqDistF < dMinRad * dMinRad) dMax = dZI + m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; else dMax = dZF + m_dHeight - ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; } else dMax = dZI + m_dHeight - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; } else { if ( dSqDistI < dMaxRad * dMaxRad) dMax = dZI + m_dHeight - ( ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; else if ( dProj >= dPMaxI && dProj < dPMaxI + dLen) dMax = dZI + m_dHeight - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; } } // Minimi double dPMaxCirc = sqrt( dMaxRad * dMaxRad - dSqDistM) ; if ( dProj > dLen - dPMaxCirc) dMin = dZF ; else dMin = dZI + ( dDeltaZ / dLen) * ( dProj + dPMaxCirc) ; } SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::Sw_ZMilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza dell'utensile con lo Zmap bool bTest = BoundingBox( nGrid, ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; if ( ! bTest) return true ; // Punti iniziale e finale e proiezione sul piano del punto iniziale Point3d ptI, ptF, ptO ; if ( vtToolDir.z > 0) { ptI = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; ptF = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; } else { ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; } Point3d ptICyl = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; double dMaxRad = max( m_dRadius, m_dTipRadius) ; double dMinRad = min( m_dRadius, m_dTipRadius) ; double dDeltaH = m_dHeight - m_dTipHeight ; double dMinZCyl = min( ptICyl.z, ptICyl.z - vtToolDir.z * dDeltaH) ; // Punti contatto cono cilindro Point3d ptIS = ptI - ( m_dHeight - m_dTipHeight) * vtToolDir ; Point3d ptFS = ptF - ( m_dHeight - m_dTipHeight) * vtToolDir ; // Quote iniziali e finali e DeltaZ double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; double dADeltaZ = abs( dDeltaZ) ; double dZIS = ptIS.z ; double dZFS = ptFS.z ; // Vettori di movimento Vector3d vtMove = ptF - ptI ; Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMoveXY.LenXY() ; // Sistema di riferimento sul cono e vertice del cono Vector3d vtV1 = - vtToolDir ; Vector3d vtV2 = vtMoveXY ; vtV2.Normalize() ; Vector3d vtV3 = vtV1 ^ vtV2 ; Point3d ptV = ptI + ( m_dHeight - m_dTipHeight * ( 1 + dMinRad / ( dMaxRad - dMinRad))) * vtV1 ; // Apertura del cono e parametri per determinare i piani double dTanAlpha = ( dMaxRad - dMinRad) / m_dTipHeight ; double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; double dCos = dTanAlpha * dRatio ; double dSin = ( abs( dCos) < 1 ? sqrt( 1- dCos * dCos) : 0) ; double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; // Versori normali e prodotti scalari per per determinare i piani Vector3d vtNp = - ( dTanAlpha / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; Vector3d vtNm = - ( dTanAlpha / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * vtV3 ; Vector3d vtR0 = ptV - ORIG ; double dDotp = vtR0 * vtNp ; double dDotm = vtR0 * vtNm ; // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++j) { double dMin, dMax ; double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; Vector3d vtCf = vtC - vtMoveXY ; Vector3d vtUC = vtC ; Vector3d vtUCf = vtCf ; vtUC.Normalize() ; vtUCf.Normalize() ; double dCCos = vtUC * vtV2 ; double dCCosf = vtUCf * vtV2 ; double dProj = vtC * vtV2 ; Vector3d vtOrt = vtC - dProj * vtV2 ; double dSqDistI = vtC * vtC ; double dSqDistM = vtOrt * vtOrt ; double dSqDistF = vtCf * vtCf ; if ( ( dProj < 0 && dSqDistI < dMaxRad * dMaxRad) || ( dProj >= 0 && dProj < dLen && dSqDistM < dMaxRad * dMaxRad) || ( dProj >= dLen && dSqDistF < dMaxRad * dMaxRad)) { // Caso vettore utensile equiverso all'asse Z if ( vtV1.z < 0) { double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; // Massimi if ( dRatio <= 1 / dTanAlpha) { if ( dSqDistI < dMinRad * dMinRad) dMax = dZIS ; else { if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) dMax = dZIS - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; if ( dSqDistM <= dMinSql) dMax = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; else if ( dSqDistM < dMaxSql) { if ( vtC * vtV3 > 0) dMax = ( dDotp - dX * vtNp.x - dY * vtNp.y) / vtNp.z ; else dMax = ( dDotm - dX * vtNm.x - dY * vtNm.y) / vtNm.z ; } } else if ( dCCosf >= dCos) { double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; if ( dSqDistF < dMinRad * dMinRad) dMax = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; else dMax = dZFS - ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; } else dMax = dZIS - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; } } else { if ( dSqDistI < dMinRad * dMinRad) dMax = dZIS ; else if ( dSqDistI < dMaxRad * dMaxRad) dMax = dZIS - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; else { if ( dProj >= dPMaxI) dMax = dZIS - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; } } // Minimi if ( dSqDistF < dMaxRad * dMaxRad) dMin = dZFS - m_dTipHeight ; else if ( dProj <= dLen - dPMaxI) dMin = dZIS - m_dTipHeight + ( dProj + dPMaxI) * dDeltaZ / dLen ; } // Caso vettore utensile opposto all'asse Z else { double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; // Massimi if ( dSqDistF < dMaxRad * dMaxRad) dMax = dZFS + m_dTipHeight ; else if ( dProj <= dLen - dPMaxI) dMax = dZIS + m_dTipHeight + ( dProj + dPMaxI) * dDeltaZ / dLen ; // Minimi if ( dRatio <= 1 / dTanAlpha) { if ( dSqDistI < dMinRad * dMinRad) dMin = dZIS ; else { if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) dMin = dZIS + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; if ( dSqDistM <= dMinSql) dMin = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; else if ( dSqDistM < dMaxSql) { if ( vtC * vtV3 > 0) dMin = ( dDotp - dX * vtNp.x - dY * vtNp.y) / vtNp.z ; else dMin = ( dDotm - dX * vtNm.x - dY * vtNm.y) / vtNm.z ; } } else if ( dCCosf >= dCos) { double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; if ( dSqDistF < dMinRad * dMinRad) dMin = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; else dMin = dZFS + ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; } else dMin = dZIS + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; } } else { if ( dSqDistI < dMinRad * dMinRad) dMin = dZIS ; else if ( dSqDistI < dMaxRad * dMaxRad) dMin = dZIS + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; else dMin = dZIS + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; } } SubtractIntervals( nGrid, i, j, dMin, dMax) ; } // Parte cilindrica Vector3d vtCyl = ( vtV1.z < 0 ? vtCf : vtC) ; Vector3d vtCylf = ( vtV1.z < 0 ? vtC : vtCf) ; Vector3d vtMot = ( vtV1.z < 0 ? - vtV2 : vtV2) ; double dCylProj = vtCyl * vtMot ; double dCylSqDistI = vtCyl * vtCyl ; double dCylSqDistF = vtCylf * vtCylf ; double dCylSqDistM = ( vtCyl - dCylProj * vtMot) * ( vtCyl - dCylProj * vtMot) ; if ( dCylSqDistI < dMinRad * dMinRad || dCylSqDistF < dMinRad * dMinRad || ( dCylProj > 0 && dCylProj < dLen && dCylSqDistM < dMinRad * dMinRad)) { double dSt = sqrt( dMinRad * dMinRad - dCylSqDistM) ; // Minimi if ( dCylSqDistI < dMinRad * dMinRad ) dMin = dMinZCyl ; else if ( dCylProj >= dSt) dMin = dMinZCyl + ( dCylProj - dSt) * dADeltaZ / dLen ; // Massimi if ( dCylSqDistF < dMinRad * dMinRad) dMax = dMinZCyl + dDeltaH + dADeltaZ ; else if ( dCylProj <= dLen - dSt) dMax = dMinZCyl + dDeltaH + ( dCylProj + dSt) * dADeltaZ / dLen ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } return true ; } // --------- Utensile generico ------------------------------------------------ //---------------------------------------------------------------------------- bool VolZmap::GenTool_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { // Posizioni iniziale e finale dell'utensile Point3d ptI = ptS ; Point3d ptF = ptE ; // vettore movimento Vector3d vtMove = ptE - ptS ; // Settaggio profilo CurveComposite* pToolProfile ; if ( m_ToolArcLineApprox.GetCurveCount() == 0) // Se l'utensile non è stato approssimato uso l'originale pToolProfile = &m_ToolOutline ; else // altrimenti usi l'approssimazione pToolProfile = &m_ToolArcLineApprox ; // Ciclo sulle curve const ICurve* pCurve = pToolProfile->GetFirstCurve() ; while ( pCurve != nullptr) { double dHeight ; int nCurveType = pCurve -> GetType() ; // Caso segmento if ( nCurveType == CRV_LINE) { Point3d ptStart, ptEnd ; pCurve -> GetStartPoint( ptStart) ; pCurve -> GetEndPoint( ptEnd) ; if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { dHeight = abs( ptStart.y - ptEnd.y) ; // Il componente è un cilindro if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { double dRadius = ptStart.x ; CompCyl_ZDrilling( nGrid, ptS, ptE, vtToolDir, dHeight, dRadius) ; } // Il componente è un cono con vettore equiverso a quello dell'utensile else if ( ptStart.x > ptEnd.x) { double dMaxRad = ptStart.x ; double dMinRad = ptEnd.x ; CompConus_ZDrilling( nGrid, ptS, ptE, vtToolDir, dHeight, dMaxRad, dMinRad) ; } // Il componente è un cono con vettore opposto a quello dell'utesile else if ( ptStart.x < ptEnd.x) { double dMaxRad = ptEnd.x ; double dMinRad = ptStart.x ; Point3d ptIn = ptI - vtToolDir * dHeight ; Point3d ptFn = ptIn + vtMove ; CompConus_ZDrilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; } } else dHeight = 0 ; } // Caso arco else if ( nCurveType == CRV_ARC) { // Centro e Punti iniziale e finale del cerchio Point3d ptStart, ptEnd, ptO ; pCurve -> GetStartPoint( ptStart) ; pCurve -> GetEndPoint( ptEnd) ; pCurve -> GetCenterPoint( ptO) ; // Determino il raggio Vector3d vtStRad = ptStart - ptO ; Vector3d vtEnRad = ptEnd - ptO ; double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; // Determino le posizioni iniziale e finale del centrodella sfera Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; Point3d ptOEn = ptOSt + vtMove ; // Eseguo l'asportazione del materiale CompBall_Milling( nGrid, ptOSt, ptOEn, dRadius) ; // aggiorno l'altezza dHeight = abs( ptStart.y - ptEnd.y) ; } // Determino le posizioni iniziale e finale del componente successivo ptI = ptI - vtToolDir * dHeight ; ptF = ptI + vtMove ; // Aggiorno il puntatore pCurve = pToolProfile->GetNextCurve() ; } return true ; } //---------------------------------------------------------------------------- bool VolZmap::GenTool_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { // Posizioni iniziale e finale dell'utensile Point3d ptI = ptS ; Point3d ptF = ptE ; // vettore movimento Vector3d vtMove = ptE - ptS ; // Settaggio profilo CurveComposite* pToolProfile ; if ( m_ToolArcLineApprox.GetCurveCount() == 0) // Se l'utensile non è stato approssimato uso l'originale pToolProfile = &m_ToolOutline ; else // altrimenti usi l'approssimazione pToolProfile = &m_ToolArcLineApprox ; // Ciclo sulle curve const ICurve* pCurve = pToolProfile->GetFirstCurve() ; while ( pCurve != nullptr) { double dHeight ; int nCurveType = pCurve -> GetType() ; // Caso segmento if ( nCurveType == CRV_LINE) { Point3d ptStart, ptEnd ; pCurve -> GetStartPoint( ptStart) ; pCurve -> GetEndPoint( ptEnd) ; if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { dHeight = abs( ptStart.y - ptEnd.y) ; // Il componente è un cilindro if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { double dRadius = ptStart.x ; CompCyl_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius) ; } // Il componente è un cono con vettore equiverso a quello dell'utensile else if ( ptStart.x > ptEnd.x) { double dMaxRad = ptStart.x ; double dMinRad = ptEnd.x ; CompConus_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; } // Il componente è un cono con vettore opposto a quello dell'utensile else if ( ptStart.x < ptEnd.x) { double dMaxRad = ptEnd.x ; double dMinRad = ptStart.x ; Point3d ptIn = ptI - vtToolDir * dHeight ; Point3d ptFn = ptIn + vtMove ; CompConus_ZMilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; } } else dHeight = 0 ; } // Caso arco else if ( nCurveType == CRV_ARC) { // Centro e Punti iniziale e finale del cerchio Point3d ptStart, ptEnd, ptO ; pCurve -> GetStartPoint( ptStart) ; pCurve -> GetEndPoint( ptEnd) ; pCurve -> GetCenterPoint( ptO) ; // Determino il raggio Vector3d vtStRad = ptStart - ptO ; Vector3d vtEnRad = ptEnd - ptO ; double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; // Determino le posizioni iniziale e finale del centrodella sfera Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; Point3d ptOEn = ptOSt + vtMove ; // Eseguo l'asportazione del materiale CompBall_Milling( nGrid, ptOSt, ptOEn, dRadius) ; // aggiorno l'altezza dHeight = abs( ptStart.y - ptEnd.y) ; } // Determino le posizioni iniziale e finale del componente successivo ptI = ptI - vtToolDir * dHeight ; ptF = ptI + vtMove ; // Aggiorno il puntatore pCurve = pToolProfile->GetNextCurve() ; } return true ; } // ---------- VERSORE UTENSILE NEL PIANO XY ---------------------------------- // --------- Cilindro e sfera ------------------------------------------------ //---------------------------------------------------------------------------- bool VolZmap::CylBall_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza utensile Zmap bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; if ( ! bTest) return true ; // Parametri geometrici dell'utensile e quota Z del movimento double dStemHeigth = m_dHeight - m_dTipHeight ; double dSqRad = m_dRadius * m_dRadius ; double dZ = ptS.z ; // Vettore movimento e sua lunghezza Vector3d vtMove = ptE - ptS ; double dLen = vtMove.LenXY() ; // Definizione di un sistema di riferimento ad hoc Point3d ptI = ( vtMove * vtToolDir > 0 ? ptE : ptS) ; Point3d ptF = ( vtMove * vtToolDir > 0 ? ptS - dStemHeigth * vtToolDir : ptE - dStemHeigth * vtToolDir) ; Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; Vector3d vtV1( - vtToolDir.x, - vtToolDir.y, 0) ; vtV1.Normalize() ; Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; for( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; double dP1 = vtC * vtV1 ; double dP2 = vtC * vtV2 ; Vector3d vtBall = ptC - ptFxy ; double dSqLen = vtBall.SqLenXY() ; // Zona lavorata dalla parte cilindrica if ( dP1 > 0 && dP1 < dStemHeigth + dLen && abs( dP2) < m_dRadius ) { double dH = sqrt( dSqRad - dP2 * dP2) ; SubtractIntervals( nGrid, i, j, dZ - dH , dZ + dH) ; } // Se l'utensile è sferico sottraggo anche la punta if ( m_nToolType == BallEndMill) if ( dSqLen < dSqRad) { // LA SOLUZIONE MOMENTANEA è CREARE UTENSILE GENERICO SE LO STELO è PIù CORTO DEL RAGGIO double dH = sqrt( dSqRad - dSqLen) ; SubtractIntervals( nGrid, i, j, dZ - dH, dZ + dH) ; } } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::CylBall_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza utensile Zmap bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; if ( ! bTest) return true ; // Parametri geometrici dell'utensile double dStemHeigth = m_dHeight - m_dTipHeight ; double dSqRad = m_dRadius * m_dRadius ; // Studio simmetrie del problema Point3d ptI = ( ptS.z <= ptE.z ? ptS : ptE) ; Point3d ptF = ( ptS.z <= ptE.z ? ptE : ptS) ; Point3d ptIxy( ptI.x, ptI.y, 0) ; // Quote punti iniziale e finale double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = ptF.z - ptI.z ; // Vettori caratterizzanti il moto Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLenXY = vtMoveXY.LenXY() ; vtMove.Normalize() ; // Sistema di riferimento ad hoc Vector3d vtV1( - vtToolDir.x, - vtToolDir.y, 0) ; vtV1.Normalize() ; Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; if ( vtV2 * vtMove < 0) vtV2 = - vtV2 ; // Vettori e punti determinanti i piani Vector3d vtP = vtMove ; // Se dLen < EPS_SMALL non si usa vtP.Rotate( vtToolDir, 90) ; Point3d ptUp = ptI + m_dRadius * ( vtP.z > 0 ? vtP : - vtP) ; Point3d ptDw = ptI + m_dRadius * ( vtP.z > 0 ? - vtP : vtP) ; Vector3d vtPXY( vtP.x, vtP.y, 0) ; Vector3d vtUp = ptUp - ORIG ; double dDotUp = vtUp * vtP ; Vector3d vtDw = ptDw - ORIG ; double dDotDw = vtDw * vtP ; double dSmall = m_dRadius * vtPXY.LenXY() ; // Parte sferica double dCos = vtMove.z ; // vtMove.z > 0 : ptF.z >= ptI.z double dSin = ( dCos < 1 ? sqrt( 1 - dCos * dCos) : 0) ; double dSemiAxMin = m_dRadius * dCos ; double dInfZ, dSupZ ; for( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; double dP1 = vtC * vtV1 ; double dP2 = vtC * vtV2 ; // Parte cilindrica if ( dP1 > 0 && dP1 < dStemHeigth) { if ( dP2 > - m_dRadius && dP2 < dLenXY + m_dRadius) { // Massimi if ( dP2 < - dSmall + EPS_SMALL) { double dHsq = dSqRad - dP2 * dP2 ; double dH = ( dHsq > 0 ? sqrt( dHsq) : 0) ; dSupZ = dZI + dH ; } else if ( dP2 < dLenXY - dSmall - EPS_SMALL) { dSupZ = ( dDotUp - dX * vtP.x - dY * vtP.y) / vtP.z ; } else { double dH = sqrt( dSqRad - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; dSupZ = dZF + dH ; } // Minimi if ( dP2 < dSmall + EPS_SMALL) { double dHsq = dSqRad - dP2 * dP2 ; double dH = ( dHsq > 0 ? sqrt( dHsq) : 0) ; dInfZ = dZI - dH ; } else if ( dP2 < dLenXY + dSmall - EPS_SMALL) { dInfZ = ( dDotDw - dX * vtP.x - dY * vtP.y) / vtP.z ; } else { double dH = sqrt( dSqRad - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; dInfZ = dZF - dH ; } SubtractIntervals( nGrid, i, j, dInfZ, dSupZ) ; } } // Se l'utensile è ball-end sottraggo la punta if ( m_nToolType == BallEndMill) { if ( ( ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + dP2 * dP2 < dSqRad || ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + ( dP2 - dLenXY) * ( dP2 - dLenXY) < dSqRad || ( dP2 > 0 && dP2 < dLenXY && dP1 < m_dHeight)) && ( dP1 >= dStemHeigth)) { double dSqRoot = sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth)) ; double dP2_0 = dCos * dSqRoot ; double dH0 = dSin * dSqRoot ; double dMin, dMax ; // Massimo if ( dP2 < - dP2_0) dMax = dZI + sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - dP2 * dP2) ; else if ( dP2 < dLenXY - dP2_0) dMax = dZI + dH0 + dDeltaZ * ( dP2 + dP2_0) / dLenXY ; else dMax = dZF + sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; // Minimo if ( dP2 < dP2_0) dMin = dZI - sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - dP2 * dP2) ; else if ( dP2 < dLenXY + dP2_0) dMin = dZI - dH0 + dDeltaZ * ( dP2 - dP2_0) / dLenXY ; else dMin = dZF - sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::CylBall_XYMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { if ( m_nToolType == CylindricalMill) return CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, m_dHeight, m_dRadius) ; else if ( m_nToolType == BallEndMill) { double dHei = m_dHeight - m_dTipHeight ; CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dHei, m_dRadius) ; CompBall_Milling( nGrid, ptS - dHei * vtToolDir, ptE - dHei * vtToolDir, m_dRadius) ; return true ; } else return false ; } // --------- Coni ------------------------------------------------------------ //---------------------------------------------------------------------------- bool VolZmap::Conus_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza utensile Zmap bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; if ( ! bTest) return true ; // Parametri geometrici dell'utensile double dStemHeigth = m_dHeight - m_dTipHeight ; double dMinRad = min( m_dRadius, m_dTipRadius) ; double dMaxRad = max( m_dRadius, m_dTipRadius) ; double dDeltaRad = dMaxRad - dMinRad ; double dSqMinRad = dMinRad * dMinRad ; double dSqMaxRad = dMaxRad * dMaxRad ; // Geometria del moto double dLenXY = ( ptE - ptS).LenXY() ; Point3d ptI = ( vtToolDir * ( ptE - ptS) < 0 ? ptS : ptE) ; double dMatStemLen = ( m_dRadius > m_dTipRadius ? dStemHeigth + dLenXY : dStemHeigth) ; double dSqTipRad = m_dTipRadius * m_dTipRadius ; double dSqRad = m_dRadius * m_dRadius ; // Sistema di riferimento sul piano Vector3d vtV1 = - vtToolDir ; Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; // Proiezione di ptI sul piano Point3d ptIxy( ptI.x, ptI.y, 0) ; // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC ( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; double dX1 = vtC * vtV1 ; double dX2 = vtC * vtV2 ; double dr = m_dRadius + ( dX1 - dMatStemLen) * ( m_dTipRadius - m_dRadius) / m_dTipHeight ; if ( dX1 > 0 && dX1 < dMatStemLen && abs( dX2) < m_dRadius) { double dH = sqrt( dSqRad - dX2 * dX2) ; SubtractIntervals( nGrid, i, j, ptI.z - dH, ptI.z + dH) ; } else if ( dX1 >= dMatStemLen && dX1 < dMatStemLen + m_dTipHeight && abs( dX2) < dr) { double dH = sqrt( dr * dr - dX2 * dX2) ; SubtractIntervals( nGrid, i, j, ptI.z - dH, ptI.z + dH) ; } if ( m_dTipRadius >= m_dRadius) { if ( dX1 >= dMatStemLen + m_dTipHeight && dX1 < dMatStemLen + m_dTipHeight + dLenXY && abs( dX2) < dSqTipRad) { double dH = sqrt( dSqTipRad - dX2 * dX2) ; SubtractIntervals( nGrid, i, j, ptI.z - dH, ptI.z + dH) ; } } } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::Conus_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza utensile Zmap bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; if ( ! bTest) return true ; // Parametri geometrici dell'utensile double dStemHeigth = m_dHeight - m_dTipHeight ; double dMinRad = min( m_dRadius, m_dTipRadius) ; double dMaxRad = max( m_dRadius, m_dTipRadius) ; double dSqTipRad = m_dTipRadius * m_dTipRadius ; double dSqRad = m_dRadius * m_dRadius ; double dDeltaRad = dMaxRad - dMinRad ; double dSqMinRad = dMinRad * dMinRad ; double dSqMaxRad = dMaxRad * dMaxRad ; // Studio delle simmetrie Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ; Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ; // Vettori caratterizzanti il moto Vector3d vtMove = ptF - ptI ; Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMove.Len() ; double dLenXY = vtMoveXY.LenXY() ; // Quote iniziale e finale double dZI = ptI.z ; double dZF = ptF.z ; // Sistema di riferimento sul piano Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; // Primo vettore del riferimento Vector3d vtV1( - vtToolDir.x, - vtToolDir.y, 0) ; vtV1.Normalize() ; Vector3d vtV2 ; // Movimento verticale if ( dLenXY / dLen < EPS_SMALL) { // Secondo vettore del riferimento vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; double dX1 = vtC * vtV1 ; double dX2 = vtC * vtV2 ; double dr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dX1 - dStemHeigth) / m_dTipHeight ; // Parte cilindrica if ( dX1 > 0 && dX1 < dStemHeigth && abs( dX2) < m_dRadius) { double dH = sqrt( dSqRad - dX2 * dX2) ; SubtractIntervals( nGrid, i, j, dZI - dH, dZF + dH) ; } // Parte conica else if ( dX1 >= dStemHeigth && dX1 < m_dHeight && abs( dX2) < dr) { double dH = sqrt( dr * dr - dX2 * dX2) ; SubtractIntervals ( nGrid, i, j, dZI - dH, dZF + dH) ; } } } } else { // Secondo vettore del riferimento Vector3d vtV2 = vtMoveXY ; vtV2.Normalize() ; // Sistema di riferimento per determinare i piani Vector3d vtW1 = ( m_dHeight > m_dTipHeight ? vtV1 : - vtV1) ; Vector3d vtW2 = vtMove ; vtW2.Normalize() ;// Se vtMove non è suff ort a vtW1 vtMove = vtMoveOrt + vtMoveLong e via Vector3d vtW3 = vtW1 ^ vtW2 ; // Altezza cono double dL = dMaxRad * m_dTipHeight / dDeltaRad ; // Vertice del cono iniziale Point3d ptV = ptI - ( m_dHeight > m_dTipHeight ? ( dStemHeigth + dL) * vtW1 : ( dL - m_dHeight) * vtW1) ; // double dCos = vtW2.z ; double dSin = ( dCos < 1 ? sqrt( 1 - dCos * dCos) : 0) ; double dLimXY = dCos * m_dRadius ; double dLimH = dSin * m_dRadius ; double dDeltaZ = ptF.z - ptI.z ; double dMin, dMax ; // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; double dX1 = vtC * vtV1 ; double dX2 = vtC * vtV2 ; double dr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dX1 - dStemHeigth) / m_dTipHeight ; // Parte cilindrica if ( dX1 > 0 && dX1 < dStemHeigth && dX2 > - m_dRadius && dX2 < dLenXY + m_dRadius) { // Massimi if ( dX2 < - dLimXY) dMax = dZI + sqrt( dSqRad - dX2 * dX2) ; else if ( dX2 < dLenXY - dLimXY) dMax = dZI + dLimH + dDeltaZ * ( dX2 + dLimXY) / dLenXY ; else dMax = dZF + sqrt( dSqRad - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; // Minimi if ( dX2 < dLimXY) dMin = dZI + sqrt( dSqRad - dX2 * dX2) ; else if ( dX2 < dLenXY + dLimXY) dMin = dZI - dLimH + dDeltaZ * ( dX2 - dLimXY) / dLenXY ; else dMin = dZF + sqrt( dSqRad - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } // Parte conica else if ( dX1 >= dStemHeigth && dX1 < m_dHeight && dX2 > - dr && dX2 < dLenXY + dr) { double dRadLimXY = dr * dCos ; double dRadLimH = dr * dSin ; // Massimi if ( dX2 < - dRadLimXY) dMax = dZI + sqrt( dr * dr - dX2 * dX2) ; else if ( dX2 < dLenXY - dRadLimXY) dMax = dZI + dRadLimH + dDeltaZ * ( dX2 + dRadLimXY) / dLenXY ; else dMax = dZF + sqrt( dr * dr - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; // Minimi if ( dX2 < dRadLimXY) dMin = dZI + sqrt( dr * dr - dX2 * dX2) ; else if ( dX2 < dLenXY + dRadLimXY) dMin = dZI - dRadLimH + dDeltaZ * ( dX2 - dRadLimXY) / dLenXY ; else dMin = dZF + sqrt( dr * dr - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::Conus_XYMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { double dStemHeigth = m_dHeight - m_dTipRadius ; CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; if ( m_dTipRadius < m_dRadius) { Point3d ptSTip = ptS - dStemHeigth * vtToolDir ; Point3d ptETip = ptE - dStemHeigth * vtToolDir ; CompConus_Milling( nGrid, ptSTip, ptETip, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius) ; } else { Point3d ptSTip = ptS - m_dHeight * vtToolDir ; Point3d ptETip = ptE - m_dHeight * vtToolDir ; CompConus_Milling( nGrid, ptSTip, ptETip, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius) ; } return true ; } // ---------- VERSORE UTENSILE CON ORIENTAZIONE GENERICA --------------------- // ---------- Cilindro e sfera ----------------------------------------------- //---------------------------------------------------------------------------- bool VolZmap::CylBall_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { double dStemHeigth = m_dHeight - m_dRadius ; CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; // Sfera if ( m_nToolType == 2) { Point3d ptSBall = ptS - dStemHeigth * vtToolDir ; Point3d ptEBall = ptE - dStemHeigth * vtToolDir ; CompBall_Milling( nGrid, ptSBall, ptEBall, m_dRadius) ; } return true ; } //---------------------------------------------------------------------------- bool VolZmap::CylBall_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { double dStemHeigth = m_dHeight - m_dTipHeight ; CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; // Sfera if ( m_nToolType == 2) { Point3d ptSBall = ptS - dStemHeigth * vtToolDir ; Point3d ptEBall = ptE - dStemHeigth * vtToolDir ; CompBall_Milling( nGrid, ptSBall, ptEBall, m_dRadius) ; } return true ; } // ---------- Coni ----------------------------------------------------------- //---------------------------------------------------------------------------- bool VolZmap::Conus_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { double dStemHeigth = m_dHeight - m_dRadius ; CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; // Trapano if ( m_dTipRadius < m_dRadius) { Point3d ptSBall = ptS - dStemHeigth * vtToolDir ; Point3d ptEBall = ptE - dStemHeigth * vtToolDir ; CompConus_Drilling( nGrid, ptSBall, ptEBall, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius) ; } else { Point3d ptSBall = ptS - m_dHeight * vtToolDir ; Point3d ptEBall = ptE - m_dHeight * vtToolDir ; CompConus_Drilling( nGrid, ptSBall, ptEBall, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius) ; } return true ; } //---------------------------------------------------------------------------- bool VolZmap::Conus_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { double dStemHeigth = m_dHeight - m_dTipHeight ; CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; // Trapano if ( m_dTipRadius < m_dRadius) { Point3d ptSBall = ptS - dStemHeigth * vtToolDir ; Point3d ptEBall = ptE - dStemHeigth * vtToolDir ; CompConus_Milling( nGrid, ptSBall, ptEBall, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius) ; } else { Point3d ptSBall = ptS - m_dHeight * vtToolDir ; Point3d ptEBall = ptE - m_dHeight * vtToolDir ; CompConus_Milling( nGrid, ptSBall, ptEBall, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius) ; } return true ; } // ---------- Utensile generico ---------------------------------------------- //---------------------------------------------------------------------------- bool VolZmap::GenTool_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { // Posizioni iniziale e finale dell'utensile Point3d ptI = ptS ; Point3d ptF = ptE ; // vettore movimento Vector3d vtMove = ptE - ptS ; // Settaggio profilo CurveComposite* pToolProfile ; if ( m_ToolArcLineApprox.GetCurveCount() == 0) // Se l'utensile non è stato approssimato uso l'originale pToolProfile = & m_ToolOutline ; else // altrimenti usi l'approssimazione pToolProfile = &m_ToolArcLineApprox ; // Ciclo sulle curve const ICurve* pCurve = pToolProfile->GetFirstCurve() ; while ( pCurve != nullptr) { double dHeight ; int nCurveType = pCurve -> GetType() ; // Caso di semento if ( nCurveType == CRV_LINE) { Point3d ptStart, ptEnd ; pCurve -> GetStartPoint( ptStart) ; pCurve -> GetEndPoint( ptEnd) ; if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { dHeight = abs( ptStart.y - ptEnd.y) ; // Il componente è un cilindro if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { double dRadius = ptStart.x ; CompCyl_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius) ; } // Il componente è un cono con vettore equiverso a quello dell'utensile else if ( ptStart.x > ptEnd.x) { double dMaxRad = ptStart.x ; double dMinRad = ptEnd.x ; CompConus_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; } // Il componente è un cono con vettore opposto a quello dell'utensile else if ( ptStart.x < ptEnd.x) { double dMaxRad = ptEnd.x ; double dMinRad = ptStart.x ; Point3d ptIn = ptI - vtToolDir * dHeight ; Point3d ptFn = ptIn + vtMove ; CompConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; } } else dHeight = 0 ; } // Caso arco else if ( nCurveType == CRV_ARC) { // Centro e Punti iniziale e finale del cerchio Point3d ptStart, ptEnd, ptO ; pCurve -> GetStartPoint( ptStart) ; pCurve -> GetEndPoint( ptEnd) ; pCurve -> GetCenterPoint( ptO) ; // Determino il raggio Vector3d vtStRad = ptStart - ptO ; Vector3d vtEnRad = ptEnd - ptO ; double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; // Determino le posizioni iniziale e finale del centrodella sfera Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; Point3d ptOEn = ptOSt + vtMove ; // Eseguo l'asportazione del materiale CompBall_Milling( nGrid, ptOSt, ptOEn, dRadius) ; // aggiorno l'altezza dHeight = abs( ptStart.y - ptEnd.y) ; } // Determino le posizioni iniziale e finale del componente successivo ptI = ptI - vtToolDir * dHeight ; ptF = ptI + vtMove ; // Aggiorno il puntatore pCurve = pToolProfile->GetNextCurve() ; } return true ; } //---------------------------------------------------------------------------- bool VolZmap::GenTool_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { // Posizioni iniziale e finale dell'utensile Point3d ptI = ptS ; Point3d ptF = ptE ; // vettore movimento Vector3d vtMove = ptE - ptS ; // Settaggio profilo CurveComposite* pToolProfile ; if ( m_ToolArcLineApprox.GetCurveCount() == 0) // Se l'utensile non è stato approssimato uso l'originale pToolProfile = &m_ToolOutline ; else // altrimenti usi l'approssimazione pToolProfile = &m_ToolArcLineApprox ; // Ciclo sulle curve const ICurve* pCurve = pToolProfile->GetFirstCurve() ; while ( pCurve != nullptr) { double dHeight ; int nCurveType = pCurve -> GetType() ; // Caso di semento if ( nCurveType == CRV_LINE) { Point3d ptStart, ptEnd ; pCurve -> GetStartPoint( ptStart) ; pCurve -> GetEndPoint( ptEnd) ; if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { dHeight = abs( ptStart.y - ptEnd.y) ; // Il componente è un cilindro if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { double dRadius = ptStart.x ; CompCyl_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius) ; } // Il componente è un cono con vettore equiverso a quello dell'utensile else if ( ptStart.x > ptEnd.x) { double dMaxRad = ptStart.x ; double dMinRad = ptEnd.x ; CompConus_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; } // Il componente è un cono con vettore opposto a quello dell'utensile else if ( ptStart.x < ptEnd.x) { double dMaxRad = ptEnd.x ; double dMinRad = ptStart.x ; Point3d ptIn = ptI - vtToolDir * dHeight ; Point3d ptFn = ptIn + vtMove ; CompConus_Milling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; } } else dHeight = 0 ; } // Caso arco else if ( nCurveType == CRV_ARC) { // Centro e Punti iniziale e finale del cerchio Point3d ptStart, ptEnd, ptO ; pCurve -> GetStartPoint( ptStart) ; pCurve -> GetEndPoint( ptEnd) ; pCurve -> GetCenterPoint( ptO) ; // Determino il raggio Vector3d vtStRad = ptStart - ptO ; Vector3d vtEnRad = ptEnd - ptO ; double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; // Determino le posizioni iniziale e finale del centrodella sfera Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; Point3d ptOEn = ptOSt + vtMove ; // Eseguo l'asportazione del materiale CompBall_Milling( nGrid, ptOSt, ptOEn, dRadius) ; // aggiorno l'altezza dHeight = abs( ptStart.y - ptEnd.y) ; } // Determino le posizioni iniziale e finale del componente successivo ptI = ptI - vtToolDir * dHeight ; ptF = ptI + vtMove ; // Aggiorno il puntatore pCurve = pToolProfile->GetNextCurve() ; } return true ; } // ------------------------- COMPONENTI ELEMENTARI ----------------------------------------------------------------------------- // Asse di simmetria diretto come l'asse Z: FORATURA //---------------------------------------------------------------------------- bool VolZmap::CompCyl_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza con lo Zmap bool bTest = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; if ( ! bTest) return true ; // Proiezione dei punti sul piano Point3d ptSxy( ptS.x, ptS.y, 0) ; // Parametri geometrici dell'utensile double dSqRad = dRad * dRad ; // Punte del gambo Point3d ptTStemS = ptS - vtToolDir * dHei ; Point3d ptTStemE = ptE - vtToolDir * dHei ; // Quote estreme del gambo double dMinStemZ = min( min( ptS.z, ptTStemS.z), min( ptE.z, ptTStemE.z)) ; double dMaxStemZ = max( max( ptS.z, ptTStemS.z), max( ptS.z, ptTStemS.z)) ; // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptSxy ; double dSqLen = vtC.SqLen() ; // Se il punto si trova dentro il cerchio taglio if ( dSqLen < dSqRad) SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ) ; } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::CompConus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza con lo Zmap bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; if ( ! Control) return true ; Point3d ptO( ptS.x, ptS.y, 0) ; double dZMin, dZMax ; double dAngC = dHei / ( dMaxRad - dMinRad) ; double dSqMinRad = dMinRad * dMinRad ; double dSqMaxRad = dMaxRad * dMaxRad ; // Studio delle simmetrie if ( vtToolDir.z > 0) { dZMin = ( ptS.z < ptE.z ? ptS.z - dHei : ptE.z - dHei) ; dZMax = ( ptS.z < ptE.z ? ptE.z : ptS.z) ; } else { dZMin = ( ptS.z < ptE.z ? ptS.z : ptE.z) ; dZMax = ( ptS.z < ptE.z ? ptE.z + dHei : ptS.z + dHei) ; } // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; double dSqDist = vtC * vtC ; if ( dSqDist < dSqMinRad) SubtractIntervals( nGrid, i, j, dZMin, dZMax) ; else if ( dSqDist < dSqMaxRad) { double dr = sqrt( dSqDist) ; if ( vtToolDir.z > 0) SubtractIntervals( nGrid, i, j, dZMin + dAngC * ( dr - dMinRad), dZMax) ; else SubtractIntervals( nGrid, i, j, dZMin, dZMax - dAngC * ( dr - dMinRad)) ; } } return true ; } // Asse di simmetria diretto come l'asse Z: FRESATURA //---------------------------------------------------------------------------- bool VolZmap::CompCyl_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza con lo Zmap bool bTest = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; if ( ! bTest) return true ; // Parametri geometrici double dSqRad = dRad * dRad ; // Studio delle simmetrie Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ; Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ; Point3d ptIT = ptI - vtToolDir * dHei ; Point3d ptFT = ptF - vtToolDir * dHei ; Point3d ptIxy( ptI.x, ptI.y, 0) ; // Quote iniziali e finali massime e // minime del gambo dell'utensile e DeltaZ double dZMaxI = max( ptI.z, ptIT.z) ; double dZMaxF = max( ptF.z, ptFT.z) ; double dZMinI = dZMaxI - dHei ; double dZMinF = dZMaxF - dHei ; double dDeltaZ = dZMaxF - dZMaxI ; // Vettori caratterizzanti il moto Vector3d vtMove = ptF - ptI ; Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMove.Len() ; double dLenXY = vtMoveXY.LenXY() ; vtMove.Normalize() ; // Parametri per determinare l'ellisse proiettata double dCos = vtToolDir * vtMove ; double dSin = ( abs( dCos) < 1 ? 1 - dCos * dCos : 0) ; double dSemiAxMin = dRad * dCos ; // x1^2 = a^2 - (a / b)^2 x2^2 ; a = r dCos e b = r; double dSqSemiAxMin = dSemiAxMin * dSemiAxMin ; // da cui si ottiene x1^2 = a^2 - dCos^2 x2^2 double dSqRatio = dSqSemiAxMin / dSqRad ; // Definizione di un sistema di riferimento ad hoc Vector3d vtV1, vtV2 ; // Se la lunghezza è troppo piccola lo allungo if ( dLenXY < EPS_SMALL) vtV1 = ( 1 / dLenXY) * vtMoveXY ; else vtV1 = vtMoveXY ; // Normalizzo vtV1 vtV1.Normalize() ; // Definisco vtV2 vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; double dMin, dMax ; for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; double dX1 = vtC * vtV1 ; double dX2 = vtC * vtV2 ; // Se il punto appartiene alla proiezione del volume spazzato valuto massimo e minimo if ( ( dX1 > 0 && dX1 < dLenXY && abs( dX2) < dRad) || ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad || dX1 * dX1 + dX2 * dX2 < dSqRad) { double dX1_0 = sqrt( dSqRad - dX2 * dX2) ; // Massimo if ( ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad) dMax = dZMaxF ; else dMax = dZMaxI + dDeltaZ * ( dX1 + dX1_0) / dLenXY ; // Minimo if ( dX1 * dX1 + dX2 * dX2 < dSqRad) dMin = dZMinI ; else dMin = dZMinI + dDeltaZ * ( dX1 - dX1_0) / dLenXY ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::CompConus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) { double dMin, dMax, dPLim, dMLim ; unsigned int nStartI, nStartJ, nEndI, nEndJ ; bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; if ( ! Control) return true ; Point3d ptI = ( vtToolDir * ( ptE - ptS) > 0 ? ptS : ptE) ; Point3d ptF = ( vtToolDir * ( ptE - ptS) > 0 ? ptE : ptS) ; Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; Vector3d vtMLong = ( vtMove * vtToolDir) * vtToolDir ; double dLLong = vtMLong.Len() ; Vector3d vtMOrt = vtMove - vtMLong ; double dLOrt = vtMOrt.Len() ; Vector3d vtV1 = vtToolDir ; Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ; Vector3d vtV3 = vtV1 ^ vtV2 ; double dZI = ptI.z ; double dZTI = ptI.z - vtV1.z * dHei ; double dDeltaZ = ptF.z - ptI.z ; double dDeltaR = dMaxRad - dMinRad ; double dTan = dDeltaR / dHei ; double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; double dCos = dTan * dRatio ; double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; double dDen = sqrt( 1 + dTan * dTan) ; Point3d ptV = ptI - vtV1 * ( dHei * dMaxRad / dDeltaR) ; Vector3d vtNs = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * vtV3 ; Vector3d vtR0 = ptV - ORIG ; double dDots = vtR0 * vtNs ; double dDotd = vtR0 * vtNd ; for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtCI = ptC - ptIxy ; double dSqDI = vtCI.SqLenXY() ; Vector3d vtCF = ptC - ptFxy ; double dSqDF = vtCF.SqLenXY() ; double dIDO = vtCI * vtV3 ; double dIDL = vtCI * vtV2 ; double dIVarCos = dIDL / sqrt( dSqDI) ; double dFDL = vtCF * vtV2 ; double dFVarCos = dFDL / sqrt( dSqDF) ; if ( dSqDI < dMaxRad * dMaxRad || dSqDF < dMaxRad * dMaxRad || (abs( dIDO) < dMaxRad && dIDL > 0 && dIDL < dLOrt)) { // Caso dTan > 1 / dRatio if ( dRatio > 1 / dTan) { // Limiti nella direzione positiva di vtV1 if ( dSqDF < dMaxRad * dMaxRad) dPLim = dZI + dDeltaZ ; else dPLim = dZI + ( dIDL + sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; // Limiti nella direzione negativa di vtV1 if ( dSqDI < dMinRad * dMinRad) dMLim = dZTI ; else if ( dSqDI < dMaxRad * dMaxRad) dMLim = dZTI + ( sqrt( dSqDI) - dMinRad) * ( dZI - dZTI) / dDeltaR ; else dMLim = dZI + ( dIDL - sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; } else { // Limiti nella direzione positiva di vtV1 if ( dSqDF < dMaxRad * dMaxRad) dPLim = dZI + dDeltaZ ; else dPLim = dZI + ( dIDL + sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; // Limiti nella direzione negativa di vtV1 if ( dSqDI < dMinRad * dMinRad) dMLim = dZTI ; else if ( dSqDI >= dMinRad * dMinRad && dSqDI < dMaxRad * dMaxRad && dIVarCos < dCos) dMLim = dZTI + ( sqrt( dSqDI) - dMinRad) * ( dZI - dZTI) / dDeltaR ; else if ( dSqDI >= dMinRad * dMinRad && dIVarCos >= dCos && dFVarCos < dCos && abs( dIDO) < dMaxRad * dSin) { // da qui if ( dIDO > - dMaxRad * dSin && dIDO <= - dMinRad * dSin) dMLim = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; else if ( dIDO > - dMinRad * dSin && dIDO < dMinRad * dSin) dMLim = dZTI + ( dIDL - sqrt( dMinRad * dMinRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; else if ( dIDO >= dMinRad * dSin && dIDO < dMaxRad * dSin) dMLim = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; // a qui } else if ( dFVarCos >= dCos) { if ( dSqDF < dMinRad * dMinRad) dMLim = dZTI + ( dIDL - sqrt( dMinRad * dMinRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; else dMLim = dZTI + dDeltaZ + ( sqrt( dSqDF) - dMinRad) * ( dZI - dZTI) / dDeltaR ; } else dMLim = dZI + ( dIDL - sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; } dMin = min( dPLim, dMLim) ; dMax = max( dPLim, dMLim) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } return true ; } // Asse di simmetria con orientazione generica: FORATURA //---------------------------------------------------------------------------- bool VolZmap::CompCyl_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad) { double dMin, dMax; unsigned int nStartI, nEndI, nStartJ, nEndJ ; bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; if ( ! Control) return true ; // Studio delle simmetrie Vector3d vtMove = ptE - ptS ; Point3d ptI = ( vtMove * vtToolDir > 0 ? ptE : ptS) ; Point3d ptF = ( vtMove * vtToolDir > 0 ? ptS - dHei * vtToolDir : ptE - dHei * vtToolDir) ; if ( ptI.z > ptF.z) { Point3d ptTemp = ptI ; ptI = ptF ; ptF = ptTemp ; } double dDeltaZ = ptF.z - ptI.z ; double dZI = ptI.z ; // Definizione Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; Vector3d vtCyl = ptF - ptI ; double dLen = sqrt( vtCyl * vtCyl) ; Vector3d vtCylVer( 0, 0, vtCyl.z) ; double dLVer = abs( vtCyl.z) ; Vector3d vtCylOri( vtCyl.x, vtCyl.y, 0) ; double dLOri = vtCylOri.LenXY() ; double dCos = dLVer / dLen ; // Coseno dell'angolo formato da vtCyl con l'asse Z. double dSin = dLOri / dLen ; // Seno dell'angolo formato da vtCyl con l'asse Z. double dSemiMin = dRad * dCos ; double dSqRad = dRad * dRad ; // Definizione del sistema di riferimento nel piano Vector3d vtU1 = vtCylOri ; if ( vtU1.LenXY() < EPS_SMALL) { double dLenVector = sqrt(vtCyl.x * vtCyl.x + vtCyl.y * vtCyl.y) ; vtU1 = ( 1 + dLenVector) / dLenVector * vtU1 ; } vtU1.Normalize() ; Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; // Definizione piani Vector3d vtV = vtMove ; vtV.Normalize() ; Vector3d vtRI = ptI - ORIG ; double dDotI = vtRI * vtV ; Vector3d vtRF = ptF - ORIG ; double dDotF = vtRF * vtV ; for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtCI = ptC - ptIxy ; Vector3d vtCF = ptC - ptFxy ; double dProjI1 = vtCI * vtU1 ; double dProjI2 = vtCI * vtU2 ; double dProjF1 = vtCF * vtU1 ; double dProjF2 = vtCF * vtU2 ; if ( dProjI1 > - dCos * sqrt( dSqRad - dProjI2 * dProjI2) && dProjI1 < dLOri + dCos * sqrt( dSqRad - dProjI2 * dProjI2) && dProjI2 * dProjI2 < dSqRad) { // Massimi if ( dProjI1 < dLOri - dCos * sqrt( dSqRad - dProjI2 * dProjI2)) { double dZ0 = dSin * sqrt( dSqRad - dProjI2 * dProjI2) ; double dI10 = - dCos * sqrt( dSqRad - dProjI2 * dProjI2) ; dMax = dZI + dZ0 + ( dProjI1 - dI10) * dDeltaZ / dLOri ; } else dMax = ( dDotF - vtV.x * dX - vtV.y *dY) / vtV.z ; // Minimi if ( dProjI1 < dCos * sqrt( dSqRad - dProjI2 * dProjI2)) dMin = ( dDotI - vtV.x * dX - vtV.y *dY) / vtV.z ; else { double dZ0 = - dSin * sqrt( dSqRad - dProjI2 * dProjI2) ; double dI10 = dCos * sqrt( dSqRad - dProjI2 * dProjI2) ; dMin = dZI + dZ0 + ( dProjI1 - dI10) * dDeltaZ / dLOri ; } SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::CompConus_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) { double dMin, dMax ; unsigned int nStartI, nStartJ, nEndI, nEndJ ; bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; if ( ! Control) return true ; Vector3d vtMove = ptE - ptS ; double dLen = vtMove.Len() ; Vector3d vtMZ( 0, 0, vtMove.z) ; double dLVer = abs( vtMove.z) ; Vector3d vtMXY( vtMove.x, vtMove.y, 0) ; double dLOri = vtMXY.LenXY() ; double dSin = dLOri / dLen ; double dCos = dLVer / dLen ; double dSemiMinR = dMaxRad * dCos ; double dSemiMinr = dMinRad * dCos ; double dSqMaxRad = dMaxRad * dMaxRad ; // Sistema di riferimento sul cono Vector3d vtV1 = vtToolDir ; // controllare qui e negli altri coni che le proiezioni non siano troppo piccole FORSE CONVIENE FARE I CONTI CON VTMOVE NORMALIZZATO (QUESTO IN TUTTI I MOVIMENTI) double dCoef23 = ( vtV1.z > 0 ? 1 : - 1) ; double dCoef21 = - dCoef23 * vtV1.z ; // vtV1.z := vtV1 * Z_AX Vector3d vtV2 = dCoef21 * vtV1 + dCoef23 * Z_AX ; vtV2.Normalize() ; Vector3d vtV3 = vtV1 ^ vtV2 ; // Simmetrie del problema riguardanti il cono Point3d ptCBot = ( vtV1 * vtMove > 0 ? ptS : ptE) ; Point3d ptCTip = ptCBot - dHei * vtV1 ; double dDeltaR = dMaxRad - dMinRad ; double dTan = dDeltaR / dHei ; double dL = ( ( dMaxRad * dHei) / dDeltaR) ; double dl = dL - dHei ; Point3d ptV = ptCBot - vtV1 * dL ; // Simmetrie del problema riguardanti il cilinidro Point3d ptCylI = ( ptS.z < ptE.z ? ptS : ptE) ; Point3d ptCylF = ( ptS.z < ptE.z ? ptE : ptS) ; double dDeltaZ = ptCylF.z - ptCylI.z ; double dZCylI = ptCylI.z ; // Piani cono Vector3d vtR0B = ptCBot - ORIG ; double dDotB = vtR0B * vtV1 ; Vector3d vtR0T = ptCTip - ORIG ; double dDotT = vtR0T * vtV1 ; // Piani cilindro Vector3d vtR0I = ptCylI - ORIG ; double dDotI = vtR0I * vtV1 ; Vector3d vtR0F = ptCylF - ORIG ; double dDotF = vtR0F * vtV1 ; // Punti sul piano Point3d ptCylIxy( ptCylI.x, ptCylI.y, 0) ; Point3d ptCBotxy( ptCBot.x, ptCBot.y, 0) ; // Riferimenti sul piano Vector3d vtU1( ptCylF.x - ptCylI.x, ptCylF.y - ptCylI.y, 0) ; vtU1.Normalize() ; Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; Vector3d vtW1( vtV1.x, vtV1.y, 0) ; vtW1.Normalize() ; Vector3d vtW2 = vtW1 ; vtW2.Rotate( Z_AX, 90) ; // Sistema di riferimento del cono Frame3d ConusFrame ; ConusFrame.Set( ptV, vtV1, vtV2, vtV3) ; Frame3d GridFrame ; GridFrame.Set( ORIG, X_AX, Y_AX, Z_AX) ; // Ciclo for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptCylIxy ; double dPCyl1 = vtC * vtU1 ; double dPCyl2 = vtC * vtU2 ; // Parte cilindrica if ( dPCyl2 * dPCyl2 < dSqMaxRad && dPCyl1 > - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad) && dPCyl1 < dLOri + dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad)) { // Massimi if ( dPCyl1 < dLOri - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad)) { double dZ0 = dSin * sqrt( dSqMaxRad - dPCyl2 * dPCyl2) ; double dP0 = - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad) ; dMax = dZCylI + dZ0 + ( dPCyl1 - dP0) * dDeltaZ / ( dLOri) ; } else dMax = ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z ; // Minimi if ( dPCyl1 < dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad)) dMin = ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z ; else { double dZ0 = - dSin * sqrt( dSqMaxRad - dPCyl2 * dPCyl2) ; double dP0 = dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad) ; dMin = dZCylI + dZ0 + ( dPCyl1 - dP0) * dDeltaZ / ( dLOri) ; } SubtractIntervals( nGrid, i, j, dMin, dMax) ; } // Parte conica Vector3d vtD = Z_AX ; ptC.LocToLoc( GridFrame, ConusFrame) ; vtD.LocToLoc( GridFrame, ConusFrame) ; std::vector vdCoef(3); std::vector vdRoots; vdCoef[0] = ( dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z) ; vdCoef[1] = 2 * ( dTan * dTan * ptC.x * vtD.x - ptC.y * vtD.y - ptC.z * vtD.z) ; vdCoef[2] = dTan * dTan * vtD.x * vtD.x - vtD.y * vtD.y - vtD.z * vtD.z ; int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; if ( nRoot == 1) { Point3d ptR1 = ptC + vdRoots[0] * vtD ; if ( ptR1.x >= dl && ptR1.x < dL) { ptR1.LocToLoc( ConusFrame, GridFrame) ; dMin = min( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x >= 0 && ptR1.x < dl) { dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } else if ( nRoot == 2) { Point3d ptR1 = ptC + vdRoots[0] * vtD ; Point3d ptR2 = ptC + vdRoots[1] * vtD ; if ( ptR1.x > ptR2.x) { Point3d ptTemp = ptR1 ; ptR1 = ptR2 ; ptR2 = ptTemp ; } if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { ptR2.LocToLoc( ConusFrame, GridFrame) ; dMin = min( ptR2.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR2.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { ptR2.LocToLoc( ConusFrame, GridFrame) ; dMin = min( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { ptR1.LocToLoc( ConusFrame, GridFrame) ; ptR2.LocToLoc( ConusFrame, GridFrame) ; dMin = min( ptR1.z, ptR2.z) ; dMax = max( ptR1.z, ptR2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { ptR1.LocToLoc( ConusFrame, GridFrame) ; dMin = min( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } } return true ; } // Asse di simmetria con orientazione generica: FRESATURA //---------------------------------------------------------------------------- bool VolZmap::CompCyl_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dRad) { double dMin, dMax ; unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza utensile Zmap bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; if ( ! Control) return true ; Point3d ptI ; Point3d ptF ; Vector3d vtV1 ; // Studio delle simmetrie if ( vtToolDir.z < 0) { vtV1 = - vtToolDir ; ptI = ( vtV1 * ( ptE - ptS) > 0 ? ptS + dHei * vtV1 : ptE + dHei * vtV1) ; ptF = ( vtV1 * ( ptE - ptS) > 0 ? ptE + dHei * vtV1 : ptS + dHei * vtV1) ; } else { vtV1 = vtToolDir ; ptI = ( vtV1 * ( ptE - ptS) > 0 ? ptS : ptE) ; ptF = ( vtV1 * ( ptE - ptS) > 0 ? ptE : ptS) ; } Point3d ptIT = ptI - vtV1 * dHei ; Point3d ptFT = ptF - vtV1 * dHei ; // Definizione di un sintema di riferimento nel piano // Ocio che |V1| sia maggiore di EPS_SMALL Vector3d vtU1( - vtV1.x, - vtV1.y, 0) ; vtU1.Normalize() ; Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; Vector3d vtMove = ptF - ptI ; Vector3d vtMLong = ( vtMove * vtV1) * vtV1 ; Vector3d vtMOrt = vtMove - vtMLong ; // Parametri geometrici dell'utensile // e della traiettoria double dCos = vtV1.z ; double dSin = vtV1.LenXY() ; double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = ptIT.z - ptI.z ; double dL = dSin * dHei ; double dLen = vtMove.Len() ; double dLLong = vtMLong.Len() ; double dLOrt = vtMOrt.Len() ; double dCoef = dLOrt / dLLong ; double dAng = atan( 1 / dCoef) ; double dSqRad = dRad * dRad ; double dSemiAxMin = dCos * dRad ; // vtV1, vtV2 e vtV3 definiscono gli assi dei sistemi di riferimento intrinseci Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ; Vector3d vtV3 = vtV1 ^ vtV2 ; Frame3d GridFrame ; GridFrame.Set( ORIG, X_AX, Y_AX, Z_AX) ; Frame3d CylFrame ; CylFrame.Set( ptI, vtV1, vtV2, vtV3) ; Frame3d FCylFrame ; FCylFrame.Set( ptF, vtV1, vtV2, vtV3) ; Frame3d TCylFrame ; TCylFrame.Set( ptIT, vtV1, vtV2, vtV3) ; Frame3d FTCylFrame ; FTCylFrame.Set( ptFT, vtV1, vtV2, vtV3) ; // Altri punti notevoli Point3d ptIPlus = ptI + dRad * vtV3 ; Point3d ptIMinus = ptI - dRad * vtV3 ; Point3d ptFPlus = ptIPlus + vtMove ; Point3d ptFMinus = ptIMinus + vtMove ; Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; // Grandezze per la definizione dei piani Vector3d vtRI = ptI - ORIG ; double dDotI = vtV1 * vtRI ; Vector3d vtRF = ptF - ORIG ; double dDotF = vtV1 * vtRF ; Vector3d vtRIT = ptIT - ORIG ; double dDotIT = vtV1 * vtRIT ; Vector3d vtRFT = ptFT - ORIG ; double dDotFT = vtV1 * vtRFT ; Vector3d vtRIPlus = ptIPlus - ORIG ; Vector3d vtRIMinus = ptIMinus - ORIG ; Vector3d vtRFPlus = ptFPlus - ORIG ; Vector3d vtW1 = vtV1 ; vtW1.Rotate( vtV3, - 180 * dAng / PIGRECO) ; Vector3d vtW2 = vtV2 ; vtW2.Rotate( vtV3, - 180 * dAng / PIGRECO) ; Vector3d vtRITPlus = ptIPlus - ORIG - vtV1 * dHei ; Frame3d RotFrame ; RotFrame.Set( ptI, vtW1, vtW2, vtV3) ; Frame3d TRotFrame ; TRotFrame.Set( ptIT, vtW1, vtW2, vtV3) ; for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtCI = ptC - ptIxy ; Vector3d vtCF = ptC - ptFxy ; Vector3d vtC = ptC - ORIG ; /* double dPI1 = vtCI * vtU1 ; double dPI2 = vtCI * vtU2 ; double dPF1 = vtCF * vtU1 ; double dPF2 = vtCF * vtU2 ; // Forse queste parti cilindriche andrebbero fatte per // intersezione se il versoreutensile è molto verticale // Parte cilindrica I double dSqRootI = sqrt( dSqRad - dPI2 * dPI2) ; double dPI1_0 = dCos * dSqRootI ; if ( dPI1 >= - dPI1_0 && dPI1 <= dL + dPI1_0 && dPI2 * dPI2 < dSqRad) { // Minimi if ( dPI1 <= dL - dPI1_0) { double dZ0 = - dSin * dSqRootI ; // da ( dPI1 - dPI1_0) è stato cambiato in ( dPI1 + dPI1_0) dMin = dZI + dZ0 + ( dPI1 + dPI1_0) * dDeltaZ / dL ; } else dMin = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; // Massimi if ( dPI1 < dPI1_0) dMax = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; else { double dZ0 = dSin * dSqRootI ; dMax = dZI + dZ0 + ( dPI1 - dPI1_0) * dDeltaZ / dL ; } SubtractIntervals( nGrid, i, j, dMin, dMax) ; } // Parte cilindrica F double dSqRootF = sqrt( dSqRad - dPF2 * dPF2) ; double dPF1_0 = dCos * dSqRootF ; if ( dPF1 >= - dPF1_0 && dPF1 <= dL + dPF1_0 && dPF2 * dPF2 < dSqRad) { // Baubaubau // Minimi if ( dPF1 <= dL - dPF1_0) { double dZ0 = - dSin * dSqRootF ; // da ( dPI1 - dPI1_0) è stato cambiato in ( dPI1 + dPI1_0) dMin = dZF + dZ0 + ( dPF1 + dPF1_0) * dDeltaZ / dL ; } else dMin = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; // Massimi if ( dPF1 < dPF1_0) dMax = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; else { double dZ0 = dSin * dSqRootF ; dMax = dZF + dZ0 + ( dPF1 - dPF1_0) * dDeltaZ / dL ; } SubtractIntervals( nGrid, i, j, dMin, dMax) ; } */ if ( IntersZLineCylinder( ptC, ptI, ptIT, vtToolDir, dRad, dMin, dMax)) { SubtractIntervals( nGrid, i, j, dMin, dMax) ; } if ( IntersZLineCylinder( ptC, ptF, ptFT, vtToolDir, dRad, dMin, dMax)) { SubtractIntervals( nGrid, i, j, dMin, dMax) ; } // Parallelepipedo Point3d ptInt1 = ptC + ( ( ( vtRIPlus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; Point3d ptInt2 = ptC + ( ( ( vtRIMinus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; Point3d ptInt3 = ptC + ( ( ( vtRIPlus - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; Point3d ptInt4 = ptC + ( ( ( vtRIPlus - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; Point3d ptInt5 = ptC + ( ( ( vtRFPlus - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; Point3d ptInt6 = ptC + ( ( ( vtRITPlus - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; ptInt1.LocToLoc( GridFrame, CylFrame) ; ptInt2.LocToLoc( GridFrame, CylFrame) ; ptInt3.LocToLoc( GridFrame, CylFrame) ; ptInt4.LocToLoc( GridFrame, RotFrame) ; ptInt5.LocToLoc( GridFrame, CylFrame) ; ptInt6.LocToLoc( GridFrame, TRotFrame) ; bool bFlag = false ; double dLim1, dLim2 ; if ( ptInt1.y >= 0 && ptInt1.y <= dLOrt && ptInt1.x >= - dHei + ptInt1.y * ( dLLong / dLOrt) && ptInt1.x <= ptInt1.y * ( dLLong / dLOrt)) { ptInt1.LocToLoc( CylFrame, GridFrame) ; dLim1 = ptInt1.z ; bFlag = true ; } if ( ptInt2.y >= 0 && ptInt2.y <= dLOrt && ptInt2.x >= - dHei + ptInt2.y * ( dLLong / dLOrt) && ptInt2.x <= ptInt2.y * ( dLLong / dLOrt)) { ptInt2.LocToLoc( CylFrame, GridFrame) ; if ( ! bFlag) { dLim1 = ptInt2.z ; bFlag = true ; } else dLim2 = ptInt2.z ; } if ( ptInt3.z >= - dRad && ptInt3.z <= dRad && ptInt3.x >= - dHei && ptInt3.x <= 0) { ptInt3.LocToLoc( CylFrame, GridFrame) ; if ( ! bFlag) { dLim1 = ptInt3.z ; bFlag = true ; } else dLim2 = ptInt3.z ; } if ( ptInt4.z >= - dRad && ptInt4.z <= dRad && ptInt4.y >= 0 && ptInt4.y <= dLen) { ptInt4.LocToLoc( RotFrame, GridFrame) ; if ( ! bFlag) { dLim1 = ptInt4.z ; bFlag = true ; } else dLim2 = ptInt4.z ; } if ( ptInt5.z >= - dRad && ptInt5.z <= dRad && ptInt5.x >= dLLong- dHei && ptInt5.x <= dLLong) { ptInt5.LocToLoc( CylFrame, GridFrame) ; if ( ! bFlag) { dLim1 = ptInt5.z ; bFlag = true ; } else dLim2 = ptInt5.z ; } if ( ptInt6.z >= - dRad && ptInt6.z <= dRad && ptInt6.y >= 0 && ptInt6.y <= dLen) { ptInt6.LocToLoc( TRotFrame, GridFrame) ; if ( ! bFlag) { dLim1 = ptInt6.z ; bFlag = true ; } else dLim2 = ptInt6.z ; } if ( bFlag) { // Una linea non confinata se entra in un volume chiuso ci deve uscire dMin = min( dLim1, dLim2) ; dMax = max( dLim1, dLim2) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } // Traslazione dell'ellisse Vector3d vtK = Z_AX ; vtK.LocToLoc( GridFrame, CylFrame) ; ptC.LocToLoc( GridFrame, CylFrame) ; std::vector vdCoef(3); std::vector vdRoots; vdCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dSqRad ; vdCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; vdCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; if ( nRoot == 0 || nRoot == 1) { Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; ptPi.LocToLoc( GridFrame, CylFrame) ; ptPf.LocToLoc( GridFrame, FCylFrame) ; if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqRad && ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqRad) { ptPi.LocToLoc( CylFrame, GridFrame) ; ptPf.LocToLoc( FCylFrame, GridFrame) ; dMin = min( ptPi.z, ptPf.z) ; dMax = max( ptPi.z, ptPf.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } else if ( nRoot == 2) { Point3d ptInter1 = ptC + vdRoots[0] * vtK ; Point3d ptInter2 = ptC + vdRoots[1] * vtK ; if ( ptInter1.x > ptInter2.x) { Point3d ptTemp = ptInter1 ; ptInter1 = ptInter2 ; ptInter2 = ptTemp ; } if ( ptInter1.x > 0 && ptInter1.x < dLLong && ptInter2.x > dLLong) { ptInter1.LocToLoc( CylFrame, GridFrame) ; dMin = min( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; dMax = max( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptInter1.x > 0 && ptInter2.x < dLLong) { ptInter1.LocToLoc( CylFrame, GridFrame) ; ptInter2.LocToLoc( CylFrame, GridFrame) ; dMin = min( ptInter1.z, ptInter2.z) ; dMax = max( ptInter1.z, ptInter2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptInter1.x < 0 && ptInter2.x > dLLong) { dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) { ptInter2.LocToLoc( CylFrame, GridFrame) ; dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } ptC.LocToLoc( CylFrame, TCylFrame) ; vtK.LocToLoc( CylFrame, TCylFrame) ; std::vector vdTCoef(3); std::vector vdTRoots; vdTCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dSqRad ; vdTCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; vdTCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; int nTRoot = PolynomialRoots( 2, vdTCoef, vdTRoots) ; if ( nTRoot == 0 || nTRoot == 1) { Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; ptPi.LocToLoc( GridFrame, TCylFrame) ; ptPf.LocToLoc( GridFrame, FTCylFrame) ; if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqRad && ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqRad) { ptPi.LocToLoc( TCylFrame, GridFrame) ; ptPf.LocToLoc( FTCylFrame, GridFrame) ; dMin = min( ptPi.z, ptPf.z) ; dMax = max( ptPi.z, ptPf.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } else if ( nTRoot == 2) { Point3d ptTInter1 = ptC + vdTRoots[0] * vtK ; Point3d ptTInter2 = ptC + vdTRoots[1] * vtK ; if ( ptTInter1.x > ptTInter2.x) { Point3d ptTemp = ptTInter1 ; ptTInter1 = ptTInter2 ; ptTInter2 = ptTemp ; } if ( ptTInter1.x > 0 && ptTInter1.x < dLLong && ptTInter2.x > dLLong) { ptTInter1.LocToLoc( TCylFrame, GridFrame) ; dMin = min( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; dMax = max( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptTInter1.x > 0 && ptTInter2.x < dLLong) { ptTInter1.LocToLoc( TCylFrame, GridFrame) ; ptTInter2.LocToLoc( TCylFrame, GridFrame) ; dMin = min( ptTInter1.z, ptTInter2.z) ; dMax = max( ptTInter1.z, ptTInter2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptTInter1.x < 0 && ptTInter2.x > dLLong) { dMin = min( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptTInter1.x < 0 && ptTInter2.x > 0 && ptTInter2.x < dLLong) { ptTInter2.LocToLoc( TCylFrame, GridFrame) ; dMin = min( ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; dMax = max( ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) { double dMin, dMax ; unsigned int nStartI, nStartJ, nEndI, nEndJ ; bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; if ( ! Control) return true ; double dDeltaR = dMaxRad - dMinRad ; double dSqMaxRad = dMaxRad * dMaxRad ; double dSqMinRad = dMinRad * dMinRad ; Point3d ptI = ( vtToolDir * ( ptE - ptS) > 0 ? ptS : ptE) ; Point3d ptF = ( vtToolDir * ( ptE - ptS) > 0 ? ptE : ptS) ; Point3d ptIT = ptI - vtToolDir * dHei ; Point3d ptFT = ptF - vtToolDir * dHei ; double dL = ( ( dMaxRad * dHei) / ( dDeltaR)) ; double dl = dL - dHei ; Point3d ptIV = ptI - vtToolDir * dL ; Point3d ptFV = ptF - vtToolDir * dL ; Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; Vector3d vtMLong = ( vtMove * vtToolDir) * vtToolDir ; double dLLong = vtMLong.Len() ; Vector3d vtMOrt = vtMove - vtMLong ; double dLOrt = vtMOrt.Len() ; Vector3d vtV1 = vtToolDir ; Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ; Vector3d vtV3 = vtV1 ^ vtV2 ; // Apertura del cono e parametri per determinare i piani double dTan = dDeltaR / dHei ; double dRatio = dLLong / dLOrt ; double dCos = dTan * dRatio ; double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; double dDen = sqrt( 1 + dTan * dTan) ; double dCoef = dLOrt / dLLong ; // Per traslazione ellissi if ( dRatio > 1 / dTan) return CompConusAux_Milling( nGrid, ptI, ptF, vtV1, vtV2, vtV3, nStartI, nStartJ, nEndI, nEndJ, dHei, dMaxRad, dMinRad, dCoef) ; // Versori normali e prodotti scalari per per determinare i piani // Piani laterali: Vector3d vtNs = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * vtV3 ; Vector3d vtRIV = ptIV - ORIG ; // double dDots = vtRIV * vtNs ; // forse qui è meglio due punti ptIT + vtV3 * dMinRad e ptIT - vtV3 * dMinRad // double dDotd = vtRIV * vtNd ; Vector3d vtS1 = vtNs ; Vector3d vtS2 = vtMove ; vtS2.Normalize() ; // double dDotTestqs = vtS1 * vtS2 ; Vector3d vtS3 = vtS1 ^ vtS2 ; Vector3d vtD1 = vtNd ; Vector3d vtD2 = vtS2 ; // double dDotTestD = vtD1 * vtD2 ; Vector3d vtD3 = vtD1 ^ vtD2 ; Point3d ptSloc = ptI + vtV2 * ( dMaxRad * dCos) + vtV3 * ( dMaxRad * dSin) ; Point3d ptD = ptI + vtV2 * ( dMaxRad * dCos) - vtV3 * ( dMaxRad * dSin) ; Point3d ptST = ptIT + vtV2 * ( dMinRad * dCos) + vtV3 * ( dMinRad * dSin) ; Vector3d vtLen = ptST - ptSloc ; double dPLong = abs( vtLen * vtS3) ; double dPOrt = abs( vtLen * vtS2) ; // Vector3d vtLTr = vtLen - dPLong * vtS3 ; // double dPOrt = vtLTr.Len() ; // Piani di fondo e punta: Vector3d vtU1 = - dLOrt * vtV1 + dLLong * vtV2 ; vtU1.Normalize() ; Vector3d vtU2 = vtMove ; vtU2.Normalize() ; // double dDotTest = vtU1 * vtU2 ; Vector3d vtU3 = vtU1 ^ vtU2 ; Point3d ptU = ptI + vtV2 * ( dMaxRad * dCos) ; Point3d ptTU = ptIT + vtV2 * ( dMinRad * dCos) ; Vector3d vtRU = ptU - ORIG ; // double dDotB = vtRU * vtU1 ; Vector3d vtRUT = ptTU - ORIG ; // double dDotT = vtRUT * vtU1 ; // Piani finale e iniziale: Vector3d vtVAux = ptTU - ptU ; double dAuxOrt = vtVAux * vtV2 ; double dAuxLong = vtVAux * vtV1 ; // Tenere in considerazione per tronchi con dimensioni tali da poter approssimare tori Vector3d vtW1 = - dAuxOrt * vtV1 + dAuxLong * vtV2 ; double dLAux1 = vtW1.Len() ; vtW1.Normalize() ; Vector3d vtW2 = vtVAux ; double dLAux2 = vtW2.Len() ; vtW2.Normalize() ; // double dDottest = vtW1 * vtW2 ; Vector3d vtW3 = vtW1 ^ vtW2 ; double dPr2 = vtLen * vtW2 ; double prova1 = vtLen * vtW3 ; double prova2 = dSin * dDeltaR ; Point3d ptFU = ptU + vtMove ; Vector3d vtRFU = ptFU - ORIG ; // double dDotPF = vtRFU * vtW1 ; // Piani cono: Vector3d vtRCI = ptI - ORIG ; double dDotCI = vtRCI * vtV1 ; Vector3d vtRCIT = ptIT - ORIG ; double dDotCIT = vtRCIT * vtV1 ; Vector3d vtRCF = ptF - ORIG ; double dDotCF = vtRCF * vtV1 ; Vector3d vtRCFT = ptFT - ORIG ; double dDotCFT = vtRCFT * vtV1 ; // Sistemi di riferimento Frame3d GridFrame ; GridFrame.Set( ORIG, X_AX, Y_AX, Z_AX) ; Frame3d IConeFrame ; IConeFrame.Set( ptIV, vtV1, vtV2, vtV3) ; Frame3d FConeFrame ; FConeFrame.Set( ptFV, vtV1, vtV2, vtV3) ; Frame3d PlSFrame ; PlSFrame.Set( ptSloc, vtS1, vtS2, vtS3) ; Frame3d PlDFrame ; PlDFrame.Set( ptD, vtD1, vtD2, vtD3) ; Frame3d PlBFrame ; PlBFrame.Set( ptU, vtU1, vtU2, vtU3) ; Frame3d PlTFrame ; PlTFrame.Set( ptTU, vtU1, vtU2, vtU3) ; Frame3d PlIFrame ; PlIFrame.Set( ptU, vtW1, vtW2, vtW3) ; Frame3d PlFFrame ; PlFFrame.Set( ptFU, vtW1, vtW2, vtW3) ; Frame3d LargeEllipse ; LargeEllipse.Set( ptI, vtV1, vtV2, vtV3) ; Frame3d FLargeEllipse ; FLargeEllipse.Set( ptF, vtV1, vtV2, vtV3) ; Frame3d SmallEllipse ; SmallEllipse.Set( ptIT, vtV1, vtV2, vtV3) ; Frame3d FSmallEllipse ; FSmallEllipse.Set( ptFT, vtV1, vtV2, vtV3) ; for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ORIG ; Vector3d vtK = Z_AX ; Point3d ptIntLC1, ptIntLC2 ; double dPMax, dPMin ; // Cono iniziale if ( IntersLineConus( ptC, vtK, IConeFrame, dTan, dl, dL, ptIntLC1, ptIntLC2)) { dPMin = min( ptIntLC1.z, ptIntLC2.z) ; dPMax = max( ptIntLC1.z, ptIntLC2.z) ; SubtractIntervals( nGrid, i, j, dPMin, dPMax) ; } // Cono finale if ( IntersLineConus( ptC, vtK, FConeFrame, dTan, dl, dL, ptIntLC1, ptIntLC2)) { dPMin = min( ptIntLC1.z, ptIntLC2.z) ; dPMax = max( ptIntLC1.z, ptIntLC2.z) ; SubtractIntervals( nGrid, i, j, dPMin, dPMax) ; } /* // Cono I ptC.LocToLoc( GridFrame, IConeFrame) ; vtK.LocToLoc( GridFrame, IConeFrame) ; std::vector vdIConeCoef(3); std::vector vdIConeRoots; vdIConeCoef[0] = dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z ; vdIConeCoef[1] = 2 * ( dTan * dTan * ptC.x * vtK.x - ptC.y * vtK.y - ptC.z * vtK.z) ; vdIConeCoef[2] = dTan * dTan * vtK.x * vtK.x - vtK.y * vtK.y - vtK.z * vtK.z ; int nIConeRoot = PolynomialRoots( 2, vdIConeCoef, vdIConeRoots) ; if ( nIConeRoot == 1) { Point3d ptR1 = ptC + vdIConeRoots[0] * vtK ; if ( ptR1.x >= dl && ptR1.x < dL) { ptR1.LocToLoc( IConeFrame, GridFrame) ; dMin = min( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x >= 0 && ptR1.x < dl) { dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } else if ( nIConeRoot == 2) { Point3d ptR1 = ptC + vdIConeRoots[0] * vtK ; Point3d ptR2 = ptC + vdIConeRoots[1] * vtK ; if ( ptR1.x > ptR2.x) { Point3d ptTemp = ptR1 ; ptR1 = ptR2 ; ptR2 = ptTemp ; } if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { ptR2.LocToLoc( IConeFrame, GridFrame) ; dMin = min( ptR2.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR2.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { ptR2.LocToLoc( IConeFrame, GridFrame) ; dMin = min( ptR2.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR2.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { ptR1.LocToLoc( IConeFrame, GridFrame) ; ptR2.LocToLoc( IConeFrame, GridFrame) ; dMin = min( ptR1.z, ptR2.z) ; dMax = max( ptR1.z, ptR2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { ptR1.LocToLoc( IConeFrame, GridFrame) ; dMin = min( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } // Cono F ptC.LocToLoc( IConeFrame, FConeFrame) ; vtK.LocToLoc( IConeFrame, FConeFrame) ; std::vector vdFConeCoef(3); std::vector vdFConeRoots; vdFConeCoef[0] = dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z ; vdFConeCoef[1] = 2 * ( dTan * dTan * ptC.x * vtK.x - ptC.y * vtK.y - ptC.z * vtK.z) ; vdFConeCoef[2] = dTan * dTan * vtK.x * vtK.x - vtK.y * vtK.y - vtK.z * vtK.z ; int nFConeRoot = PolynomialRoots( 2, vdFConeCoef, vdFConeRoots) ; if ( nFConeRoot == 1) { Point3d ptR1 = ptC + vdFConeRoots[0] * vtK ; if ( ptR1.x >= dl && ptR1.x < dL) { ptR1.LocToLoc( FConeFrame, GridFrame) ; dMin = min( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x >= 0 && ptR1.x < dl) { dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } else if ( nFConeRoot == 2) { Point3d ptR1 = ptC + vdFConeRoots[0] * vtK ; Point3d ptR2 = ptC + vdFConeRoots[1] * vtK ; if ( ptR1.x > ptR2.x) { Point3d ptTemp = ptR1 ; ptR1 = ptR2 ; ptR2 = ptTemp ; } if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { ptR2.LocToLoc( FConeFrame, GridFrame) ; dMin = min( ptR2.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR2.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { ptR2.LocToLoc( FConeFrame, GridFrame) ; dMin = min( ptR2.z, ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR2.z, ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { ptR1.LocToLoc( FConeFrame, GridFrame) ; ptR2.LocToLoc( FConeFrame, GridFrame) ; dMin = min( ptR1.z, ptR2.z) ; dMax = max( ptR1.z, ptR2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { ptR1.LocToLoc( FConeFrame, GridFrame) ; dMin = min( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } */ // Solido interno // ptC.LocToLoc( FConeFrame, GridFrame) ; // vtK.LocToLoc( FConeFrame, GridFrame) ; Point3d ptInt1 = ptC + ( ( ( vtRIV - vtC) * vtS1) / ( vtK * vtS1)) * vtK ; Point3d ptInt2 = ptC + ( ( ( vtRIV - vtC) * vtD1) / ( vtK * vtD1)) * vtK ; Point3d ptInt3 = ptC + ( ( ( vtRU - vtC) * vtU1) / ( vtK * vtU1)) * vtK ; Point3d ptInt4 = ptC + ( ( ( vtRUT - vtC) * vtU1) / ( vtK * vtU1)) * vtK ; Point3d ptInt5 = ptC + ( ( ( vtRU - vtC) * vtW1) / ( vtK * vtW1)) * vtK ; Point3d ptInt6 = ptC + ( ( ( vtRFU - vtC) * vtW1) / ( vtK * vtW1)) * vtK ; ptInt1.LocToLoc( GridFrame, PlSFrame) ; ptInt2.LocToLoc( GridFrame, PlDFrame) ; ptInt3.LocToLoc( GridFrame, PlBFrame) ; ptInt4.LocToLoc( GridFrame, PlTFrame) ; ptInt5.LocToLoc( GridFrame, PlIFrame) ; ptInt6.LocToLoc( GridFrame, PlFFrame) ; double dLim1, dLim2 ; bool bFlag = false ; if ( ptInt1.z >= 0 && ptInt1.z <= dPLong && ptInt1.y >= - ptInt1.z * dPOrt / dPLong && ptInt1.y <= dLen - ptInt1.z * dPOrt / dPLong ) { ptInt1.LocToLoc( PlSFrame, GridFrame) ; dLim1 = ptInt1.z ; bFlag = true ; } if ( ptInt2.z >= - dPLong && ptInt2.z <= 0 && ptInt2.y >= ptInt2.z * dPOrt / dPLong && ptInt2.y <= dLen + ptInt2.z * dPOrt / dPLong) { ptInt2.LocToLoc( PlDFrame, GridFrame) ; if ( ! bFlag) { dLim1 = ptInt2.z ; bFlag = true ; } else dLim2 = ptInt2.z ; } if ( ptInt3.y >= 0 && ptInt3.y <= dLen && ptInt3.z > - dMaxRad * dSin && ptInt3.z < dMaxRad * dSin) { ptInt3.LocToLoc( PlBFrame, GridFrame) ; if ( ! bFlag) { dLim1 = ptInt3.z ; bFlag = true ; } else dLim2 = ptInt3.z ; } if ( ptInt4.y >= 0 && ptInt4.y <= dLen && ptInt4.z > - dMinRad * dSin && ptInt4.z < dMinRad * dSin) { ptInt4.LocToLoc( PlTFrame, GridFrame) ; if ( ! bFlag) { dLim1 = ptInt4.z ; bFlag = true ; } else dLim2 = ptInt4.z ; } if ( ptInt5.y >= 0 && ptInt5.y <= dPr2 && ptInt5.z > - dSin * dMaxRad + ptInt5.y * prova1 / dPr2 && ptInt5.z < dSin * dMaxRad - ptInt5.y * prova1 / dPr2) { ptInt5.LocToLoc( PlIFrame, GridFrame) ; if ( ! bFlag) { dLim1 = ptInt5.z ; bFlag = true ; } else dLim2 = ptInt5.z ; } if ( ptInt6.y >= 0 && ptInt6.y <= dPr2 && ptInt6.z > - dSin * dMaxRad + ptInt6.y * prova1 / dPr2 && ptInt6.z < dSin * dMaxRad - ptInt6.y * prova1 / dPr2) { ptInt6.LocToLoc( PlFFrame, GridFrame) ; if ( ! bFlag) { dLim1 = ptInt6.z ; bFlag = true ; } else dLim2 = ptInt6.z ; } if( bFlag) { dMin = min( dLim1, dLim2) ; dMax = max( dLim1, dLim2) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } // Traslazioni ellissi ptC.LocToLoc( GridFrame, LargeEllipse) ; vtK.LocToLoc( GridFrame, LargeEllipse) ; std::vector vdLargeCoef(3); std::vector vdLargeRoots; vdLargeCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dSqMaxRad ; vdLargeCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; vdLargeCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; int nLRoot = PolynomialRoots( 2, vdLargeCoef, vdLargeRoots) ; if ( nLRoot == 0) { Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; ptPi.LocToLoc( GridFrame, LargeEllipse) ; ptPf.LocToLoc( GridFrame, FLargeEllipse) ; if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqMaxRad && ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqMaxRad) { ptPi.LocToLoc( LargeEllipse, GridFrame) ; ptPf.LocToLoc( FLargeEllipse, GridFrame) ; dMin = min( ptPi.z, ptPf.z) ; dMax = max( ptPi.z, ptPf.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } else if ( nLRoot == 2) { Point3d ptInter1 = ptC + vdLargeRoots[0] * vtK ; Point3d ptInter2 = ptC + vdLargeRoots[1] * vtK ; if ( ptInter1.x > ptInter2.x) { Point3d ptTemp = ptInter1 ; ptInter1 = ptInter2 ; ptInter2 = ptTemp ; } if ( ptInter1.x > 0 && ptInter1.x < dLLong && ptInter2.x > dLLong) { ptInter1.LocToLoc( LargeEllipse, GridFrame) ; dMin = min( ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; dMax = max( ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptInter1.x > 0 && ptInter2.x < dLLong) { ptInter1.LocToLoc( LargeEllipse, GridFrame) ; ptInter2.LocToLoc( LargeEllipse, GridFrame) ; dMin = min( ptInter1.z, ptInter2.z) ; dMax = max( ptInter1.z, ptInter2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptInter1.x < 0 && ptInter2.x > dLLong) { dMin = min( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) { ptInter2.LocToLoc( LargeEllipse, GridFrame) ; dMin = min( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; dMax = max( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } ptC.LocToLoc( LargeEllipse, SmallEllipse) ; vtK.LocToLoc( LargeEllipse, SmallEllipse) ; std::vector vdSmallCoef(3); std::vector vdSmallRoots; vdSmallCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dSqMinRad ; vdSmallCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; vdSmallCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; int nSRoot = PolynomialRoots( 2, vdSmallCoef, vdSmallRoots) ; if ( nSRoot == 0) { Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; ptPi.LocToLoc( GridFrame, SmallEllipse) ; ptPf.LocToLoc( GridFrame, FSmallEllipse) ; if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqMinRad && ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqMinRad) { ptPi.LocToLoc( SmallEllipse, GridFrame) ; ptPf.LocToLoc( FSmallEllipse, GridFrame) ; dMin = min( ptPi.z, ptPf.z) ; dMax = max( ptPi.z, ptPf.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } else if ( nSRoot == 2) { Point3d ptTInter1 = ptC + vdSmallRoots[0] * vtK ; Point3d ptTInter2 = ptC + vdSmallRoots[1] * vtK ; if ( ptTInter1.x > ptTInter2.x) { Point3d ptTemp = ptTInter1 ; ptTInter1 = ptTInter2 ; ptTInter2 = ptTemp ; } if ( ptTInter1.x > 0 && ptTInter1.x < dLLong && ptTInter2.x > dLLong) { ptTInter1.LocToLoc( SmallEllipse, GridFrame) ; dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptTInter1.x > 0 && ptTInter2.x < dLLong) { ptTInter1.LocToLoc( SmallEllipse, GridFrame) ; ptTInter2.LocToLoc( SmallEllipse, GridFrame) ; dMin = min( ptTInter1.z, ptTInter2.z) ; dMax = max( ptTInter1.z, ptTInter2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptTInter1.x < 0 && ptTInter2.x > dLLong) { dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptTInter1.x < 0 && ptTInter2.x > 0 && ptTInter2.x < dLLong) { ptTInter2.LocToLoc( SmallEllipse, GridFrame) ; dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } } return true ; } //---------------------------------------------------------------------------- bool VolZmap::CompConusAux_Milling( unsigned int nGrid, const Point3d & ptI, const Point3d & ptF, const Vector3d & vtV1, const Vector3d & vtV2, const Vector3d & vtV3, unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, double dHei, double dMaxRad, double dMinRad, double dCoef) { double dDeltaR = dMaxRad - dMinRad ; double dL = ( ( dMaxRad * dHei) / ( dDeltaR)) ; double dTan = dDeltaR / dHei ; double dl = dL - dHei ; double dLLong = abs( ( ptF - ptI) * vtV1) ; double dLOrt = abs( ( ptF - ptI) * vtV2) ; double dSqMaxRad = dMaxRad * dMaxRad ; Point3d ptV = ptI - vtV1 * dL ; Point3d ptT = ptI - vtV1 * dHei ; Frame3d GridFrame ; GridFrame.Set( ORIG, X_AX, Y_AX, Z_AX) ; Frame3d ConeFrame ; ConeFrame.Set( ptV, vtV1, vtV2, vtV3) ; Frame3d IEllipseFrame ; IEllipseFrame.Set( ptI, vtV1, vtV2, vtV3) ; Frame3d FEllipseFrame ; FEllipseFrame.Set( ptF, vtV1, vtV2, vtV3) ; Vector3d vtI = ptI - ORIG ; double dDotI = vtI * vtV1 ; Vector3d vtT = ptT - ORIG ; double dDotT = vtT * vtV1 ; Vector3d vtF = ptF - ORIG ; double dDotF = vtF * vtV1 ; Vector3d vtK = Z_AX ; Vector3d vtKC = vtK ; vtKC.LocToLoc( GridFrame, ConeFrame) ; Vector3d vtKE = vtK ; vtKE.LocToLoc( GridFrame, IEllipseFrame) ; double dMin, dMax ; for ( unsigned int i = nStI ; i <= nEnI ; ++ i) { for ( unsigned int j = nStJ ; j <= nEnJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ORIG ; // Cono ptC.LocToLoc( GridFrame, ConeFrame) ; std::vector vdConeCoef(3); std::vector vdConeRoots; vdConeCoef[0] = dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z ; vdConeCoef[1] = 2 * ( dTan * dTan * ptC.x * vtKC.x - ptC.y * vtKC.y - ptC.z * vtKC.z) ; vdConeCoef[2] = dTan * dTan * vtKC.x * vtKC.x - vtKC.y * vtKC.y - vtKC.z * vtKC.z ; int nConeRoot = PolynomialRoots( 2, vdConeCoef, vdConeRoots) ; if ( nConeRoot == 1) { Point3d ptR1 = ptC + vdConeRoots[0] * vtKC ; if ( ptR1.x >= dl && ptR1.x < dL) { ptR1.LocToLoc( ConeFrame, GridFrame) ; dMin = min( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x >= 0 && ptR1.x < dl) { dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } else if ( nConeRoot == 2) { Point3d ptR1 = ptC + vdConeRoots[0] * vtKC ; Point3d ptR2 = ptC + vdConeRoots[1] * vtKC ; if ( ptR1.x > ptR2.x) { Point3d ptTemp = ptR1 ; ptR1 = ptR2 ; ptR2 = ptTemp ; } if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { ptR2.LocToLoc( ConeFrame, GridFrame) ; dMin = min( ptR2.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR2.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { ptR2.LocToLoc( ConeFrame, GridFrame) ; dMin = min( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { ptR1.LocToLoc( ConeFrame, GridFrame) ; ptR2.LocToLoc( ConeFrame, GridFrame) ; dMin = min( ptR1.z, ptR2.z) ; dMax = max( ptR1.z, ptR2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { ptR1.LocToLoc( ConeFrame, GridFrame) ; dMin = min( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } // Tralsazione dell'ellisse ptC.LocToLoc( ConeFrame, IEllipseFrame) ; std::vector vdEllipseCoef(3); std::vector vdEllipseRoots; vdEllipseCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dSqMaxRad ; vdEllipseCoef[1] = 2 * ( dCoef * dCoef * vtKE.x * ptC.x + vtKE.y * ptC.y + vtKE.z * ptC.z - dCoef * ( vtKE.x * ptC.y + vtKE.y * ptC.x)) ; vdEllipseCoef[2] = dCoef * dCoef * vtKE.x * vtKE.x + vtKE.y * vtKE.y + vtKE.z * vtKE.z - 2 * dCoef * vtKE.x * vtKE.y ; int nEllipseRoot = PolynomialRoots( 2, vdEllipseCoef, vdEllipseRoots) ; if ( nEllipseRoot == 0 || nEllipseRoot == 1) { Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; ptPi.LocToLoc( GridFrame, IEllipseFrame) ; ptPf.LocToLoc( GridFrame, FEllipseFrame) ; if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqMaxRad && ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqMaxRad) { ptPi.LocToLoc( IEllipseFrame, GridFrame) ; ptPf.LocToLoc( FEllipseFrame, GridFrame) ; dMin = min( ptPi.z, ptPf.z) ; dMax = max( ptPi.z, ptPf.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } if ( nEllipseRoot == 2) { Point3d ptInter1 = ptC + vdEllipseRoots[0] * vtKE ; Point3d ptInter2 = ptC + vdEllipseRoots[1] * vtKE ; if ( ptInter1.x > ptInter2.x) { Point3d ptTemp = ptInter1 ; ptInter1 = ptInter2 ; ptInter2 = ptTemp ; } if ( ptInter1.x > 0 && ptInter1.x < dLLong && ptInter2.x > dLLong) { ptInter1.LocToLoc( IEllipseFrame, GridFrame) ; dMin = min( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; dMax = max( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptInter1.x > 0 && ptInter2.x < dLLong) { ptInter1.LocToLoc( IEllipseFrame, GridFrame) ; ptInter2.LocToLoc( IEllipseFrame, GridFrame) ; dMin = min( ptInter1.z, ptInter2.z) ; dMax = max( ptInter1.z, ptInter2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptInter1.x < 0 && ptInter2.x > dLLong) { dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) { ptInter2.LocToLoc( IEllipseFrame, GridFrame) ; dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } } return true ; } // ---------- SFERA ---------------------------------------------------------- //---------------------------------------------------------------------------- bool VolZmap::CompBall_Milling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, double dRad) { double dMin, dMax ; unsigned int nStartI, nStartJ, nEndI, nEndJ ; bool Control = BBoxComponent( nGrid, ptLs, ptLe, V_NULL, V_NULL, nStartI, nStartJ, nEndI, nEndJ, dRad, 0, 0) ; if ( ! Control) return true ; Point3d ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; Point3d ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; Vector3d vtMove = ptF - ptI ; Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dVLen = abs( vtMove.z) ; // Verticale e planare rispetto ai dexel double dPLen = vtMoveXY.LenXY() ; double dLen = vtMove.Len() ; double dR1 = dVLen / dLen ; double dR2 = dPLen / dLen ; double dZI = ptI.z ; double dDeltaZ = ptF.z - ptI.z ; double dSqRad = dRad * dRad ; if ( dPLen < EPS_SMALL) { for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; double dSqLen = vtC.SqLen() ; if ( dSqLen < dSqRad) { double dH = sqrt( dSqRad - dSqLen) ; dMin = dZI - dH ; dMax = dZI + dDeltaZ + dH ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } } else { Vector3d vtV1 = vtMoveXY ; vtV1.Normalize() ; Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtCI = ptC - ptIxy ; Vector3d vtCF = ptC - ptFxy ; double dX1 = vtCI * vtV1 ; double dX2 = vtCI * vtV2 ; double dISqDist = vtCI * vtCI ; double dFSqDist = vtCF * vtCF ; if ( dISqDist < dSqRad || dFSqDist < dSqRad || ( dX1 > 0 && dX1 < dPLen && dX2 * dX2 < dSqRad)) { // Massimi if ( dX1 < - dR1 * sqrt( dSqRad - ( dX2 * dX2))) dMax = dZI + sqrt( dSqRad - dISqDist) ; else if ( dX1 < dPLen - dR1 * sqrt( dSqRad - ( dX2 * dX2))) dMax = dZI + dR2 * sqrt( dSqRad - dX2 * dX2) + ( dX1 + dR1 * sqrt( dSqRad - ( dX2 * dX2))) * dVLen / dPLen ; else dMax = dZI + dDeltaZ + sqrt( dSqRad - dFSqDist) ; // Minimi if ( dX1 < dR1 * sqrt( dSqRad - ( dX2 * dX2))) dMin = dZI - sqrt( dSqRad - dISqDist) ; else if ( dX1 < dPLen + dR1 * sqrt( dSqRad - ( dX2 * dX2))) dMin = dZI - dR2 * sqrt( dSqRad - dX2 * dX2) + ( dX1 - dR1 * sqrt( dSqRad - ( dX2 * dX2))) * dVLen / dPLen ; else dMin = dZI + dDeltaZ - sqrt( dSqRad - dFSqDist) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } } return true ; } // ------------------------- BOUNDING BOX -------------------------------------------------------------------------------------- //---------------------------------------------------------------------------- inline bool VolZmap::BoundingBox( unsigned int nGrid, const Point3d & ptP1, const Point3d & ptP2, const Vector3d & vtV1, const Vector3d & vtV2, unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ) { // NB: E' vitale che vengano passati i punti e i vettori nel sistema di riferimento // di riferimento opportuno. // Controllo sull'ammissibilità del numero di griglia if ( nGrid < 0 || nGrid > 2) return false ; unsigned int nMaxNx, nMaxNy ; double dMaxXValue, dMaxYValue ; double dMinZValue, dMaxZValue ; nMaxNx = m_nVNx[nGrid] ; nMaxNy = m_nVNy[nGrid] ; dMaxXValue = nMaxNx * m_dStep ; dMaxYValue = nMaxNy * m_dStep ; dMinZValue = m_dVMinZ[nGrid] ; dMaxZValue = m_dVMaxZ[nGrid] ; // Determinazione del raggio massimo dell'utensile double dMaxRad = max( m_dRadius, m_dTipRadius) ; // Determinazione delle posizioni della punta dell'utensile nelle posizioni iniziale e finale Point3d ptP1T = ptP1 - m_dHeight * vtV1 ; Point3d ptP2T = ptP2 - m_dHeight * vtV2 ; // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento double dMinX = min( min( ptP1.x, ptP1T.x), min( ptP2.x, ptP2T.x)) - dMaxRad ; double dMinY = min( min( ptP1.y, ptP1T.y), min( ptP2.y, ptP2T.y)) - dMaxRad ; double dMinZ = min( min( ptP1.z, ptP1T.z), min( ptP2.z, ptP2T.z)) - dMaxRad ; double dMaxX = max( max( ptP1.x, ptP1T.x), max( ptP2.x, ptP2T.x)) + dMaxRad ; double dMaxY = max( max( ptP1.y, ptP1T.y), max( ptP2.y, ptP2T.y)) + dMaxRad ; double dMaxZ = max( max( ptP1.z, ptP1T.z), max( ptP2.z, ptP2T.z)) + dMaxRad ; // Verifica dell'interferenza dell'utensile con lo Zmap if ( dMaxX < EPS_SMALL || dMinX > dMaxXValue - EPS_SMALL) return false ; if ( dMaxY < EPS_SMALL || dMinY > dMaxYValue - EPS_SMALL) return false ; if ( dMaxZ < dMinZValue + EPS_SMALL || dMinZ > dMaxZValue - EPS_SMALL) return false ; // Limiti su indici nStI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; nEnI = ( dMaxX > dMaxXValue - EPS_SMALL ? nMaxNx - 1 : static_cast ( dMaxX / m_dStep)) ; nStJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; nEnJ = ( dMaxY > dMaxYValue - EPS_SMALL ? nMaxNy - 1 : static_cast ( dMaxY / m_dStep)) ; return true ; } //---------------------------------------------------------------------------- inline bool VolZmap::BBoxComponent( unsigned int nGrid, const Point3d & ptP1, const Point3d & ptP2, const Vector3d & vtV1, const Vector3d & vtV2, unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, double dRad, double dTipRad, double dHei) { // NB: E' vitale che vengano passati i punti e i vettori nel sistema di riferimento // di riferimento opportuno. // Controllo sull'ammissibilità del numero di griglia if ( nGrid < 0 || nGrid > 2) return false ; unsigned int nMaxNx, nMaxNy ; double dMaxXValue, dMaxYValue ; double dMinZValue, dMaxZValue ; nMaxNx = m_nVNx[nGrid] ; nMaxNy = m_nVNy[nGrid] ; dMaxXValue = nMaxNx * m_dStep ; dMaxYValue = nMaxNy * m_dStep ; dMinZValue = m_dVMinZ[nGrid] ; dMaxZValue = m_dVMaxZ[nGrid] ; // Determinazione del raggio massimo del componente double dMaxRad = max( dRad, dTipRad) ; // Determinazione delle posizioni della punta del componente nelle posizioni iniziale e finale Point3d ptP1T = ptP1 - dHei * vtV1 ; Point3d ptP2T = ptP2 - dHei * vtV2 ; // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento double dMinX = min( min( ptP1.x, ptP1T.x), min( ptP2.x, ptP2T.x)) - dMaxRad; double dMinY = min( min( ptP1.y, ptP1T.y), min( ptP2.y, ptP2T.y)) - dMaxRad; double dMinZ = min( min( ptP1.z, ptP1T.z), min( ptP2.z, ptP2T.z)) - dMaxRad; double dMaxX = max( max( ptP1.x, ptP1T.x), max( ptP2.x, ptP2T.x)) + dMaxRad; double dMaxY = max( max( ptP1.y, ptP1T.y), max( ptP2.y, ptP2T.y)) + dMaxRad; double dMaxZ = max( max( ptP1.z, ptP1T.z), max( ptP2.z, ptP2T.z)) + dMaxRad; // Verifica dell'interferenza dell'utensile con lo Zmap if ( dMaxX < EPS_SMALL || dMinX > dMaxXValue - EPS_SMALL) return false ; if ( dMaxY < EPS_SMALL || dMinY > dMaxYValue - EPS_SMALL) return false ; if ( dMaxZ < dMinZValue + EPS_SMALL || dMinZ > dMaxZValue - EPS_SMALL) return false ; // Limiti su indici nStI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; nEnI = ( dMaxX > dMaxXValue - EPS_SMALL ? nMaxNx - 1 : static_cast ( dMaxX / m_dStep)) ; nStJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; nEnJ = ( dMaxY > dMaxYValue - EPS_SMALL ? nMaxNy - 1 : static_cast ( dMaxY / m_dStep)) ; return true ; } /* /* // VERSIONE NUOVA DA TESTARE bool VolZmap::Cyl_Milling( unsigned int nGrid, const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) { double dMin, dMax ; unsigned int nStartI, nStartJ, nEndI, nEndJ ; bool Control = BBoxComponent( nGrid, ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; if ( ! Control) return true ; Point3d ptI, ptF ; Vector3d vtV1, vtV2, vtV3 ; // Studio delle simmetrie //vtV1 = ( vtToolDir.z < 0 ? - vtToolDir : vtToolDir) ; //Point3d ptI = ptLs + ( vtToolDir.z < 0 ? dHei * vtV1 : vtNUll) ; //Point3d ptF + ( vtToolDir.z < 0 ? dHei * vtV1 : vtNUll) ; if ( vtToolDir.z < 0) { vtV1 = - vtToolDir ; ptI = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLs + dHei * vtV1 : ptLe + dHei * vtV1) ; ptF = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLe + dHei * vtV1 : ptLs + dHei * vtV1) ; } else { vtV1 = vtToolDir ; ptI = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLs : ptLe) ; ptF = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLe : ptLs) ; } Point3d ptIT = ptI - vtV1 * dHei ; Point3d ptFT = ptF - vtV1 * dHei ; // Definizione di un sintema di riferimento nel piano Vector3d vtU1( - vtV1.x, - vtV1.y, 0) ; double dCos = vtV1.z ; double dSin = vtU1.LenXY() ; double dSemiAxMin = m_dRadius * dCos ; double dSqRad = m_dRadius * m_dRadius ; double dSqSemiAxMin = dSemiAxMin * dSemiAxMin ; vtU1.Normalize() ; // Ocio che la sua lunghezza sia maggiore di EPS_SMALL Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = ptIT.z - ptI.z ; double dL = dSin * dHei ; Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; Vector3d vtMLong = ( vtMove * vtV1) * vtV1 ; double dLLong = vtMLong.Len() ; Vector3d vtMOrt = vtMove - vtMLong ; double dLOrt = vtMOrt.Len() ; double dCoef = dLOrt / dLLong ; double dAng = atan( 1 / dCoef) ; // vtV1, vtV2 e vtV3 definiscono gli assi dei sistemi di riferimento intrinseci vtV2 = vtMOrt ; vtV2.Normalize() ; vtV3 = vtV1 ^ vtV2 ; Frame3d CylFrame ; CylFrame.Set( ptI, vtV1, vtV2, vtV3) ; Frame3d FCylFrame ; FCylFrame.Set( ptF, vtV1, vtV2, vtV3) ; Frame3d TCylFrame ; TCylFrame.Set( ptIT, vtV1, vtV2, vtV3) ; Frame3d FTCylFrame ; FTCylFrame.Set( ptFT, vtV1, vtV2, vtV3) ; // Altri punti notevoli Point3d ptIPlus = ptI + dRad * vtV3 ; Point3d ptIMinus = ptI - dRad * vtV3 ; Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; // Grandezze per la definizione dei piani Vector3d vtRI = ptI - ORIG ; double dDotI = vtV1 * vtRI ; Vector3d vtRIT = ptIT - ORIG ; double dDotIT = vtV1 * vtRIT ; Vector3d vtRF = ptF - ORIG ; double dDotF = vtV1 * vtRF ; Vector3d vtRFT = ptFT - ORIG ; double dDotFT = vtV1 * vtRFT ; Vector3d vtW1 = vtV1 ; vtW1.Rotate( vtV3, - 180 * dAng / PIGRECO) ; Vector3d vtW2 = vtV2 ; vtW2.Rotate( vtV3, - 180 * dAng / PIGRECO) ; double dFrCos = cos( dAng) ; double dFrSin = sin( dAng) ; Frame3d RotFrame ; RotFrame.Set( ptI, vtW1, vtW2, vtV3) ; Frame3d TRotFrame ; TRotFrame.Set( ptIT, vtW1, vtW2, vtV3) ; // Versore Z nel sistema di riferimento CylFrame Vector3d vtKCyl = Z_AX ; vtKCyl.LocToLoc( m_LocalFrame, CylFrame) ; // Versore Z nel sistema di riferimento RotFrame Vector3d vtKRot = Z_AX ; vtKRot.LocToLoc( m_LocalFrame, RotFrame) ; // Ciclo sui dexel for( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Point3d ptCCyl( dX, dY, 0) ; Point3d ptCRot( dX, dY, 0) ; Point3d ptCTCyl( dX, dY, 0) ; ptCCyl.LocToLoc( m_LocalFrame, CylFrame) ; ptCRot.LocToLoc( m_LocalFrame, RotFrame) ; ptCTCyl.LocToLoc( m_LocalFrame, TCylFrame) ; Vector3d vtCI = ptC - ptIxy ; Vector3d vtCF = ptC - ptFxy ; //Vector3d vtC = ptC - ORIG ; double dPI1 = vtCI * vtU1 ; double dPI2 = vtCI * vtU2 ; double dPF1 = vtCF * vtU1 ; double dPF2 = vtCF * vtU2 ; // Cilindro iniziale if ( dPI1 * dPI1 / dSqSemiAxMin + dPI2 * dPI2 / dSqRad < 1 || ( dPI1 - dL) * ( dPI1 - dL) / dSqSemiAxMin + dPI2 * dPI2 / dSqRad < 1 || ( dPI1 > 0 && dPI1 < dL && abs( dPI2) < m_dRadius)) { double dSqRoot = sqrt( dSqRad - dPI2 * dPI2) ; double dPI1_0 = dCos * dSqRoot ; double dH = dSin * dSqRoot ; // Massimo if ( dPI1 < dPI1_0) // Se vtV1.z -> 0 allora dCos -> 0 e con essi l'area ove vi // è la proiezione su XY del piano, quindi la divisione non da // problemi, data la dimensione del passo della griglia dMax = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; else // Se vtV1.z -> 1 dCos -> 1 3 dSin -> 0 e con esso dL -> 0, // ma anche l'area della regione interessata tende a zero, // quindi la divisione non da problemi, data la dimensione del passo della griglia dMax = dZI + dH + dDeltaZ * ( dPI1 - dPI1_0) / dL ; // Minimo if ( dPI1 < - dPI1_0) // Analoga osservazione dMin = dZI - dH + dDeltaZ * ( dPI1 + dPI1_0) / dL ; else // Analoga osservazione dMin = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } // Cilindro finale if ( dPF1 * dPF1 + dPF2 * dPF2 < 1 || ( dPF1 - dL) * ( dPF1 - dL) + dPF2 * dPF2 < 1 || ( dPF1 > 0 && dPF1 < dL && abs( dPF2) < EPS_SMALL)) { double dSqRoot = sqrt( dSqRad - ( dPF2 - dL) * ( dPF2 - dL)) ; double dPF1_0 = dCos * dSqRoot ; double dH = dSin * dSqRoot ; // Massimo if ( dPF1 < dPF1_0) // Se vtV1.z -> 0 allora dCos -> 0 e con essi l'area ove vi // è la proiezione su XY del piano, quindi la divisione non da // problemi, data la dimensione del passo della griglia dMax = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; else // Se vtV1.z -> 1 dCos -> 1 3 dSin -> 0 e con esso dL -> 0, // ma anche l'area della regione interessata tende a zero, // quindi la divisione non da problemi, data la dimensione del passo della griglia dMax = dZF + dH + dDeltaZ * ( dPF1 - dPF1_0) / dL ; // Minimo if ( dPF1 < - dPF1_0) // Analoga osservazione dMin = dZF - dH + dDeltaZ * ( dPF1 + dPF1_0) / dL ; else // Analoga osservazione dMin = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } // Parallelepipedo unsigned int nInt = 0 ; double dt ; Point3d ptInt1, ptInt2 ; // Piani paralleli a XY nel sistema CylFrame if ( abs( vtKCyl.z) > EPS_ZERO || abs( ptCCyl.z - m_dRadius) < EPS_SMALL || abs( ptCCyl.z + m_dRadius) < EPS_SMALL) { dt = ( m_dRadius - ptCCyl.z) / vtKCyl.z ; Point3d ptInt = ptCCyl + dt * vtKCyl ; if ( ptInt.y > 0 && ptInt.y < dLOrt && dLOrt * ptCCyl.x - dLLong * ptCCyl.y < 0 && dLOrt * ptCCyl.x + dLOrt * dHei - dLLong * ptCCyl.y > 0) { ptInt.LocToLoc( CylFrame, m_LocalFrame) ; ptInt1 = ptInt ; nInt = 1 ; } dt = ( - m_dRadius - ptCCyl.z) / vtKCyl.z ; ptInt = ptCCyl + dt * vtKCyl ; if ( ptInt.y > 0 && ptInt.y < dLOrt && dLOrt * ptCCyl.x - dLLong * ptCCyl.y < 0 && dLOrt * ptCCyl.x + dLOrt * dHei - dLLong * ptCCyl.y > 0) { ptInt.LocToLoc( CylFrame, m_LocalFrame) ; if ( nInt == 0) { ptInt1 = ptInt ; nInt = 1 ; } else if ( nInt == 1) { ptInt2 = ptInt ; nInt = 2 ; } } } // Piani paralleli a XZ nel sistema CylFrame if ( abs( vtKCyl.y) > EPS_ZERO || abs( ptCCyl.y) < EPS_SMALL || abs( ptCCyl.y - dLOrt) < EPS_SMALL) { dt = - ptCCyl.y / vtKCyl.y ; Point3d ptInt = ptCCyl + dt * vtKCyl ; if ( ptInt.x > - dHei && ptInt.x < 0 && ptInt.z > - m_dRadius && ptInt.z < m_dRadius) { ptInt.LocToLoc( CylFrame, m_LocalFrame) ; if ( nInt == 0) { ptInt1 = ptInt ; nInt = 1 ; } else if ( nInt == 1) { ptInt2 = ptInt ; nInt = 2 ; } } dt = ( dLOrt - ptCCyl.y) / vtKCyl.y ; ptInt = ptCCyl + dt * vtKCyl ; if ( ptInt.x > - dHei && ptInt.x < 0 && ptInt.z > - m_dRadius && ptInt.z < m_dRadius) { ptInt.LocToLoc( CylFrame, m_LocalFrame) ; if ( nInt == 0) { ptInt1 = ptInt ; nInt = 1 ; } else if ( nInt == 1) { ptInt2 = ptInt ; nInt = 2 ; } } } // Piani paralleli a YZ nel sistema RotFrame if ( abs( vtKRot.x) > EPS_ZERO || abs( ptCRot.x) < EPS_SMALL || abs( ptCRot.x + dHei * dFrCos) < EPS_SMALL) { dt = - ptCRot.x / vtKRot.x ; Point3d ptInt = ptCCyl + dt * vtKRot ; if ( ptInt.y > 0 && ptInt.y < dLen && ptInt.z > - m_dRadius && ptInt.z < m_dRadius) { ptInt.LocToLoc( RotFrame, m_LocalFrame) ; if ( nInt == 0) { ptInt1 = ptInt ; nInt = 1 ; } else if ( nInt == 1) { ptInt2 = ptInt ; nInt = 2 ; } } dt = ( - dHei * dFrSin - ptCRot.x) / vtKRot.x ; ptInt = ptCCyl + dt * vtKRot ; if ( ptInt.y > - dHei * dFrSin && ptInt.y < dLen - dHei * dFrSin && ptInt.z > - m_dRadius && ptInt.z < m_dRadius) { ptInt.LocToLoc( RotFrame, m_LocalFrame) ; if ( nInt == 0) { ptInt1 = ptInt ; nInt = 1 ; } else if ( nInt == 1) { ptInt2 = ptInt ; nInt = 2 ; } } } if ( nInt == 2) { dMin = min( ptInt1.z, ptInt2.z) ; dMax = max( ptInt1.z, ptInt2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } // Traslazione ellisse di fondo std::vector vdCoef(3); std::vector vdRoots; vdCoef[0] = dCoef * dCoef * ptCCyl.x * ptCCyl.x + ptCCyl.y * ptCCyl.y + ptCCyl.z * ptCCyl.z - 2 * dCoef * ptCCyl.x * ptCCyl.y - dRad * dRad ; vdCoef[1] = 2 * ( dCoef * dCoef * vtKCyl.x * ptCCyl.x + vtKCyl.y * ptCCyl.y + vtKCyl.z * ptCCyl.z - dCoef * ( vtKCyl.x * ptCCyl.y + vtKCyl.y * ptCCyl.x)) ; vdCoef[2] = dCoef * dCoef * vtKCyl.x * vtKCyl.x + vtKCyl.y * vtKCyl.y + vtKCyl.z * vtKCyl.z - 2 * dCoef * vtKCyl.x * vtKCyl.y ; int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; if ( nRoot == 0 || nRoot == 1) { Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; ptPi.LocToLoc( m_LocalFrame, CylFrame) ; ptPf.LocToLoc( m_LocalFrame, FCylFrame) ; if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { ptPi.LocToLoc( CylFrame, m_LocalFrame) ; ptPf.LocToLoc( FCylFrame, m_LocalFrame) ; dMin = min( ptPi.z, ptPf.z) ; dMax = max( ptPi.z, ptPf.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } else if ( nRoot == 2) { Point3d ptInter1 = ptCCyl + vdRoots[0] * vtKCyl ; Point3d ptInter2 = ptCCyl + vdRoots[1] * vtKCyl ; if ( ptInter1.x > ptInter2.x) { Point3d ptTemp = ptInter1 ; ptInter1 = ptInter2 ; ptInter2 = ptTemp ; } if ( ptInter1.x > 0 && ptInter1.x < dLLong && ptInter2.x > dLLong) { ptInter1.LocToLoc( CylFrame, m_LocalFrame) ; dMin = min( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; dMax = max( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptInter1.x > 0 && ptInter2.x < dLLong) { ptInter1.LocToLoc( CylFrame, m_LocalFrame) ; ptInter2.LocToLoc( CylFrame, m_LocalFrame) ; dMin = min( ptInter1.z, ptInter2.z) ; dMax = max( ptInter1.z, ptInter2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptInter1.x < 0 && ptInter2.x > dLLong) { dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) { ptInter2.LocToLoc( CylFrame, m_LocalFrame) ; dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } // Traslazione ellisse di punta std::vector vdTCoef(3); std::vector vdTRoots; vdTCoef[0] = dCoef * dCoef * ptCTCyl.x * ptCTCyl.x + ptCTCyl.y * ptCTCyl.y + ptCTCyl.z * ptCTCyl.z - 2 * dCoef * ptCTCyl.x * ptCTCyl.y - dRad * dRad ; vdTCoef[1] = 2 * ( dCoef * dCoef * vtKCyl.x * ptCTCyl.x + vtKCyl.y * ptCTCyl.y + vtKCyl.z * ptCTCyl.z - dCoef * ( vtKCyl.x * ptCTCyl.y + vtKCyl.y * ptCTCyl.x)) ; vdTCoef[2] = dCoef * dCoef * vtKCyl.x * vtKCyl.x + vtKCyl.y * vtKCyl.y + vtKCyl.z * vtKCyl.z - 2 * dCoef * vtKCyl.x * vtKCyl.y ; int nTRoot = PolynomialRoots( 2, vdTCoef, vdTRoots) ; if ( nTRoot == 0 || nTRoot == 1) { Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; ptPi.LocToLoc( m_LocalFrame, TCylFrame) ; ptPf.LocToLoc( m_LocalFrame, FTCylFrame) ; if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { ptPi.LocToLoc( TCylFrame, m_LocalFrame) ; ptPf.LocToLoc( FTCylFrame, m_LocalFrame) ; dMin = min( ptPi.z, ptPf.z) ; dMax = max( ptPi.z, ptPf.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } else if ( nTRoot == 2) { Point3d ptTInter1 = ptCTCyl + vdTRoots[0] * vtKCyl ; Point3d ptTInter2 = ptCTCyl + vdTRoots[1] * vtKCyl ; if ( ptTInter1.x > ptTInter2.x) { Point3d ptTemp = ptTInter1 ; ptTInter1 = ptTInter2 ; ptTInter2 = ptTemp ; } if ( ptTInter1.x > 0 && ptTInter1.x < dLLong && ptTInter2.x > dLLong) { ptTInter1.LocToLoc( TCylFrame, m_LocalFrame) ; dMin = min( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; dMax = max( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptTInter1.x > 0 && ptTInter2.x < dLLong) { ptTInter1.LocToLoc( TCylFrame, m_LocalFrame) ; ptTInter2.LocToLoc( TCylFrame, m_LocalFrame) ; dMin = min( ptTInter1.z, ptTInter2.z) ; dMax = max( ptTInter1.z, ptTInter2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptTInter1.x < 0 && ptTInter2.x > dLLong) { dMin = min( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; dMax = max( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } else if ( ptTInter1.x < 0 && ptTInter2.x > 0 && ptTInter2.x < dLLong) { ptTInter2.LocToLoc( TCylFrame, m_LocalFrame) ; dMin = min( ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; dMax = max( ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } } return true ; } */ /* //---------------------------------------------------------------------------- bool VolZmap::MillCyl2( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) { double dMin, dMax ; unsigned int nStartI, nStartJ, nEndI, nEndJ ; bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; if ( ! Control) return true ; // Punti notevoli Point3d ptI = ptLs ; Point3d ptF = ptLe ; Point3d ptIT = ptI - vtToolDir * dHei ; Point3d ptFT = ptF - vtToolDir * dHei ; // Vettori notevoli Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; Vector3d vtLong = ( vtMove * vtToolDir) * vtToolDir ; double dLong = vtLong.Len() ; Vector3d vtOrt = vtMove - vtLong ; double dOrt = vtOrt.Len() ; double dCoef = dOrt / dLong ; double dAng = atan( 1 / dCoef) ; Vector3d vtV1 = vtToolDir ; Vector3d vtV2 = vtOrt ; vtV2.Normalize() ; Vector3d vtV3 = vtV1 ^ vtV2 ; // Definizione dei sistemi di riferimento Frame3d ICylFrame ; ICylFrame.Set( ptI, vtV1, vtV2, vtV3) ; Frame3d FCylFrame ; FCylFrame.Set( ptF, vtV1, vtV2, vtV3) ; Frame3d ITCylFrame ; ITCylFrame.Set( ptIT, vtV1, vtV2, vtV3) ; Frame3d FTCylFrame ; FTCylFrame.Set( ptFT, vtV1, vtV2, vtV3) ; Vector3d vtW1 = vtV1 ; vtW1.Rotate( vtV3, - 180 * dAng / PIGRECO) ; Vector3d vtW2 = vtV2 ; vtW2.Rotate( vtV3, - 180 * dAng / PIGRECO) ; Vector3d vtW3 = vtV3 ; Frame3d RotFrame ; RotFrame.Set( ptI, vtW1, vtW2, vtW3) ; Frame3d TRotFrame ; TRotFrame.Set( ptIT, vtW1, vtW2, vtW3) ; // Altri vettori notevoi Vector3d vtKC = Z_AX ; vtKC.LocToLoc( m_LocalFrame, ICylFrame) ; Vector3d vtRI = ptI - ORIG ; double dDotI = vtRI * vtV1 ; Vector3d vtRF = ptF - ORIG ; double dDotF = vtRF * vtV1 ; Vector3d vtRIT = ptIT - ORIG ; double dDotIT = vtRIT * vtV1 ; Vector3d vtRFT = ptFT - ORIG ; double dDotFT = vtRFT * vtV1 ; Vector3d vtRIPlus = vtRI + dRad * vtW3 ; Vector3d vtRIMinus = vtRI - dRad * vtW3 ; for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ORIG ; // Cilindro iniziale ptC.LocToLoc( m_LocalFrame, ICylFrame) ; std::vector vdICylCoef(3); std::vector vdICylRoots; vdICylCoef[0] = ptC.y * ptC.y + ptC.z * ptC.z - dRad * dRad ; vdICylCoef[1] = 2 * ( ptC.y * vtKC.y + ptC.z * vtKC.z) ; vdICylCoef[2] = vtKC.y * vtKC.y + vtKC.z * vtKC.z ; int nICylRoot = PolynomialRoots( 2, vdICylCoef, vdICylRoots) ; if ( nICylRoot == 0 || nICylRoot == 1) { Point3d ptPb ; ptPb.x = dX ; ptPb.y = dY ; ptPb.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; Point3d ptPt ; ptPt.x = dX ; ptPt.y = dY ; ptPt.z = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; ptPb.LocToLoc( m_LocalFrame, ICylFrame) ; ptPt.LocToLoc( m_LocalFrame, ITCylFrame) ; if ( ptPb.y * ptPb.y + ptPb.z * ptPb.z < dRad * dRad && ptPt.y * ptPt.y + ptPt.z * ptPt.z < dRad * dRad) { ptPb.LocToLoc( ICylFrame, m_LocalFrame) ; ptPt.LocToLoc( ITCylFrame, m_LocalFrame) ; dMin = min( ptPb.z, ptPt.z) ; dMax = max( ptPb.z, ptPt.z) ; SubtractIntervals( i, j, dMin, dMax) ; } } else if ( nICylRoot == 2) { Point3d ptR1 = ptC + vdICylRoots[0] * vtKC ; Point3d ptR2 = ptC + vdICylRoots[1] * vtKC ; if ( ptR1.x > ptR2.x) { Point3d ptTemp = ptR1 ; ptR1 = ptR2 ; ptR2 = ptTemp ; } if ( ptR1.x < - dHei && ptR2.x >= - dHei && ptR2.x < 0) { ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; dMin = min( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; dMax = max( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; SubtractIntervals( i, j, dMin, dMax) ; } else if ( ptR1.x < - dHei && ptR2.x >= 0) { dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; SubtractIntervals( i, j, dMin, dMax) ; } else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x < 0) { ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; dMin = min( ptR1.z, ptR2.z) ; dMax = max( ptR1.z, ptR2.z) ; SubtractIntervals( i, j, dMin, dMax) ; } else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x >= 0) { ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; SubtractIntervals( i, j, dMin, dMax) ; } } // Cilindro finale ptC.LocToLoc( ICylFrame, FCylFrame) ; std::vector vdFCylCoef(3); std::vector vdFCylRoots; vdFCylCoef[0] = ptC.y * ptC.y + ptC.z * ptC.z - dRad * dRad ; vdFCylCoef[1] = 2 * ( ptC.y * vtKC.y + ptC.z * vtKC.z) ; vdFCylCoef[2] = vtKC.y * vtKC.y + vtKC.z * vtKC.z ; int nFCylRoot = PolynomialRoots( 2, vdFCylCoef, vdFCylRoots) ; if ( nFCylRoot == 0 || nFCylRoot == 1) { Point3d ptPb ; ptPb.x = dX ; ptPb.y = dY ; ptPb.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; Point3d ptPt ; ptPt.x = dX ; ptPt.y = dY ; ptPt.z = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; ptPb.LocToLoc( m_LocalFrame, FCylFrame) ; ptPt.LocToLoc( m_LocalFrame, FTCylFrame) ; if ( ptPb.y * ptPb.y + ptPb.z * ptPb.z < dRad * dRad && ptPt.y * ptPt.y + ptPt.z * ptPt.z < dRad * dRad) { ptPb.LocToLoc( FCylFrame, m_LocalFrame) ; ptPt.LocToLoc( FTCylFrame, m_LocalFrame) ; dMin = min( ptPb.z, ptPt.z) ; dMax = max( ptPb.z, ptPt.z) ; SubtractIntervals( i, j, dMin, dMax) ; } } else if ( nFCylRoot == 2) { Point3d ptR1 = ptC + vdFCylRoots[0] * vtKC ; Point3d ptR2 = ptC + vdFCylRoots[1] * vtKC ; if ( ptR1.x > ptR2.x) { Point3d ptTemp = ptR1 ; ptR1 = ptR2 ; ptR2 = ptTemp ; } if ( ptR1.x < - dHei && ptR2.x >= - dHei && ptR2.x < 0) { ptR2.LocToLoc( FCylFrame, m_LocalFrame) ; dMin = min( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; dMax = max( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; SubtractIntervals( i, j, dMin, dMax) ; } else if ( ptR1.x < - dHei && ptR2.x >= 0) { dMin = min( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; dMax = max( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; SubtractIntervals( i, j, dMin, dMax) ; } else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x < 0) { ptR1.LocToLoc( FCylFrame, m_LocalFrame) ; ptR2.LocToLoc( FCylFrame, m_LocalFrame) ; dMin = min( ptR1.z, ptR2.z) ; dMax = max( ptR1.z, ptR2.z) ; SubtractIntervals( i, j, dMin, dMax) ; } else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x >= 0) { ptR1.LocToLoc( FCylFrame, m_LocalFrame) ; dMin = min( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; dMax = max( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; SubtractIntervals( i, j, dMin, dMax) ; } } // Traslazione ellisse fondo ptC.LocToLoc( FCylFrame, ICylFrame) ; std::vector vdEllipseCoef(3); std::vector vdEllipseRoots; vdEllipseCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dRad * dRad ; vdEllipseCoef[1] = 2 * ( dCoef * dCoef * vtKC.x * ptC.x + vtKC.y * ptC.y + vtKC.z * ptC.z - dCoef * ( vtKC.x * ptC.y + vtKC.y * ptC.x)) ; vdEllipseCoef[2] = dCoef * dCoef * vtKC.x * vtKC.x + vtKC.y * vtKC.y + vtKC.z * vtKC.z - 2 * dCoef * vtKC.x * vtKC.y ; int nEllipseRoot = PolynomialRoots( 2, vdEllipseCoef, vdEllipseRoots) ; if ( nEllipseRoot == 0 || nEllipseRoot == 1) { Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; ptPi.LocToLoc( m_LocalFrame, ICylFrame) ; ptPf.LocToLoc( m_LocalFrame, FCylFrame) ; if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { ptPi.LocToLoc( ICylFrame, m_LocalFrame) ; ptPf.LocToLoc( FCylFrame, m_LocalFrame) ; dMin = min( ptPi.z, ptPf.z) ; dMax = max( ptPi.z, ptPf.z) ; SubtractIntervals( i, j, dMin, dMax) ; } } else if ( nEllipseRoot == 2) { Point3d ptR1 = ptC + vdEllipseRoots[0] * vtKC ; Point3d ptR2 = ptC + vdEllipseRoots[1] * vtKC ; if ( ptR1.x > ptR2.x) { Point3d ptTemp = ptR1 ; ptR1 = ptR2 ; ptR2 = ptTemp ; } if ( ptR1.x < 0 && ptR2.x >= 0 && ptR2.x < dLong) { ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; SubtractIntervals( i, j, dMin, dMax) ; } else if ( ptR1.x < 0 && ptR2.x >= dLong) { dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; SubtractIntervals( i, j, dMin, dMax) ; } else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x < dLong) { ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; dMin = min( ptR1.z, ptR2.z) ; dMax = max( ptR1.z, ptR2.z) ; SubtractIntervals( i, j, dMin, dMax) ; } else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x >= dLong) { ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; dMin = min( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; dMax = max( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; SubtractIntervals( i, j, dMin, dMax) ; } } // Traslazione ellisse punta ptC.LocToLoc( ICylFrame, ITCylFrame) ; std::vector vdTEllipseCoef(3); std::vector vdTEllipseRoots; vdTEllipseCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dRad * dRad ; vdTEllipseCoef[1] = 2 * ( dCoef * dCoef * vtKC.x * ptC.x + vtKC.y * ptC.y + vtKC.z * ptC.z - dCoef * ( vtKC.x * ptC.y + vtKC.y * ptC.x)) ; vdTEllipseCoef[2] = dCoef * dCoef * vtKC.x * vtKC.x + vtKC.y * vtKC.y + vtKC.z * vtKC.z - 2 * dCoef * vtKC.x * vtKC.y ; int nTEllipseRoot = PolynomialRoots( 2, vdTEllipseCoef, vdTEllipseRoots) ; if ( nTEllipseRoot == 0 || nTEllipseRoot == 1) { Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; ptPi.LocToLoc( m_LocalFrame, ITCylFrame) ; ptPf.LocToLoc( m_LocalFrame, FTCylFrame) ; if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { ptPi.LocToLoc( ITCylFrame, m_LocalFrame) ; ptPf.LocToLoc( FTCylFrame, m_LocalFrame) ; dMin = min( ptPi.z, ptPf.z) ; dMax = max( ptPi.z, ptPf.z) ; SubtractIntervals( i, j, dMin, dMax) ; } } else if ( nTEllipseRoot == 2) { Point3d ptR1 = ptC + vdTEllipseRoots[0] * vtKC ; Point3d ptR2 = ptC + vdTEllipseRoots[1] * vtKC ; if ( ptR1.x > ptR2.x) { Point3d ptTemp = ptR1 ; ptR1 = ptR2 ; ptR2 = ptTemp ; } if ( ptR1.x < 0 && ptR2.x >= 0 && ptR2.x < dLong) { ptR2.LocToLoc( ITCylFrame, m_LocalFrame) ; dMin = min( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; dMax = max( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; SubtractIntervals( i, j, dMin, dMax) ; } else if ( ptR1.x < 0 && ptR2.x >= dLong) { dMin = min( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; dMax = max( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; SubtractIntervals( i, j, dMin, dMax) ; } else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x < dLong) { ptR1.LocToLoc( ITCylFrame, m_LocalFrame) ; ptR2.LocToLoc( ITCylFrame, m_LocalFrame) ; dMin = min( ptR1.z, ptR2.z) ; dMax = max( ptR1.z, ptR2.z) ; SubtractIntervals( i, j, dMin, dMax) ; } else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x >= dLong) { ptR1.LocToLoc( ITCylFrame, m_LocalFrame) ; dMin = min( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; dMax = max( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; SubtractIntervals( i, j, dMin, dMax) ; } } // Parallelepipedo Point3d ptInt1 = ptC + ( ( ( vtRI - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; Point3d ptInt2 = ptC + ( ( ( vtRI - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; Point3d ptInt3 = ptC + ( ( ( vtRF - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; Point3d ptInt4 = ptC + ( ( ( vtRIT - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; Point3d ptInt5 = ptC + ( ( ( vtRIPlus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; Point3d ptInt6 = ptC + ( ( ( vtRIMinus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; ptInt1.LocToLoc( m_LocalFrame, ICylFrame) ; ptInt2.LocToLoc( m_LocalFrame, RotFrame) ; ptInt3.LocToLoc( m_LocalFrame, FCylFrame) ; ptInt4.LocToLoc( m_LocalFrame, TRotFrame) ; ptInt5.LocToLoc( m_LocalFrame, ICylFrame) ; ptInt6.LocToLoc( m_LocalFrame, ICylFrame) ; bool bFlag = false ; double dLim1, dLim2 ; if ( ptInt1.x >= - dHei && ptInt1.x <= 0 && ptInt1.z >= - dRad && ptInt1.z <= dRad) { ptInt1.LocToLoc( ICylFrame, m_LocalFrame) ; dLim1 = ptInt1.z ; bFlag = true ; } if ( ptInt2.y >= 0 && ptInt2.y <= dLen && ptInt2.z >= - dRad && ptInt2.z <= dRad) { ptInt2.LocToLoc( RotFrame, m_LocalFrame) ; if ( bFlag == false) { dLim1 = ptInt2.z ; bFlag = true ; } else dLim2 = ptInt2.z ; } if ( ptInt3.z >= - dRad && ptInt3.z <= dRad && ptInt3.x >= - dHei && ptInt3.x <= 0) { ptInt3.LocToLoc( FCylFrame, m_LocalFrame) ; if ( bFlag == false) { dLim1 = ptInt3.z ; bFlag = true ; } else dLim2 = ptInt3.z ; } if ( ptInt4.z >= - dRad && ptInt4.z <= dRad && ptInt4.y >= 0 && ptInt4.y <= dLen) { ptInt4.LocToLoc( TRotFrame, m_LocalFrame) ; if ( bFlag == false) { dLim1 = ptInt4.z ; bFlag = true ; } else dLim2 = ptInt4.z ; } if ( ptInt5.y >= 0 && ptInt5.y <= dOrt && ptInt5.x >= - dHei + dCoef * ptInt5.y && ptInt5.x <= dCoef * ptInt5.y) { ptInt5.LocToLoc( ICylFrame, m_LocalFrame) ; if ( bFlag == false) { dLim1 = ptInt5.z ; bFlag = true ; } else dLim2 = ptInt5.z ; } if ( ptInt6.y >= 0 && ptInt6.y <= dOrt && ptInt6.x >= - dHei + dCoef * ptInt6.y && ptInt6.x <= dCoef * ptInt6.y) { ptInt6.LocToLoc( ICylFrame, m_LocalFrame) ; if ( bFlag == false) { dLim1 = ptInt6.z ; bFlag = true ; } else dLim2 = ptInt6.z ; } if ( bFlag == true) { // Una linea non confinata se entra in un volume chiuso ci deve uscire dMin = min( dLim1, dLim2) ; dMax = max( dLim1, dLim2) ; SubtractIntervals( i, j, dMin, dMax) ; } } } return true ; } */ /* //---------------------------------------------------------------------------- bool VolZmap::Conus_XYPerp( unsigned int nGrid, const Point3d ptS, const Point3d ptE, const Vector3d vtToolDir) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; // Verifica sull'interferenza utensile Zmap bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; if ( ! bTest) return true ; // Parametri geometrici dell'utensile double dStemHeigth = m_dHeight - m_dTipHeight ; double dMinRad = min( m_dRadius, m_dTipRadius) ; double dMaxRad = max( m_dRadius, m_dTipRadius) ; double dSqTipRad = m_dTipRadius * m_dTipRadius ; double dSqRad = m_dRadius * m_dRadius ; double dDeltaRad = dMaxRad - dMinRad ; double dSqMinRad = dMinRad * dMinRad ; double dSqMaxRad = dMaxRad * dMaxRad ; // Studio delle simmetrie Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ; Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ; // Vettori caratterizzanti il moto Vector3d vtMove = ptF - ptI ; Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMove.Len() ; double dLenXY = vtMoveXY.LenXY() ; // Quote iniziale e finale double dZI = ptI.z ; double dZF = ptF.z ; // Sistema di riferimento sul piano Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; // Primo vettore del riferimento Vector3d vtV1( - vtToolDir.x, - vtToolDir.y, 0) ; vtV1.Normalize() ; Vector3d vtV2 ; // Movimento verticale if ( dLenXY / dLen < EPS_SMALL) { // Secondo vettore del riferimento vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; double dX1 = vtC * vtV1 ; double dX2 = vtC * vtV2 ; double dr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dX1 - dStemHeigth) / m_dTipHeight ; // Parte cilindrica if ( dX1 > 0 && dX1 < dStemHeigth && abs( dX2) < m_dRadius) { double dH = sqrt( dSqRad - dX2 * dX2) ; SubtractIntervals( nGrid, i, j, dZI - dH, dZF + dH) ; } // Parte conica else if ( dX1 >= dStemHeigth && dX1 < m_dHeight && abs( dX2) < dr) { double dH = sqrt( dr * dr - dX2 * dX2) ; SubtractIntervals ( nGrid, i, j, dZI - dH, dZF + dH) ; } } } } else { // Secondo vettore del riferimento Vector3d vtV2 = vtMoveXY ; vtV2.Normalize() ; // Sistema di riferimento per determinare i piani Vector3d vtW1 = ( m_dHeight > m_dTipHeight ? vtV1 : - vtV1) ; Vector3d vtW2 = vtMove ; vtW2.Normalize() ;// Se vtMove non è suff ort a vtW1 vtMove = vtMoveOrt + vtMoveLong e via Vector3d vtW3 = vtW1 ^ vtW2 ; // Altezza cono double dL = dMaxRad * m_dTipHeight / dDeltaRad ; // Vertice del cono iniziale Point3d ptV = ptI - ( m_dHeight > m_dTipHeight ? ( dStemHeigth + dL) * vtW1 : ( dL - m_dHeight) * vtW1) ; // double dCos = vtW2.z ; double dSin = ( dCos < 1 ? sqrt( 1 - dCos * dCos) : 0) ; double dLimXY = dCos * m_dRadius ; double dLimH = dSin * m_dRadius ; double dDeltaZ = ptF.z - ptI.z ; double dMin, dMax ; // Ciclo sui punti for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; double dX1 = vtC * vtV1 ; double dX2 = vtC * vtV2 ; double dr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dX1 - dStemHeigth) / m_dTipHeight ; // Parte cilindrica if ( dX1 > 0 && dX1 < dStemHeigth && dX2 > - m_dRadius && dX2 < dLenXY + m_dRadius) { // Massimi if ( dX2 < - dLimXY) dMax = dZI + sqrt( dSqRad - dX2 * dX2) ; else if ( dX2 < dLenXY - dLimXY) dMax = dZI + dLimH + dDeltaZ * ( dX2 + dLimXY) / dLenXY ; else dMax = dZF + sqrt( dSqRad - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; // Minimi if ( dX2 < dLimXY) dMin = dZI + sqrt( dSqRad - dX2 * dX2) ; else if ( dX2 < dLenXY + dLimXY) dMin = dZI + dLimH + dDeltaZ * ( dX2 + dLimXY) / dLenXY ; else dMin = dZF + sqrt( dSqRad - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } // Parte conica else if ( dX1 >= dStemHeigth && dX1 < m_dHeight && dX2 > - dr && dX2 < dLenXY + dr) { double dRadLimXY = dr * dCos ; double dRadLimH = dr * dSin ; // Massimi if ( dX2 < - dRadLimXY) dMax = dZI + sqrt( dr * dr - dX2 * dX2) ; else if ( dX2 < dLenXY - dRadLimXY) dMax = dZI + dRadLimH + dDeltaZ * ( dX2 + dRadLimXY) / dLenXY ; else dMax = dZF + sqrt( dr * dr - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; // Minimi if ( dX2 < dRadLimXY) dMin = dZI + sqrt( dr * dr - dX2 * dX2) ; else if ( dX2 < dLenXY + dRadLimXY) dMin = dZI - dRadLimH + dDeltaZ * ( dX2 - dRadLimXY) / dLenXY ; else dMin = dZF + sqrt( dr * dr - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; SubtractIntervals( nGrid, i, j, dMin, dMax) ; } } } } return true ; }*/ // Massimi //if ( dX1 < - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dSqRad * dR2 * dR2)))/* && // dISqDist < dRad * dRad) */ //dMax = dZI + sqrt( dSqRad - dISqDist) ; //else if ( /*dX1 >= - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && */ // dX1 < dPLen - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad)) //dMax = dZI + dR2 * sqrt( dSqRad - dX2 * dX2) + ( dX1 + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad)) * dVLen / dPLen ; //else /*if ( dX1 >= dPLen - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && // dFSqDist < dRad * dRad)*/ //dMax = dZI + dDeltaZ + sqrt( dSqRad - dFSqDist) ; // Minimi // if ( dX1 < dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad))/* && // dISqDist < dRad * dRad) */ // dMin = dZI - sqrt( dSqRad - dISqDist) ; //else if ( /*dX1 >= dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && */ // dX1 < dPLen + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad)) // dMin = dZI - dR2 * sqrt( dSqRad - dX2 * dX2) + ( dX1 - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad)) * dVLen / dPLen ; //else /*if ( dX1 >= dPLen + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && // dFSqDist < dRad * dRad) */ //dMin = dZI + dDeltaZ - sqrt( dSqRad - dFSqDist) ;