0dd8afedf9
- correzioni nell'intersezione di archi tangenti o quasi - pulizia uso distanze e relative costanti minime.
8524 lines
315 KiB
C++
8524 lines
315 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2016
|
|
//----------------------------------------------------------------------------
|
|
// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4
|
|
// Contenuto : Implementazione della classe Volume Zmap (singola griglia)
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 22.01.15 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "VolZmap.h"
|
|
#include "GeoConst.h"
|
|
|
|
using namespace std ;
|
|
|
|
//---------- Sottrazione intervalli ------------------------------------------
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::SubtractIntervals( 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 dMin < dMax
|
|
if ( dMax < dMin )
|
|
swap( dMax, dMin) ;
|
|
|
|
// Calcolo nPos dello spillone
|
|
unsigned int nPos = nJ * m_nNx + nI ;
|
|
|
|
// Ciclo sugli intervalli dello spillone
|
|
bool bModified = false ;
|
|
unsigned int i = 0 ;
|
|
while ( i + 1 < m_ZValues[nPos].size()) {
|
|
|
|
// Intervallo da sottrarre è tutto a sinistra di quello corrente, non vi è intersezione
|
|
if ( m_ZValues[nPos][i] > dMax - EPS_SMALL) {
|
|
;
|
|
}
|
|
|
|
// Intersezione
|
|
else if ( m_ZValues[nPos][i + 1] > dMax + EPS_SMALL) {
|
|
// L'intervallo corrente corrente viene limitato a sinistra
|
|
if ( m_ZValues[nPos][i] > dMin - EPS_SMALL) {
|
|
bModified = true ;
|
|
m_ZValues[nPos][i] = dMax ;
|
|
}
|
|
// L'intervallo si divide in due intervalli
|
|
else {
|
|
bModified = true ;
|
|
m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ;
|
|
|
|
for ( size_t j = m_ZValues[nPos].size() - 1 ; j >= i + 3 ; -- j)
|
|
|
|
m_ZValues[nPos][j] = m_ZValues[nPos][j - 2] ;
|
|
|
|
m_ZValues[nPos][i + 1] = dMin ;
|
|
m_ZValues[nPos][i + 2] = dMax ;
|
|
|
|
i = i + 2 ;
|
|
}
|
|
}
|
|
|
|
else {
|
|
// L'intervallo corrente viene eliminato
|
|
if ( m_ZValues[nPos][i] > dMin - EPS_SMALL) {
|
|
bModified = true ;
|
|
for ( unsigned int j = i ; j < m_ZValues[nPos].size() - 2 ; ++ j)
|
|
|
|
m_ZValues[nPos][j] = m_ZValues[nPos][j + 2] ;
|
|
|
|
m_ZValues[nPos].resize( m_ZValues[nPos].size() - 2) ;
|
|
|
|
i = i - 2 ;
|
|
}
|
|
// L'intervallo corrente viene limitato a destra
|
|
else if ( m_ZValues[nPos][i + 1] > dMin + EPS_SMALL) {
|
|
bModified = true ;
|
|
m_ZValues[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( const Point3d& ptP, double dMin, double dMax)
|
|
{
|
|
// ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame)
|
|
Point3d ptPL = ptP ;
|
|
ptPL.ToLoc( m_LocalFrame) ;
|
|
|
|
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 (indice è l'intero appena più basso)
|
|
double integerPartX = floor( dX / m_dStep) ;
|
|
double integerPartY = floor( dY / m_dStep) ;
|
|
|
|
unsigned int i = static_cast <unsigned int> (integerPartX) ; // Indici del punto di griglia più vicino.
|
|
unsigned int j = static_cast <unsigned int> (integerPartY) ; // i = 0, 1, ..., m_Nx - 1 ; j = 0, 1, ..., m_Ny - 1
|
|
|
|
// Controllo se le coordinate x e y del punto dato siano all'interno della griglia:
|
|
// se sono dentro la griglia chiamo l'altra subtract
|
|
if ( dX < m_dStep * m_nNx &&
|
|
dY < m_dStep * m_nNy &&
|
|
dX >= 0 && dY >= 0) {
|
|
// Mettendo > - qlc può sempre capitare un punto compreso fra - qlc e 0 e
|
|
// si esce dai limiti dell vector e vi è errore runtime
|
|
return SubtractIntervals( i, j, dhMin, dhMax) ;
|
|
}
|
|
|
|
// altrimenti non succede niente
|
|
return true ;
|
|
}
|
|
|
|
//---------- Addizione intervalli --------------------------------------------
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::AddIntervals( 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 dMin < dMax
|
|
if ( dMax < dMin)
|
|
swap( dMax, dMin) ;
|
|
|
|
// Calcolo nPos
|
|
unsigned int nPos = nJ * m_nNx + nI ;
|
|
|
|
// Se spillone vuoto
|
|
if ( m_ZValues[nPos].size() == 0) {
|
|
|
|
m_ZValues[nPos].resize( 2) ;
|
|
|
|
m_ZValues[nPos][0] = dMin ;
|
|
m_ZValues[nPos][1] = dMax ;
|
|
|
|
m_OGrMgr.Reset() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
// Ciclo sugli intervalli dello spillone
|
|
bool bModified = false ;
|
|
unsigned int i = 0 ;
|
|
while ( i + 1 < m_ZValues[nPos].size()) {
|
|
|
|
// Eventuale aggiustamento di intervalli sovrapposti
|
|
if ( i > 0) {
|
|
if ( m_ZValues[nPos][i] < m_ZValues[nPos][i - 1] + EPS_SMALL) {
|
|
// Se l'intervallo corrente non è contenuto totalmente si esegue l'istruzione successiva
|
|
if ( m_ZValues[nPos][i - 1] < m_ZValues[nPos][i + 1] + EPS_SMALL)
|
|
|
|
m_ZValues[nPos][i - 1] = m_ZValues[nPos][i + 1] ;
|
|
|
|
for ( unsigned int j = i ; j < m_ZValues[nPos].size() - 2 ; ++ j)
|
|
m_ZValues[nPos][j] = m_ZValues[nPos][j + 2] ;
|
|
|
|
m_ZValues[nPos].resize( m_ZValues[nPos].size() - 2) ;
|
|
|
|
i = i - 2 ;
|
|
}
|
|
}
|
|
|
|
// Caso in cui devo aggiungere un intervallo a sinistra dell'intervallo corrente
|
|
if ( m_ZValues[nPos][i] > dMax + EPS_SMALL) {
|
|
bModified = true ;
|
|
|
|
m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ;
|
|
|
|
for ( size_t j = m_ZValues[nPos].size() - 1 ; j >= i + 2 ; -- j)
|
|
m_ZValues[nPos][j] = m_ZValues[nPos][j - 2] ;
|
|
|
|
m_ZValues[nPos][i] = dMin ;
|
|
m_ZValues[nPos][i + 1] = dMax ;
|
|
|
|
i = i + 2 ;
|
|
}
|
|
|
|
// Casi d'intersezione:
|
|
else if ( m_ZValues[nPos][i + 1] > dMax - EPS_SMALL) {
|
|
// Se l'intervallo da aggiungere sconfina a sinistra modifico il minimo dell'intervalo corrente
|
|
if ( m_ZValues[nPos][i] > dMin - EPS_SMALL) {
|
|
bModified = true ;
|
|
m_ZValues[nPos][i] = dMin ;
|
|
}
|
|
}
|
|
|
|
else {
|
|
// Se l'intervallo corrente è tutto contenuto nell'intervallo da aggungere modifico gli estremi
|
|
if ( m_ZValues[nPos][i] > dMin + EPS_SMALL) {
|
|
bModified = true ;
|
|
m_ZValues[nPos][i] = dMin ;
|
|
m_ZValues[nPos][i + 1] = dMax ;
|
|
}
|
|
// Se l'intervallo da aggiungere sconfina a destra modifico il massimo dell'intervallo corrente
|
|
else if ( m_ZValues[nPos][i + 1] > dMin - EPS_SMALL) {
|
|
bModified = true ;
|
|
m_ZValues[nPos][i + 1] = dMax ;
|
|
}
|
|
else {
|
|
// Aggiungo intervallo a destra dell'ultimo intervallo
|
|
if ( i == m_ZValues[nPos].size() - 2) {
|
|
bModified = true ;
|
|
m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ;
|
|
|
|
m_ZValues[nPos][i + 2] = dMin ;
|
|
m_ZValues[nPos][i + 3] = dMax ;
|
|
|
|
i = i + 2 ;
|
|
}
|
|
}
|
|
}
|
|
|
|
i = i + 2 ;
|
|
}
|
|
|
|
// se eseguita modifica, imposto ricalcolo della grafica
|
|
if ( bModified)
|
|
m_OGrMgr.Reset() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::AddIntervals( const Point3d& ptP, double dMin, double dMax)
|
|
{
|
|
// ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame)
|
|
Point3d ptPL = ptP ;
|
|
ptPL.ToLoc( m_LocalFrame) ;
|
|
|
|
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 <unsigned int> (integerPartX) ; // Indici del punto di griglia più vicino.
|
|
unsigned int j = static_cast <unsigned int> (integerPartY) ; // i = 0, 1, ..., m_Nx - 1 ; j = 0, 1, ..., m_Ny - 1
|
|
|
|
// Controllo se le coordinate x e y del punto dato siano all'interno della griglia:
|
|
// se sono dentro la griglia chiamo l'altra subtract
|
|
if ( dX < m_dStep*m_nNx && dY < m_dStep*m_nNy
|
|
&& dX >= 0 && dY >= 0) {
|
|
// Mettendo > - qlc può sempre capitare un punto compreso fra - qlc e 0 e
|
|
// si esce dai limiti dell vector e vi è errore runtime
|
|
return AddIntervals( i, j, dhMin, dhMax) ;
|
|
}
|
|
|
|
// altrimenti non succede niente
|
|
return false ;
|
|
}
|
|
|
|
//---------- Volumi ----------------------------------------------------------
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Point3d& ptPe, const Vector3d& vtDe)
|
|
{
|
|
// Controllo sull'effettiva esistenza del movimento
|
|
if ( AreSamePointApprox( ptPs, ptPe) && AreSameVectorApprox( vtDs, vtDe))
|
|
return true ;
|
|
|
|
// Porto i dati del movimento nel riferimento intrinseco; quest'operazione è necessaria perché
|
|
// viene chiamata la funzione di sottrazione che accetta come parametri gli indici,
|
|
// non quella che chiede il punto, nella quale viene eseguita la trasformazione di coordinate.
|
|
Point3d ptLs = ptPs ; ptLs.ToLoc( m_LocalFrame) ;
|
|
Point3d ptLe = ptPe ; ptLe.ToLoc( m_LocalFrame) ;
|
|
Vector3d vtLs = vtDs ; vtLs.ToLoc( m_LocalFrame) ;
|
|
Vector3d vtLe = vtDe ; vtLe.ToLoc( m_LocalFrame) ;
|
|
|
|
// Normalizzo i vettori
|
|
if ( ! vtLs.Normalize() || ! vtLe.Normalize())
|
|
return false ;
|
|
|
|
// Direzione utensile costante
|
|
if ( AreSameVectorApprox( vtLs, vtLe)) {
|
|
|
|
// Versori della direzione utensile diretti come Z
|
|
if ( vtLs.LenXY() < EPS_SMALL) {
|
|
|
|
// Movimento diretto come direzione utensile
|
|
if ( AreSamePointXYApprox( ptLs, ptLe)) {
|
|
if ( m_nToolType == GenericTool)
|
|
return DrillZ( ptLs, ptLe, vtLs) ;
|
|
else
|
|
return DrillingZ( ptLs, ptLe, vtLs) ;
|
|
}
|
|
|
|
// Movimento perpendicolare a direzione utensile
|
|
if ( abs( ptLe.z - ptLs.z) < EPS_SMALL) {
|
|
if ( m_nToolType == 0)
|
|
return MillZ( ptLs, ptLe, vtLs) ;
|
|
else
|
|
return MillingPerpZ( ptLs, ptLe, vtLs) ;
|
|
}
|
|
|
|
// Movimento generico
|
|
if ( m_nToolType == 0)
|
|
return MillZ( ptLs, ptLe, vtLs) ;
|
|
else
|
|
return MillingZ( ptLs, ptLe, vtLs) ;
|
|
}
|
|
|
|
// Versori della direzione utensile nel piano XY
|
|
else if ( abs( vtLs.z) < EPS_SMALL) {
|
|
|
|
Vector3d vtDir( vtLs.x, vtLs.y, 0) ; vtDir.Normalize() ;
|
|
|
|
// Movimento con Z costante (con vettore movimento parallelo od ortogonale al versore dell'utensile)
|
|
if ( abs( ptLe.z - ptLs.z) < EPS_SMALL) {
|
|
|
|
Vector3d vtTest( ptLe.x - ptLs.x, ptLe.y - ptLs.y, 0) ;
|
|
Vector3d vtTLong = ( vtTest * vtDir) * vtDir ;
|
|
Vector3d vtTOrt = vtTest - vtTLong ;
|
|
|
|
// Movimento parallelo alla direzione dell'utensile (foratura)
|
|
if ( vtTOrt.IsSmall()) {
|
|
if ( m_nToolType == 0)
|
|
return DrillingGT( ptLs, ptLe, vtDir) ;
|
|
else
|
|
return DrillingXY( ptLs, ptLe, vtDir) ;
|
|
}
|
|
|
|
// Movimento perpendicolare alla direzione dell'utensile
|
|
if ( vtTLong.IsSmall()) {
|
|
if ( m_nToolType == GenericTool)
|
|
return MillingGT( ptLs, ptLe, vtDir) ;
|
|
else
|
|
return MillingPerpXY( ptLs, ptLe, vtDir) ;
|
|
}
|
|
|
|
// Movimento nel piano generico
|
|
if ( m_nToolType == GenericTool)
|
|
return MillingGT( ptLs, ptLe, vtDir) ;
|
|
else
|
|
return MillingXYPlaneGen( ptLs, ptLe, vtDir) ;
|
|
}
|
|
|
|
// Movimento con Z non costante
|
|
else {
|
|
|
|
if ( m_nToolType == GenericTool)
|
|
return MillingGT( ptLs, ptLe, vtDir) ;
|
|
|
|
// Movimento verticale
|
|
if ( AreSamePointXYApprox( ptLs, ptLe))
|
|
return MillingXYVert( ptLs, ptLe, vtDir) ;
|
|
|
|
// Grandezze geometriche per selezione
|
|
Vector3d vtMove = ptLe - ptLs ;
|
|
Vector3d vtTLong = ( vtMove * vtDir) * vtDir ;
|
|
Vector3d vtTOrt = vtMove - ( vtMove * vtDir) * vtDir ;
|
|
|
|
// Movimento LongVert
|
|
if ( vtTOrt.IsSmallXY())
|
|
return MillingXYLongVert( ptLs, ptLe, vtDir) ;
|
|
|
|
// Movimento perpendicolare alla direzione dell'utensile
|
|
if ( vtTLong.IsSmallXY())
|
|
return MillingXY( ptLs, ptLe, vtDir) ;
|
|
|
|
// Movimento generico con versore direzione nel piano
|
|
return Milling( ptLs, ptLe, vtDir) ;
|
|
}
|
|
}
|
|
|
|
// Caso generico
|
|
else {
|
|
|
|
Vector3d vtMove = ptLe - ptLs ;
|
|
Vector3d vtOrt = vtMove - ( vtMove * vtLs) * vtLs ;
|
|
|
|
// Drilling
|
|
if ( vtOrt.IsSmall()) {
|
|
if ( m_nToolType == GenericTool)
|
|
return DrillingGT( ptLs, ptLe, vtLs) ;
|
|
else
|
|
return Drilling( ptLs, ptLe, vtLs) ;
|
|
}
|
|
// Milling
|
|
else {
|
|
if ( m_nToolType == GenericTool)
|
|
return MillingGT( ptLs, ptLe, vtLs) ;
|
|
else
|
|
return Milling( ptLs, ptLe, vtLs) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Altri casi, non gestiti
|
|
return false ;
|
|
}
|
|
|
|
// Versore utensile parallelo all'asse Z
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::DrillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
// Cilindro sfera toro
|
|
if ( m_nToolType == CylindricalMill || m_nToolType == BallEndMill ||
|
|
m_nToolType == BullNoseMill)
|
|
|
|
return CBTDrillZ( ptLs, ptLe, vtToolDir) ;
|
|
// Coni
|
|
else if ( m_nToolType == ConusMill)
|
|
|
|
return ConusDrillingZ( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else
|
|
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::CBTDrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
// Bounding box
|
|
double dMinX = min( ptLs.x, ptLe.x) - m_dRadius ;
|
|
double dMinY = min( ptLs.y, ptLe.y) - m_dRadius ;
|
|
double dMaxX = max( ptLs.x, ptLe.x) + m_dRadius ;
|
|
double dMaxY = max( ptLs.y, ptLe.y) + m_dRadius ;
|
|
|
|
// Verifico interferisca con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
|
|
// Determino i limiti sugli indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
// Determino quote estreme del tagliente
|
|
double dMax = ptLs.z - m_dHeight ; // Volendo si può effettuare un controllo su quota punto finale e iniziale,
|
|
double dMin = ptLe.z - m_dHeight ; // ma non è necessaria dal momento che Subtract intervals scambia min con max se max < min
|
|
double dZCutBase = ptLs.z ; // Quota della base del tagliente nella posizione iniziale
|
|
double dDeltaZ = ptLe.z - ptLs.z ; // Differenza delle quote fra le posizioni finale e iniziale della base del tagliente
|
|
|
|
// Limite sul quadrato del raggio
|
|
double dSqRad = ( m_dRadius + EPS_SMALL) * ( m_dRadius + EPS_SMALL) ;
|
|
|
|
// Ciclo sui punti nei limiti
|
|
for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) {
|
|
double dX = ( i + 0.5) * m_dStep ;
|
|
for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
double dY = ( j + 0.5) * m_dStep ;
|
|
// punto
|
|
Point3d ptQ( dX, dY, 0) ;
|
|
// determino il quadrato della distanza
|
|
double dSqDist = SqDistXY( ptQ, ptLe) ;
|
|
// se distanza nei limiti, taglio
|
|
if ( dSqDist < dSqRad)
|
|
GetMinMaxZ( i, j, dZCutBase, dDeltaZ, dSqDist, vtToolDir) ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ConusDrillingZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) {
|
|
|
|
double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight),
|
|
min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ;
|
|
double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight),
|
|
max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ;
|
|
|
|
// Prima verifica sull'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL)
|
|
return true ;
|
|
|
|
double dMaxRad = max( m_dRadius, m_dTipRadius) ;
|
|
double dMinRad = min( m_dRadius, m_dTipRadius) ;
|
|
|
|
// Bounding box
|
|
double dMinX = ptLs.x - dMaxRad ;
|
|
double dMaxX = ptLs.x + dMaxRad ;
|
|
double dMinY = ptLs.y - dMaxRad ;
|
|
double dMaxY = ptLs.y + dMaxRad ;
|
|
|
|
// Seconda verifica dell'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
|
|
double dDeltaZ = abs( ptLe.z - ptLs.z) ;
|
|
|
|
Point3d ptO( ptLs.x, ptLs.y, 0) ;
|
|
|
|
// Limiti su indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
|
|
if ( m_dRadius < m_dTipRadius)
|
|
// Coda di rondine
|
|
return GetMinMaxZSw( ptO, nStartI, nEndI, nStartJ, nEndJ, dMinZ, dMaxZ, dMinRad, dMaxRad, vtToolDir.z, dDeltaZ) ;
|
|
// Punta di trapano
|
|
else
|
|
return GetMinMaxZDr( ptO, nStartI, nEndI, nStartJ, nEndJ, dMinZ, dMaxZ, dMinRad, dMaxRad, vtToolDir.z, dDeltaZ) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
inline bool
|
|
VolZmap::GetMinMaxZSw( const Point3d ptO, unsigned int nStartI, unsigned int nEndI,
|
|
unsigned int nStartJ, unsigned int nEndJ, double dMinZ, double dMaxZ,
|
|
double dMinRad, double dMaxRad, double dDir, double dDeltaZ)
|
|
{
|
|
for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) {
|
|
|
|
for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
|
|
// Determinazione della posizione xy del dexel rispetto
|
|
// all'asse di simmetria dell'utensile
|
|
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 ;
|
|
|
|
// Se il dexel cade nel cerchio di interesse taglio
|
|
if ( dSqDist < dMaxRad * dMaxRad) {
|
|
|
|
double dMin, dMax ;
|
|
|
|
if ( dSqDist < dMinRad * dMinRad) {
|
|
dMin = dMinZ ;
|
|
dMax = dMaxZ ;
|
|
}
|
|
|
|
else {
|
|
double dR = sqrt( dSqDist) ;
|
|
if ( dDir > 0) {
|
|
dMin = dMinZ ;
|
|
dMax = dMinZ + dDeltaZ + ( m_dTipHeight * ( dMaxRad - dR)) / ( dMaxRad - dMinRad) ;
|
|
}
|
|
else {
|
|
dMin = dMaxZ - dDeltaZ + ( m_dTipHeight * ( dR - dMaxRad)) / ( dMaxRad - dMinRad) ;
|
|
dMax = dMaxZ ;
|
|
}
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
inline bool
|
|
VolZmap::GetMinMaxZDr( const Point3d ptO, unsigned int nStartI, unsigned int nEndI,
|
|
unsigned int nStartJ, unsigned int nEndJ, double dMinZ, double dMaxZ,
|
|
double dMinRad, double dMaxRad, double dDir, double dDeltaZ)
|
|
{
|
|
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 ;
|
|
|
|
// Se il dexel cade nel cerchio di interesse taglio
|
|
if ( dSqDist < dMaxRad * dMaxRad) {
|
|
|
|
double dMin, dMax ;
|
|
|
|
if ( dSqDist < dMinRad * dMinRad) {
|
|
dMin = dMinZ ;
|
|
dMax = dMaxZ ;
|
|
}
|
|
|
|
else {
|
|
double dR = sqrt( dSqDist) ;
|
|
if ( dDir > 0) {
|
|
dMin = dMinZ + ( m_dTipHeight * ( dR - dMinRad)) / ( dMaxRad - dMinRad) ;
|
|
dMax = dMaxZ ;
|
|
}
|
|
else {
|
|
dMin = dMinZ ;
|
|
dMax = dMaxZ + ( m_dTipHeight * ( dR - dMinRad)) / ( dMinRad - dMaxRad) ;
|
|
}
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) {
|
|
// Cilindro sfera toro
|
|
if ( m_nToolType == CylindricalMill ||
|
|
m_nToolType == BallEndMill ||
|
|
m_nToolType == BullNoseMill)
|
|
|
|
return CBTMillingPerpZ( ptLs, ptLe, vtToolDir) ;
|
|
// Coni
|
|
else if ( m_nToolType == ConusMill)
|
|
|
|
return ConusPerpZ( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::CBTMillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
// Bounding box
|
|
double dMinX = min( ptLs.x, ptLe.x) - m_dRadius ;
|
|
double dMinY = min( ptLs.y, ptLe.y) - m_dRadius ;
|
|
double dMaxX = max( ptLs.x, ptLe.x) + m_dRadius ;
|
|
double dMaxY = max( ptLs.y, ptLe.y) + m_dRadius ;
|
|
|
|
// Verifico interferisca con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
|
|
// Determino i limiti sugli indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
// Determino quote estreme del tagliente
|
|
double dZCutBase = ptLs.z ; // Quota della base del tagliente nella posizione iniziale
|
|
double dDeltaZ = ptLe.z - ptLs.z ; // Differenza delle quote fra le posizioni finale e iniziale della base del tagliente
|
|
|
|
// Limite sul quadrato del raggio
|
|
double dSqRad = ( m_dRadius + EPS_SMALL) * ( m_dRadius + EPS_SMALL) ;
|
|
|
|
// Segmento di movimento (nel piano griglia)
|
|
Point3d ptStart( ptLs.x, ptLs.y, 0) ;
|
|
Point3d ptEnd( ptLe.x, ptLe.y, 0) ;
|
|
double dLen ;
|
|
Vector3d vtDir ;
|
|
DirDist( ptStart, ptEnd, vtDir, dLen) ;
|
|
|
|
// Ciclo sui punti nei limiti
|
|
for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) {
|
|
double dX = ( i + 0.5) * m_dStep ;
|
|
for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
double dY = ( j + 0.5) * m_dStep ;
|
|
// punto
|
|
Point3d ptQ( dX, dY, 0) ;
|
|
// determino il quadrato della distanza del punto dal segmento
|
|
double dProiez = vtDir * ( ptQ - ptStart) ;
|
|
if ( dProiez < 0)
|
|
dProiez = 0 ;
|
|
else if ( dProiez > dLen)
|
|
dProiez = dLen ;
|
|
Point3d ptMinDist = ptStart + vtDir * dProiez ;
|
|
double dSqDist = SqDistXY( ptQ, ptMinDist) ;
|
|
// se distanza nei limiti, taglio
|
|
if ( dSqDist < dSqRad)
|
|
GetMinMaxZ( i, j, dZCutBase, dDeltaZ, dSqDist, vtToolDir) ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ConusPerpZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir)
|
|
{
|
|
double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ;
|
|
double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ;
|
|
|
|
// Prima verifica sull'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL)
|
|
return true ;
|
|
|
|
double dMaxRad = max( m_dRadius, m_dTipRadius) ;
|
|
double dMinRad = min( m_dRadius, m_dTipRadius) ;
|
|
|
|
// Bounding box
|
|
double dMinX = min( ptLs.x, ptLe.x) - dMaxRad ;
|
|
double dMaxX = max( ptLs.x, ptLe.x) + dMaxRad ;
|
|
double dMinY = min( ptLs.y, ptLe.y) - dMaxRad ;
|
|
double dMaxY = max( ptLs.y, ptLe.y) + dMaxRad ; // Ricordati del caso balordo da mettere nella documentazione
|
|
|
|
// Seconda verifica dell'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
|
|
Point3d ptO( ptLs.x, ptLs.y, 0) ;
|
|
Vector3d vtMove = ptLe - ptLs ; double dLen = vtMove.LenXY() ;
|
|
Vector3d vtV1 = vtMove ; vtV1.Normalize() ;
|
|
|
|
double dZBase = ptLs.z ;
|
|
double dZStem = ptLs.z - ( m_dHeight - m_dTipHeight) * vtToolDir.z ;
|
|
double dZTip = ptLs.z - m_dHeight * vtToolDir.z ;
|
|
|
|
// Limiti su indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
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 ;
|
|
|
|
double dProj1 = vtC * vtV1 ;
|
|
Vector3d vtOrt = vtC - dProj1 * vtV1 ;
|
|
|
|
if ( dProj1 < 0) {
|
|
|
|
double dSqDist = vtC * vtC ;
|
|
|
|
if ( dSqDist < dMinRad * dMinRad) {
|
|
|
|
dMin = min( dZBase, dZTip) ;
|
|
dMax = max( dZBase, dZTip) ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
|
|
else if ( dSqDist >= dMinRad * dMinRad && dSqDist < dMaxRad * dMaxRad) {
|
|
|
|
double dr = sqrt( dSqDist) ;
|
|
|
|
if ( m_dRadius < m_dTipRadius) {
|
|
|
|
dMin = min( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ;
|
|
dMax = max( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ;
|
|
}
|
|
else {
|
|
dMin = min( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ;
|
|
dMax = max( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ;
|
|
}
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
|
|
else if ( dProj1 >= 0 && dProj1 < dLen) {
|
|
|
|
double dSqDist = vtOrt * vtOrt ;
|
|
|
|
if ( dSqDist < dMinRad * dMinRad) {
|
|
|
|
dMin = min( dZBase, dZTip) ;
|
|
dMax = max( dZBase, dZTip) ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
|
|
else if ( dSqDist >= dMinRad * dMinRad && dSqDist < dMaxRad * dMaxRad) {
|
|
|
|
double dr = sqrt( dSqDist) ;
|
|
|
|
if ( m_dRadius < m_dTipRadius) {
|
|
dMin = min( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ;
|
|
dMax = max( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ;
|
|
}
|
|
|
|
else {
|
|
dMin = min( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ;
|
|
dMax = max( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ;
|
|
}
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
|
|
else if ( dProj1 >= dLen) {
|
|
|
|
Vector3d vtCn = vtC - vtMove ;
|
|
|
|
double dSqDist = vtCn * vtCn ;
|
|
|
|
if ( dSqDist < dMinRad * dMinRad) {
|
|
dMin = min( dZBase, dZTip) ;
|
|
dMax = max( dZBase, dZTip) ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
|
|
else if ( dSqDist >= dMinRad * dMinRad && dSqDist < dMaxRad * dMaxRad) {
|
|
|
|
double dr = sqrt( dSqDist) ;
|
|
|
|
if ( m_dRadius < m_dTipRadius) {
|
|
dMin = min( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ;
|
|
dMax = max( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ;
|
|
}
|
|
|
|
else {
|
|
dMin = min( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ;
|
|
dMax = max( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ;
|
|
}
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
inline bool
|
|
VolZmap::GetMinMaxZ( unsigned int nI, unsigned int nJ, double dZCutBase,
|
|
double dDeltaZ, double dSqDist, const Vector3d& vtToolDir)
|
|
{
|
|
// Definisco variabili
|
|
double dSqRad = m_dRadius * m_dRadius ;
|
|
double dFactor = ( vtToolDir.z < 0 ? - 1 : 1) ;
|
|
double dZtip = ( vtToolDir.z < 0 ? dZCutBase + m_dHeight : dZCutBase - m_dHeight) ;
|
|
|
|
// Caso utensile generico al momento non gestito
|
|
if ( m_nToolType == 0)
|
|
return false ;
|
|
|
|
// Caso Cylindrical Mill
|
|
else if ( m_nToolType == 1) {
|
|
double dMin, dMax ;
|
|
|
|
if ( abs(vtToolDir.z * dDeltaZ) < EPS_SMALL) { // Non è meglio fare if (vt * delta < - Eps_small ) else if ( vt * delta < Eps) else ?
|
|
dMin = min(dZCutBase, dZtip) ;
|
|
dMax = max(dZCutBase, dZtip) ;
|
|
}
|
|
else if ( vtToolDir.z * dDeltaZ < 0) {
|
|
dMin = min(dZtip, dZtip + dDeltaZ) ;
|
|
dMax = max(dZtip, dZtip + dDeltaZ) ;
|
|
}
|
|
else {
|
|
dMin = min(dZCutBase, dZCutBase + dDeltaZ) ;
|
|
dMax = max(dZCutBase, dZCutBase + dDeltaZ) ;
|
|
}
|
|
return SubtractIntervals( nI, nJ, dMin, dMax) ;
|
|
}
|
|
|
|
// Caso Ball-End Mill
|
|
else if ( m_nToolType == 2) {
|
|
double dMin, dMax ;
|
|
|
|
double dH = sqrt( dSqRad - dSqDist) ;
|
|
|
|
if ( abs( vtToolDir.z * dDeltaZ) < EPS_SMALL) {
|
|
dMin = min( dZCutBase, dZtip + dFactor*( m_dRadius - dH)) ;
|
|
dMax = max( dZCutBase, dZtip + dFactor*( m_dRadius - dH)) ;
|
|
}
|
|
else if ( vtToolDir.z * dDeltaZ < 0) {
|
|
dMin = min( dZtip + dFactor*( m_dRadius - dH),
|
|
dZtip + dFactor*( m_dRadius - dH) + dDeltaZ) ;// ocio
|
|
dMax = max( dZtip + dFactor*( m_dRadius - dH),
|
|
dZtip + dFactor*( m_dRadius - dH) + dDeltaZ) ;// ocio
|
|
}
|
|
else {
|
|
dMin = min( dZCutBase, dZCutBase + dDeltaZ) ;
|
|
dMax = max( dZCutBase, dZCutBase + dDeltaZ) ;
|
|
}
|
|
return SubtractIntervals( nI, nJ, dMin, dMax) ;
|
|
}
|
|
|
|
// Caso Bull-Nose Mill
|
|
else if ( m_nToolType == 3) {
|
|
|
|
double dDeltaR = m_dRadius - m_dRCorner ;
|
|
|
|
if ( dSqDist < dDeltaR*dDeltaR) {
|
|
|
|
double dMin, dMax ;
|
|
|
|
if ( abs( vtToolDir.z * dDeltaZ) < EPS_SMALL) {
|
|
dMin = min( dZCutBase, dZtip) ;
|
|
dMax = max( dZCutBase, dZtip) ;
|
|
}
|
|
else if ( vtToolDir.z * dDeltaZ < 0) {
|
|
dMin = min( dZtip, dZtip + dDeltaZ) ;
|
|
dMax = max( dZtip, dZtip + dDeltaZ) ;
|
|
}
|
|
else {
|
|
dMin = min( dZCutBase, dZCutBase + dDeltaZ) ;
|
|
dMax = max( dZCutBase, dZCutBase + dDeltaZ) ;
|
|
}
|
|
return SubtractIntervals( nI, nJ, dMin, dMax) ;
|
|
}
|
|
|
|
else {
|
|
|
|
double dSqRadC = m_dRCorner * m_dRCorner ;
|
|
double dSqd = dSqDist + dDeltaR * dDeltaR - 2 * sqrt( dSqDist) * dDeltaR ;
|
|
double dSqrt = sqrt(dSqRadC - dSqd) ;
|
|
|
|
double dMin, dMax ;
|
|
if ( abs( vtToolDir.z * dDeltaZ) < EPS_SMALL) {
|
|
dMin = min( dZCutBase, dZtip + dFactor*( m_dRCorner - dSqrt)) ;
|
|
dMax = max( dZCutBase, dZtip + dFactor*( m_dRCorner - dSqrt)) ;
|
|
}
|
|
else if ( vtToolDir.z * dDeltaZ < 0) {
|
|
dMin = min( dZtip + dFactor *( m_dRCorner - dSqrt),
|
|
dZtip + dFactor *( m_dRCorner - dSqrt) + dDeltaZ) ;
|
|
dMax = max( dZtip + dFactor *( m_dRCorner - dSqrt),
|
|
dZtip + dFactor *( m_dRCorner - dSqrt) + dDeltaZ) ;
|
|
}
|
|
else {
|
|
dMin = min( dZCutBase, dZCutBase + dDeltaZ) ;
|
|
dMax = max( dZCutBase, dZCutBase + dDeltaZ) ;
|
|
}
|
|
return SubtractIntervals( nI, nJ, dMin, dMax) ;
|
|
}
|
|
}
|
|
|
|
// Caso di utensile inesistente ( m_nToolType fuori dai valori concessi)
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
|
|
if ( m_nToolType == 1 || m_nToolType == 2)
|
|
|
|
return CBMillingZ( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else if ( m_nToolType == 3)
|
|
|
|
return false ;
|
|
|
|
else if ( m_nToolType == 4) {
|
|
|
|
if ( m_dRadius > m_dTipRadius)
|
|
return ConusMillingZDr( ptLs, ptLe, vtToolDir) ;
|
|
else
|
|
return ConusMillingZSw( ptLs, ptLe, vtToolDir) ;
|
|
}
|
|
|
|
else
|
|
return true ; // forse ci va il nuovo
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::CBMillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
// Setto il fattore per l'orientazione in z
|
|
double dFactor = ( vtToolDir.z < 0 ? 1 : - 1) ;
|
|
|
|
// Bounding box
|
|
double dMinX = min( ptLs.x, ptLe.x) - m_dRadius ;
|
|
double dMaxX = max( ptLs.x, ptLe.x) + m_dRadius ;
|
|
double dMinY = min( ptLs.y, ptLe.y) - m_dRadius ;
|
|
double dMaxY = max( ptLs.y, ptLe.y) + m_dRadius ;
|
|
double dMinZ = min( min( ptLs.z, ptLs.z + dFactor * m_dHeight),
|
|
min( ptLe.z, ptLe.z + dFactor * m_dHeight)) ;
|
|
double dMaxZ = max( max( ptLs.z, ptLs.z + dFactor * m_dHeight),
|
|
max( ptLe.z, ptLe.z + dFactor * m_dHeight)) ;
|
|
|
|
// Verifico interferisca con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL)
|
|
return true ;
|
|
|
|
// Determino i limiti sugli indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
//
|
|
double dZCutBase = ptLs.z ; // Quota della base del tagliente nella posizione iniziale
|
|
double dDeltaZ = ptLe.z - ptLs.z ; // Differenza delle quote fra le posizioni finale e iniziale della base del tagliente
|
|
|
|
// Limite sul quadrato del raggio
|
|
double dSqRad = ( m_dRadius + EPS_SMALL) * ( m_dRadius + EPS_SMALL) ;
|
|
|
|
// Segmento di movimento (nel piano griglia)
|
|
Point3d ptStart( ptLs.x, ptLs.y, 0) ;
|
|
Point3d ptEnd( ptLe.x, ptLe.y, 0) ;
|
|
double dLen ;
|
|
Vector3d vtDir ;
|
|
DirDist( ptStart, ptEnd, vtDir, dLen) ;
|
|
|
|
// Ciclo sui punti nei limiti
|
|
for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) {
|
|
double dX = ( i + 0.5) * m_dStep ;
|
|
for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
double dY = ( j + 0.5) * m_dStep ;
|
|
// punto
|
|
Point3d ptQ( dX, dY, 0) ;
|
|
// determino il quadrato della distanza del punto dal segmento
|
|
double dProj = vtDir * ( ptQ - ptStart) ;
|
|
double dProiez ;
|
|
|
|
if ( dProj < 0)
|
|
dProiez = 0 ;
|
|
else if ( dProj < dLen)
|
|
dProiez = dProj ;
|
|
else
|
|
dProiez = dLen ;
|
|
|
|
Point3d ptMinDist = ptStart + vtDir * dProiez ;
|
|
double dSqDist = SqDistXY( ptQ, ptMinDist) ;
|
|
|
|
// se distanza nei limiti, taglio
|
|
if ( dSqDist < dSqRad)
|
|
GetMinMaxZGen( i, j, dProj, dSqDist, dLen, dZCutBase, dDeltaZ, vtToolDir) ;
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ConusMillingZDr( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir)
|
|
{
|
|
double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight),
|
|
min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ;
|
|
double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight),
|
|
max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ;
|
|
|
|
// Prima verifica sull'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL)
|
|
return true ;
|
|
|
|
double dMaxRad = max( m_dRadius, m_dTipRadius) ;
|
|
double dMinRad = min( m_dRadius, m_dTipRadius) ;
|
|
|
|
// Bounding box
|
|
double dMinX = min( ptLs.x, ptLe.x) - dMaxRad ;
|
|
double dMaxX = max( ptLs.x, ptLe.x) + dMaxRad ;
|
|
double dMinY = min( ptLs.y, ptLe.y) - dMaxRad ;
|
|
double dMaxY = max( ptLs.y, ptLe.y) + dMaxRad ;
|
|
|
|
// Seconda verifica dell'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
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) ;
|
|
}
|
|
|
|
// 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 ;
|
|
|
|
// Limiti su indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
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( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ConusMillingZSw( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir)
|
|
{
|
|
double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight),
|
|
min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ;
|
|
double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight),
|
|
max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ;
|
|
|
|
// Prima verifica sull'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL)
|
|
return true ;
|
|
|
|
double dMaxRad = max( m_dRadius, m_dTipRadius) ;
|
|
double dMinRad = min( m_dRadius, m_dTipRadius) ;
|
|
|
|
// Bounding box
|
|
double dMinX = min( ptLs.x, ptLe.x) - dMaxRad ;
|
|
double dMaxX = max( ptLs.x, ptLe.x) + dMaxRad ;
|
|
double dMinY = min( ptLs.y, ptLe.y) - dMaxRad ;
|
|
double dMaxY = max( ptLs.y, ptLe.y) + dMaxRad ;
|
|
|
|
// Seconda verifica dell'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
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 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 ;
|
|
|
|
// Limiti su indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
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( 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( i, j, dMin, dMax) ;
|
|
|
|
}
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
inline bool
|
|
VolZmap::GetMinMaxZGen( unsigned int nI, unsigned int nJ, double dProj, double dSqd,
|
|
double dLenPath, double dZheight, double dDelta, const Vector3d& vtToolDir)
|
|
{
|
|
// Controllo sul tipo di utensile: se 0 utensile generico (al momento non gestito) se maggiore di 3 utensile fuori dai tipi consentiti
|
|
if ( m_nToolType == 0 || m_nToolType > 3)
|
|
return false ;
|
|
|
|
// Definisco variabili quota della punta, minimo e massimo dell'intervallo da sottrarre
|
|
double dZTip = ( vtToolDir.z < 0 ? dZheight + m_dHeight : dZheight - m_dHeight) ;
|
|
double dMin, dMax ; double dStart ; // dStart è un parametro che esprime l'ascissa in cui la retta congiungente le due posizioni iniziale e finale
|
|
double dRSqDist1, dRSqDist2 ; // di un punto del tagliente (nel sistema dell'asse dell'utensile nella posizione iniziale) assume la quota dZheight
|
|
|
|
// Nei conti è comodo che dSqd assuma sempre il significato di distanza del punto dall'asse del movimento al quadrato
|
|
if ( dProj < 0)
|
|
dSqd = dSqd - dProj * dProj ;
|
|
else if ( dProj > dLenPath)
|
|
dSqd = dSqd - ( dProj - dLenPath) * ( dProj - dLenPath) ;
|
|
|
|
// Caso di cylindrical mill
|
|
if ( m_nToolType == 1) {
|
|
|
|
double dZ1, dZ2 ;
|
|
// Se lavora la punta
|
|
if ( vtToolDir.z * dDelta < 0) {
|
|
dZ1 = dZTip ;
|
|
dZ2 = dZheight ;
|
|
}
|
|
// Se lavora il fondo
|
|
else {
|
|
dZ1 = dZheight ;
|
|
dZ2 = dZTip ;
|
|
}
|
|
|
|
dStart = sqrt( m_dRadius * m_dRadius - dSqd) ;
|
|
dRSqDist1 = dProj * dProj + dSqd ;
|
|
dRSqDist2 = ( dLenPath - dProj) * ( dLenPath - dProj) + dSqd ;
|
|
|
|
if ( dRSqDist1 < (m_dRadius + EPS_SMALL) * (m_dRadius + EPS_SMALL)) {
|
|
|
|
dMin = min( max( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ1 + dDelta), dZ2) ;
|
|
dMax = max( min( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ1 + dDelta), dZ2) ;
|
|
}
|
|
else if ( dRSqDist2 < (m_dRadius + EPS_SMALL) * (m_dRadius + EPS_SMALL)) {
|
|
|
|
dMin = min( min(dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath, dZ2 + dDelta), dZ1 + dDelta) ;
|
|
dMax = max( max(dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath, dZ2 + dDelta), dZ1 + dDelta) ;
|
|
}
|
|
else {
|
|
|
|
dMin = min( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath) ;
|
|
dMax = max( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath) ;
|
|
}
|
|
}
|
|
|
|
// Caso di ball-end mill
|
|
else if ( m_nToolType == 2) {
|
|
|
|
if ( dDelta < 0) {
|
|
dDelta = - dDelta ;
|
|
dProj = dLenPath - dProj ;
|
|
dZheight = dZheight - dDelta ;
|
|
dZTip = dZTip - dDelta ;
|
|
}
|
|
|
|
dStart = sqrt( m_dRadius * m_dRadius - dSqd) ;
|
|
dRSqDist1 = dProj * dProj + dSqd ;
|
|
dRSqDist2 = ( dLenPath - dProj) * ( dLenPath - dProj) + dSqd ;
|
|
|
|
if ( vtToolDir.z > 0) {
|
|
|
|
// Semi-asse ellisse
|
|
double dSemiAxMin = m_dRadius * sqrt( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ;
|
|
double dSqrSemiAxMin = m_dRadius * m_dRadius * ( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ;
|
|
double dXD2 = ( dProj - dLenPath) * ( dProj - dLenPath) ;
|
|
|
|
if ( dRSqDist2 < m_dRadius * m_dRadius) {
|
|
|
|
dMax = dZheight + dDelta ;
|
|
|
|
double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ;
|
|
|
|
if ( dProj - dLenPath > dSemiAxMin * dTest) {
|
|
|
|
double dSqrRad = ( dProj - dLenPath) * ( dProj - dLenPath) + dSqd ;
|
|
double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ;
|
|
dMin = dZTip + m_dRadius + dDelta - dH ;
|
|
}
|
|
else if ( dProj > dSemiAxMin * dTest) {
|
|
// Determino l'altezza del punto sull'ellisse da cui passa la retta
|
|
double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dLenPath + dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : dLenPath) ;
|
|
double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ;
|
|
double dZ0 = ( ( dPr0 - dLenPath) * dPar) / dSemiAxMin ;
|
|
|
|
dMin = dZTip + dDelta + m_dRadius - dZ0 + ( dDelta / dLenPath) * ( dProj - dPr0) ;
|
|
}
|
|
else {
|
|
|
|
double dSqrRad = dProj * dProj + dSqd ;
|
|
double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ;
|
|
dMin = dZTip + m_dRadius - dH ;
|
|
}
|
|
}
|
|
else {
|
|
|
|
dMax = dZheight + ( dDelta * ( dProj + dStart)) / dLenPath ;
|
|
|
|
double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ;
|
|
|
|
if ( dProj > dSemiAxMin * dTest) {
|
|
// Determino l'altezza del punto sull'ellisse da cui passa la retta
|
|
double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dLenPath + dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : dLenPath) ;
|
|
double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ;
|
|
double dZ0 = ( ( dPr0 - dLenPath) * dPar) / dSemiAxMin ;
|
|
|
|
dMin = dZTip + dDelta + m_dRadius - dZ0 + ( dDelta / dLenPath) * ( dProj - dPr0) ;
|
|
}
|
|
else {
|
|
|
|
double dSqrRad = dProj * dProj + dSqd ;
|
|
double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ;
|
|
|
|
dMin = dZTip + m_dRadius - dH ;
|
|
}
|
|
}
|
|
}
|
|
|
|
else {
|
|
|
|
// Semi-asse ellisse
|
|
double dSemiAxMin = m_dRadius * sqrt( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ;
|
|
double dSqrSemiAxMin = m_dRadius * m_dRadius * ( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ;
|
|
double dXD2 = ( dProj - dLenPath) * ( dProj - dLenPath) ;
|
|
|
|
if ( dRSqDist1 < m_dRadius * m_dRadius) {
|
|
|
|
dMin = dZheight ;
|
|
|
|
double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ;
|
|
|
|
if ( dProj < - dSemiAxMin * dTest) {
|
|
|
|
double dSqrRad = dProj * dProj + dSqd ;
|
|
double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ;
|
|
|
|
dMax = dZTip - m_dRadius + dH ;
|
|
}
|
|
else if ( dProj - dLenPath < - dSemiAxMin * dTest) {
|
|
// Determino l'altezza del punto sull'ellisse da cui passa la retta
|
|
double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : 0) ;
|
|
double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ;
|
|
double dZ0 = ( dPr0 * dPar) / dSemiAxMin ;
|
|
|
|
dMax = dZTip - m_dRadius + dZ0 + ( dDelta / dLenPath) * ( dProj + dPr0) ;
|
|
}
|
|
else {
|
|
|
|
double dSqrRad = dProj * dProj + dSqd ;
|
|
double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ;
|
|
dMax = dZTip - m_dRadius + dDelta + dH ;
|
|
}
|
|
}
|
|
else {
|
|
|
|
dMin = dZheight + ( dDelta * ( dProj - dStart)) / dLenPath ;
|
|
|
|
double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ;
|
|
|
|
if ( dProj - dLenPath < - dSemiAxMin * dTest) {
|
|
// Determino l'altezza del punto sull'ellisse da cui passa la retta
|
|
double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : 0) ;
|
|
double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ;
|
|
double dZ0 = ( dPr0 * dPar) / dSemiAxMin ;
|
|
|
|
dMax = dZTip - m_dRadius + dZ0 + ( dDelta / dLenPath) * ( dProj + dPr0) ;
|
|
}
|
|
else {
|
|
|
|
double dSqrRad = ( dProj - dLenPath) * ( dProj - dLenPath) + dSqd ;
|
|
double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ;
|
|
dMax = dZTip + dDelta - m_dRadius + dH ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Caso di bull-nose mill
|
|
else
|
|
return true ;
|
|
|
|
return SubtractIntervals( nI, nJ, dMin, dMax) ;
|
|
}
|
|
|
|
|
|
// Versore utensile nel piano XY
|
|
|
|
// DeltaZ = 0
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::DrillingXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
|
|
if ( m_nToolType == CylindricalMill ||
|
|
m_nToolType == BallEndMill ||
|
|
m_nToolType == BullNoseMill)
|
|
|
|
return CBTDrillXY( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else if ( m_nToolType == ConusMill)
|
|
|
|
return ConusDrillingXY( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else
|
|
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::CBTDrillXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
if ( m_nToolType == ConusMill)
|
|
return ConusDrillingXY( ptLs, ptLe, vtToolDir) ;
|
|
|
|
// Punti per la determinazione del materiale asportato
|
|
Vector3d vtMove = ptLe - ptLs ;
|
|
// Punti di riferimento dell'asportazione
|
|
Point3d ptLNs ;
|
|
Point3d ptLNe ;
|
|
// Parametro relativo all'utensile altezza della parte non cilindrica e fattore determinante
|
|
// la lunghezza della parte lavorata a seconda che lavori la punta o il fondo
|
|
double dCylH ; double dFactor ;
|
|
|
|
// Caso utensile generico (al momento non gestito)
|
|
if ( m_nToolType == 0)
|
|
return false ;
|
|
// Caso Cylindrical Mill
|
|
else if ( m_nToolType == 1)
|
|
dCylH = m_dHeight ;
|
|
// Caso Ball-end Mill
|
|
else if ( m_nToolType == 2)
|
|
dCylH = m_dHeight - m_dRadius ;
|
|
// Caso Bull-nose Mill
|
|
else if ( m_nToolType == 3)
|
|
dCylH = m_dHeight - m_dRCorner ;
|
|
|
|
// Normalizzo tale vettore e ne determino la lunghezza:
|
|
double dLenPath = vtMove.Len() ; vtMove.Normalize() ;
|
|
|
|
// Prodotto scalare fra versore direzione utensile e direzione movimento
|
|
double dScProd = vtMove * vtToolDir ;
|
|
// Se lavora la punta
|
|
if ( dScProd < 0) {
|
|
// Trovo i punti di riferimento per la lavorazione
|
|
ptLNs = ptLs + ( vtMove * dCylH) ;
|
|
ptLNe = ptLe + ( vtMove * dCylH) ;
|
|
dFactor = 1 ;
|
|
}
|
|
// Se lavora il fondo
|
|
else {
|
|
ptLNs = ptLs ;
|
|
ptLNe = ptLe ;
|
|
dFactor = 0 ;
|
|
}
|
|
|
|
// Quota z dei punti iniziale e finale
|
|
double dHz = ptLNs.z ;
|
|
|
|
// Bounding box
|
|
double dMinX = min( ptLNs.x, ptLNe.x) - m_dRadius ;
|
|
double dMaxX = max( ptLNs.x, ptLNe.x) + m_dRadius ;
|
|
double dMinY = min( ptLNs.y, ptLNe.y) - m_dRadius ;
|
|
double dMaxY = max( ptLNs.y, ptLNe.y) + m_dRadius ;
|
|
double dMinZ = dHz - m_dRadius ;
|
|
double dMaxZ = dHz + m_dRadius ;
|
|
|
|
// Verifico se il movimento intersca lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL)
|
|
return true ;
|
|
|
|
// Determino i limiti sugli indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
//Proietto ptLNs sul piano XY:
|
|
Point3d ptStart( ptLNs.x, ptLNs.y, 0) ;
|
|
|
|
// Ciclo sui punti
|
|
for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) {
|
|
for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
// Punto da valutare
|
|
Point3d ptC( (i + 0.5)*m_dStep, (j + 0.5)*m_dStep, 0) ;
|
|
// Vettore spostamento da ptLe a ptC
|
|
Vector3d vtC = ( ptC - ptStart) ;
|
|
// Componenti parallela e perpendicolare a vtMove
|
|
// Vettore ortogonale a vtMove
|
|
Vector3d vtOrt = vtMove ;
|
|
// Ruoto vtOrt affinché sia ortogonale
|
|
vtOrt.Rotate( Z_AX, -90) ;
|
|
|
|
double dProj = vtC * vtOrt ;
|
|
Vector3d vtPara = vtOrt * dProj ; // Parallelo alla perpendicolare al movimento
|
|
Vector3d vtPerp = vtC - vtPara ; // Perpendicolare alla perpendicolare al movimento ( serve per unire le getminmax di drill e perp)
|
|
// Distanza di ptC dall'asse dell'untensile
|
|
double dSqDist = vtPerp.SqLen() ;
|
|
double dLimitMill = dLenPath + dFactor * ( m_dHeight - dCylH) ;
|
|
// Se dTestProj è positivo è vtC è dalla parte giusta
|
|
double dTestProj = vtC * vtMove ;
|
|
|
|
if ( dTestProj > 0 && dSqDist < dLimitMill * dLimitMill) {
|
|
if ( dProj > - m_dRadius && dProj < m_dRadius)
|
|
GetMinMaxXY( i, j, dProj, dHz, dSqDist, 0, dLenPath, dScProd) ;
|
|
}
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ConusDrillingXY( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir)
|
|
{
|
|
unsigned int nStartI, nStartJ, nEndI, nEndJ ;
|
|
double dMin, dMax ;
|
|
|
|
// Determinazione dell'interferenza dell'utensile con lo Zmap, bouding box e limiti su indici
|
|
BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
|
|
|
|
// Parametri geometrici dell'utensile
|
|
double dMinRad = min( m_dRadius, m_dTipRadius) ;
|
|
double dMaxRad = max( m_dRadius, m_dTipRadius) ;
|
|
double dCylH = m_dHeight - m_dTipHeight ;
|
|
|
|
Vector3d vtMove = ptLe - ptLs ; double dLen = vtMove.LenXY() ; vtMove.Normalize() ;
|
|
|
|
Point3d ptI = ( vtToolDir * vtMove < 0 ? ptLs : ptLe) ; double dZH = ptI.z ;
|
|
|
|
Vector3d vtV1 = vtToolDir ;
|
|
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 , dY = ( j + 0.5) * m_dStep ;
|
|
|
|
Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptI ;
|
|
|
|
double dPL = vtC * vtV1 ;
|
|
double dPT = vtC * vtV2 ;
|
|
|
|
if ( m_dRadius > m_dTipRadius) {
|
|
|
|
if ( dPL < 0 && dPL > - dCylH - dLen && dPT > - dMaxRad && dPT < dMaxRad) {
|
|
|
|
double dH = sqrt( dMaxRad * dMaxRad - dPT * dPT) ;
|
|
|
|
dMin = dZH - dH ; dMax = dZH + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dPL <= - dCylH - dLen && dPL > - m_dHeight - dLen &&
|
|
dPT > - dMaxRad + ( - dPL - dCylH - dLen) * ( dMaxRad - dMinRad) / m_dTipHeight &&
|
|
dPT < dMaxRad - ( - dPL - dCylH - dLen) * ( dMaxRad - dMinRad) / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad - ( - dPL - dCylH - dLen) * ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
|
|
double dH = sqrt( dr * dr - dPT * dPT) ;
|
|
|
|
dMin = dZH - dH ; dMax = dZH + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
else {
|
|
|
|
if ( dPL < 0 && dPL > - dCylH && dPT > - dMinRad && dPT < dMinRad) {
|
|
|
|
double dH = sqrt( dMinRad * dMinRad - dPT * dPT) ;
|
|
|
|
dMin = dZH - dH ; dMax = dZH + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dPL <= - dCylH && dPL > - m_dHeight &&
|
|
dPT > - dMinRad - ( - dPL - dCylH) * ( dMaxRad - dMinRad) / m_dTipHeight &&
|
|
dPT < dMinRad + ( - dPL - dCylH) * ( dMaxRad - dMinRad) / m_dTipHeight) {
|
|
|
|
double dr = dMinRad + ( - dPL - dCylH) * ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
|
|
double dH = sqrt( dr * dr - dPT * dPT) ;
|
|
|
|
dMin = dZH - dH ; dMax = dZH + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dPL <= - m_dHeight && dPL > - m_dHeight - dLen && dPT > - dMaxRad && dPT < dMaxRad) {
|
|
|
|
double dH = sqrt( dMaxRad * dMaxRad - dPT * dPT) ;
|
|
|
|
dMin = dZH - dH ; dMax = dZH + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingPerpXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
if ( m_nToolType == CylindricalMill ||
|
|
m_nToolType == BallEndMill ||
|
|
m_nToolType == BullNoseMill)
|
|
|
|
return CBTPerpXY( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else if ( m_nToolType == ConusMill)
|
|
|
|
return ConusPerpXY( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else
|
|
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::CBTPerpXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
|
|
if ( m_nToolType == ConusMill)
|
|
return ConusPerpXY( ptLs, ptLe, vtToolDir) ;
|
|
|
|
// Determinazione delle posizioni iniziali e finali della punta dell'utensile
|
|
Point3d ptTLs = ptLs - vtToolDir * m_dHeight ;
|
|
Point3d ptTLe = ptLe - vtToolDir * m_dHeight ;
|
|
|
|
// Quota Z
|
|
double dZH = ptLs.z ;
|
|
|
|
// Estremi Bounding box
|
|
double dMinX = min( min( ptLs.x, ptLe.x), min( ptTLs.x, ptTLe.x)) - m_dRadius ;
|
|
double dMaxX = max( max( ptLs.x, ptLe.x), max( ptTLs.x, ptTLe.x)) + m_dRadius ;
|
|
double dMinY = min( min( ptLs.y, ptLe.y), min( ptTLs.y, ptTLe.y)) - m_dRadius ;
|
|
double dMaxY = max( max( ptLs.y, ptLe.y), max( ptTLs.y, ptTLe.y)) + m_dRadius ;
|
|
double dMinZ = dZH - m_dRadius ;
|
|
double dMaxZ = dZH + m_dRadius ;
|
|
|
|
// Verifica dell'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL)
|
|
return true ;
|
|
|
|
// Determinazione limiti sugli indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
// Proiezione sul piano XY delle grandezze di interesse
|
|
Point3d ptStart( ptLs.x, ptLs.y, 0) ;
|
|
Point3d ptEnd( ptLe.x, ptLe.y, 0) ;
|
|
Vector3d vtMove = ptEnd - ptStart ;
|
|
double dLenPath = vtMove.Len() ;
|
|
// Normalizzo il vettore vtMove congiungente le posizioni iniziale e finale della base dell'utensile
|
|
vtMove.Normalize() ;
|
|
|
|
for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) {
|
|
for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
// Punto su cui ciclare e vettore congiungente posizione iniziale della base a tale punto
|
|
Point3d ptC( (i + 0.5) * m_dStep, (j + 0.5) * m_dStep, 0) ;
|
|
Vector3d vtC = ptC - ptStart ;
|
|
// Proiezione di vtC sulla direzione del movimento
|
|
double dProj = vtC * vtMove ;
|
|
// Componente di vtC ortogonale al movimento
|
|
Vector3d vtPerp = vtC - vtMove * dProj ;
|
|
// Lunghezza quadrata del precedente vettore
|
|
double dSqDist = vtPerp.SqLen() ;
|
|
|
|
if ( dProj > - m_dRadius && dProj < dLenPath + m_dRadius && vtPerp * vtToolDir < 0 && dSqDist < m_dHeight * m_dHeight)
|
|
GetMinMaxXY( i, j, dProj, dZH, dSqDist, dLenPath, 0, 0) ;
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ConusPerpXY( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir)
|
|
{
|
|
unsigned int nStartI, nStartJ, nEndI, nEndJ ;
|
|
double dMin, dMax ;
|
|
|
|
// Determinazione dell'interferenza dell'utensile con lo Zmap, bouding box e limiti su indici
|
|
bool bControl = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
|
|
|
|
if ( bControl == false)
|
|
return true ;
|
|
|
|
// Parametri geometrici dell'utensile
|
|
double dCylH = m_dHeight - m_dTipHeight ;
|
|
|
|
Vector3d vtMove = ptLe - ptLs ; double dLen = vtMove.LenXY() ;
|
|
|
|
// Sistema di riferimento
|
|
Vector3d vtV1 = - vtToolDir ;
|
|
Vector3d vtV2 = vtMove ; vtV2.Normalize() ;
|
|
|
|
Point3d ptIC = ptLs ; double dZ = ptLs.z ;
|
|
|
|
// Ciclo sui punti
|
|
for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) {
|
|
|
|
double dY = ( j + 0.5) * m_dStep ; double dX = ( i + 0.5) * m_dStep ;
|
|
|
|
Point3d ptCC( dX, dY, 0) ; Vector3d vtCC = ptCC - ptIC ;
|
|
|
|
double dPCL = vtCC * vtV1 ; double dPCT = vtCC * vtV2 ;
|
|
|
|
// Parte cilindrica
|
|
if( dPCL > 0 && dPCL < dCylH) {
|
|
|
|
if ( dPCT > - m_dRadius && dPCT < 0) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dPCT * dPCT) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dPCT >= 0 && dPCT < dLen) {
|
|
|
|
dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dPCT >= dLen && dPCT < dLen + m_dRadius) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - ( dPCT - dLen) * ( dPCT - dLen)) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
// Parte non cilindrica
|
|
else if ( dPCL >= dCylH && dPCL < m_dHeight) {
|
|
|
|
double dPNCL = dPCL - dCylH ; double dPNCT = dPCT ;
|
|
|
|
if ( dPNCT > - m_dRadius - dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight && dPNCT < 0) {
|
|
|
|
double dr = m_dRadius + dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight ;
|
|
|
|
double dH = sqrt( dr * dr - dPNCT * dPNCT) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dPNCT >= 0 && dPNCT < dLen) {
|
|
|
|
double dH = m_dRadius + dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dPNCT >= dLen && dPNCT < dLen + m_dRadius + dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight) {
|
|
|
|
double dr = m_dRadius + dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight ;
|
|
|
|
double dH = sqrt( dr * dr - ( dPNCT - dLen) * ( dPNCT - dLen)) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingXYPlaneGen( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
if ( m_nToolType == CylindricalMill ||
|
|
m_nToolType == BallEndMill)
|
|
return PlaneGenCylBall( ptLs, ptLe, vtToolDir) ;
|
|
else
|
|
return ConusPlaneGen( ptLs, ptLe, vtToolDir) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::PlaneGenCylBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ;
|
|
double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ;
|
|
|
|
// Prima verifica sull'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL)
|
|
return true ;
|
|
|
|
Point3d ptI = ptLs ; Point3d ptF = ptLe ;
|
|
|
|
// Quote dei punti ptI e ptF
|
|
double dZ = ptI.z ;
|
|
|
|
Point3d ptIT = ptI - vtToolDir * m_dHeight ;
|
|
Point3d ptFT = ptF - vtToolDir * m_dHeight ;
|
|
|
|
// Bounding box
|
|
double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ;
|
|
double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ;
|
|
double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ;
|
|
double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ;
|
|
|
|
// Seconda verifica dell'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
|
|
Vector3d vtMove = ptF - ptI ;
|
|
|
|
if ( vtMove * vtToolDir > 0) {
|
|
Point3d ptTemp = ptI ;
|
|
ptI = ptF ;
|
|
ptF = ptTemp ;
|
|
vtMove = - vtMove ;
|
|
}
|
|
|
|
Vector3d vtMoveOrt = vtMove - ( vtMove * vtToolDir) * vtToolDir ; double dLen2 = vtMoveOrt.Len() ;
|
|
Vector3d vtMoveLong = ( vtMove * vtToolDir) * vtToolDir ; double dLen1 = vtMoveLong.Len() ;
|
|
|
|
// Determino sistema di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento
|
|
Vector3d vtV1 = vtToolDir ;
|
|
Vector3d vtV2 = vtMoveOrt ; vtV2.Normalize() ;
|
|
|
|
// Punti iniziale e finale proiettati sul piano
|
|
Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ;
|
|
|
|
// Determinazione limiti sugli indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
// Ciclo
|
|
for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) {
|
|
for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
|
|
if ( m_nToolType == 1) {
|
|
|
|
Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ;
|
|
|
|
Vector3d vtC = ptC - ptIxy ;
|
|
|
|
double dProj1 = vtC * vtV1 ;
|
|
double dProj2 = vtC * vtV2 ;
|
|
|
|
GetMMPlaneGenCyl( i, j, dZ, dLen1, dLen2, dProj1, dProj2) ;
|
|
}
|
|
|
|
else if ( m_nToolType == 2)
|
|
GetMMPlaneGenBall( i, j, dZ, dLen1, dLen2, ptIxy, vtMove, vtV1, vtV2) ;
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
inline bool
|
|
VolZmap::GetMinMaxXY( unsigned int nI, unsigned int nJ, double dProj, double dZheight,
|
|
double dSqD, double dPathPerp, double dPathPar, double dScProd)
|
|
{
|
|
// Definisco la variabile altezza della parte cilindrica dell'utensile
|
|
double dCylH ;
|
|
// Definisco variabili per determinazione intervallo da sottrarre
|
|
double dL, dR, dH ;
|
|
|
|
// Caso di utensile generico ( per ora non gestito)
|
|
if ( m_nToolType == 0)
|
|
return false ;
|
|
// Se utensile standard setto altezza della parte cilindrica
|
|
else if ( m_nToolType == 1)
|
|
dCylH = m_dHeight ;
|
|
else if ( m_nToolType == 2)
|
|
dCylH = m_dHeight - m_dRadius ;
|
|
else if ( m_nToolType == 3)
|
|
dCylH = m_dHeight - m_dRCorner ;
|
|
// Caso di utensile non definito
|
|
else
|
|
return false ;
|
|
|
|
// Parametri per isolare la lavorazione della parte cilindrica comune a tutti gli utensili standard
|
|
// Limite nella direziona parallela all'asse dell'utensile e parametro perpendicolare
|
|
double dLimPar, dParPerp ;
|
|
|
|
// Tagli perpendicolari all'asse dell'utensile
|
|
if ( abs( dScProd) < EPS_SMALL) {
|
|
dLimPar = dCylH ;
|
|
dParPerp = dPathPerp ;
|
|
}
|
|
// Tagli paralleli all'asse dell'utensile
|
|
else {
|
|
dLimPar = dPathPar ;
|
|
dParPerp = 0 ;
|
|
}
|
|
|
|
// Parte cilindrica della lavorazione
|
|
if ( dSqD < dLimPar * dLimPar) {
|
|
// Qui il raggio del semicerchio è m_dRadius
|
|
if ( dProj < 0)
|
|
// dH = sqrt( m_dRadius^2 - dProj^2)
|
|
dH = sqrt( m_dRadius * m_dRadius - ( dProj * dProj)) ;
|
|
// Qui l'altezza è costante
|
|
else if ( dProj < dParPerp)
|
|
// dH = m_dRadius
|
|
dH = m_dRadius ;
|
|
// Qui il raggio del semicerchio è m_dRadius
|
|
else if ( dProj < dParPerp + m_dRadius)
|
|
// dH = sqrt( m_dRadius^2 - ( dProj - dParPerp)^2)
|
|
dH = sqrt( m_dRadius * m_dRadius - ( dProj - dParPerp) * ( dProj - dParPerp)) ;
|
|
// Eseguo il taglio
|
|
return SubtractIntervals( nI, nJ, dZheight - dH, dZheight + dH) ;
|
|
}
|
|
// Parte non cilindrica, questa parte esiste solo nei tagli (dScProd = 0) e nel foro con la punta quindi (dScProd < 0)
|
|
// e solo con frese non cilindriche
|
|
else {
|
|
if ( dScProd < EPS_SMALL) {
|
|
// Definisco variabili
|
|
// Caso fresa ball-end
|
|
if ( m_nToolType == 2) {
|
|
// Il raggio è sqrt( m_dRadius^2 - ( sqrt( dSqD) - dLimPar)^2)
|
|
if ( dProj < 0) {
|
|
dL = sqrt( dSqD) - dLimPar ;
|
|
dR = sqrt( m_dRadius * m_dRadius - dL * dL) ;
|
|
dH = sqrt( dR * dR - (dProj * dProj)) ;
|
|
}
|
|
// Qui dH non dipende da dProj
|
|
else if ( dProj < dParPerp) {
|
|
dL = sqrt( dSqD) - dLimPar ;
|
|
dH = sqrt( m_dRadius * m_dRadius - dL * dL) ;
|
|
}
|
|
// E' analogo al primo caso con la sostituzione di dProj con dProj - dParPerp
|
|
else if ( dProj < dParPerp + m_dRadius) { // In questo caso è equivalente a else
|
|
dL = sqrt( dSqD) - dLimPar ;
|
|
dR = sqrt( m_dRadius * m_dRadius - dL * dL) ;
|
|
dH = sqrt( dR * dR - ((dProj - dParPerp) * (dProj - dParPerp))) ;
|
|
}
|
|
}
|
|
// Caso di fresa bull-nose
|
|
else if ( m_nToolType == 3) {
|
|
// Raggio semicerchio m_dRadius - m_dRCorner + sqrt( m_dRCorner^2 - ( sqrt( dSqD) - dLimPar)^2)
|
|
if ( dProj < 0) {
|
|
dL = sqrt( dSqD) - dLimPar ;
|
|
dR = m_dRadius - m_dRCorner + sqrt( m_dRCorner * m_dRCorner - dL * dL) ;
|
|
dH = sqrt( dR * dR - ( dProj * dProj)) ;
|
|
}
|
|
// Qui dH non dipende da dProj
|
|
else if ( dProj < dParPerp) {
|
|
dL = sqrt( dSqD) - dLimPar ;
|
|
dH = m_dRadius - m_dRCorner + sqrt( m_dRCorner * m_dRCorner - dL * dL) ;
|
|
}
|
|
// E' analogo al primo caso con la sostituzione di di dProj con dProj - dParPerp
|
|
else if ( dProj < dParPerp + m_dRadius) { // In questo caso equivalente a else
|
|
dL = sqrt( dSqD) - dLimPar ;
|
|
dR = m_dRadius - m_dRCorner + sqrt( m_dRCorner * m_dRCorner - dL * dL) ;
|
|
dH = sqrt( dR * dR - ( ( dProj - dParPerp) * ( dProj - dParPerp))) ;
|
|
}
|
|
}
|
|
return SubtractIntervals( nI, nJ, dZheight - dH, dZheight + dH) ;
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
inline bool
|
|
VolZmap::GetMMPlaneGenCyl( unsigned int i, unsigned int j, double dZ,
|
|
double dLen1, double dLen2, double dProj1, double dProj2)
|
|
{
|
|
double dMin, dMax ;
|
|
|
|
if ( dProj2 > - m_dRadius && dProj2 < 0) {
|
|
|
|
if ( dProj1 < 0 && dProj1 > - m_dHeight) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
|
|
else if ( dProj1 <= - m_dHeight) {
|
|
|
|
if ( ( dProj2 < dLen2 - m_dRadius && dProj1 > - m_dHeight - ( dLen1 / dLen2) * ( dProj2 + m_dRadius))
|
|
|| ( dProj2 >= dLen2 - m_dRadius && dProj1 > - m_dHeight - dLen1)) { // In questo costrutto if-else non c'è bisogno di specificare nient'altro perché già siamo nella regione - m_dRadius < dProj2 < 0
|
|
|
|
double dPar = m_dHeight + ( dLen1 / dLen2) * ( dProj2 + m_dRadius) + dProj1 ;
|
|
double dL = m_dRadius - ( dLen2 / dLen1) * dPar ;
|
|
double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
else if ( dProj2 >= 0 && dProj2 < m_dRadius) {
|
|
|
|
if ( dProj1 < 0 && ( ( dProj2 < dLen2 && dProj1 > - ( dLen1 / dLen2) * dProj2) || ( dProj2 >= dLen2 && dProj1 > - dLen1))) {
|
|
|
|
double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ;
|
|
/* Oppure
|
|
double dPar1 = ( dLen1 / dLen2) * dProj2 + dProj1 ;
|
|
double dPar2 = ( dLen2 / dLen1) * dPar1 ; */
|
|
double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dProj2 < dLen2 && dProj1 <= - ( dLen1 / dLen2) * dProj2) {
|
|
|
|
if ( dProj1 > - ( dLen1 / dLen2) * dProj2 - m_dHeight) {
|
|
|
|
dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dProj1 <= - ( dLen1 / dLen2) * dProj2 - m_dHeight) {
|
|
|
|
if ( ( dProj2 < dLen2 - m_dRadius && dProj1 > - ( dLen1 / dLen2) * ( dProj2 + m_dRadius) - m_dHeight)
|
|
|| ( dProj2 >= dLen2 - m_dRadius && dProj1 > - m_dHeight - dLen1)) { // modificato qui
|
|
|
|
double dPar = m_dHeight + ( dLen1 / dLen2) * ( dProj2 + m_dRadius) + dProj1 ;
|
|
double dL = m_dRadius - ( dLen2 / dLen1) * dPar ;
|
|
double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
else if ( dProj2 >= dLen2 && dProj1 < - dLen1) {
|
|
|
|
if ( dProj1 > - m_dHeight - dLen1) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dLen2) * ( dProj2 - dLen2)) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
else if ( dProj2 >= m_dRadius && dProj2 < dLen2) {
|
|
|
|
if ( dProj1 < - ( dLen1 / dLen2) * ( dProj2 - m_dRadius) && dProj1 > - ( dLen1 / dLen2) * dProj2) {
|
|
|
|
double dL = ( dLen2 / dLen1) * ( ( dLen1 / dLen2) * dProj2 + dProj1) ;
|
|
double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dProj1 <= - ( dLen1 / dLen2) * dProj2 && dProj1 > - ( dLen1 / dLen2) * dProj2 - m_dHeight) {
|
|
|
|
dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ;
|
|
|
|
SubtractIntervals( i, j, dMin , dMax) ;
|
|
}
|
|
else if ( dProj1 <= - ( dLen1 / dLen2) * dProj2 - m_dHeight) {
|
|
|
|
if ( ( dProj2 < dLen2 - m_dRadius && dProj1 > - ( dLen1 / dLen2) * ( dProj2 + m_dRadius) - m_dHeight)
|
|
|| ( dProj2 >= dLen2 - m_dRadius && dProj1 > - m_dHeight - dLen1)) {
|
|
|
|
double dPar = m_dHeight + ( dLen1 / dLen2) * ( dProj2 + m_dRadius) + dProj1 ;
|
|
double dL = m_dRadius - ( dLen2 / dLen1) * dPar ;
|
|
double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
else if ( dProj2 >= dLen2 && dProj2 < dLen2 + m_dRadius) {
|
|
|
|
if ( dProj1 < - ( dLen1 / dLen2) * ( dProj2 - m_dRadius) && dProj1 >= - dLen1) {
|
|
|
|
double dL = ( dLen2 / dLen1) * ( ( dLen1 / dLen2) * dProj2 + dProj1) ;
|
|
double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dProj1 < - dLen1 && dProj1 > - dLen1 - m_dHeight) {
|
|
|
|
double dL = dProj2 - dLen2 ;
|
|
double dH = sqrt( m_dRadius * m_dRadius - dL * dL) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
inline bool
|
|
VolZmap::GetMMPlaneGenBall( unsigned int i, unsigned int j, double dZ, double dLen1, double dLen2,
|
|
Point3d ptIxy, Vector3d vtMove, Vector3d vtV1, Vector3d vtV2)
|
|
{
|
|
double dMin, dMax ;
|
|
|
|
Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ;
|
|
|
|
Vector3d vtC = ptC - ptIxy ;
|
|
|
|
double dProj1 = vtC * vtV1 ; // vtV1, vtV2 sono paralleli al piano
|
|
double dProj2 = vtC * vtV2 ;
|
|
|
|
double dCH = m_dHeight - m_dRadius ;
|
|
double dLMove = vtMove.LenXY() ;
|
|
|
|
Point3d ptCS = ptIxy - dCH * vtV1 ; Point3d ptCE = ptCS + vtMove ; // vtMove è orizzontale
|
|
|
|
Vector3d vtCS = ptC - ptCS ; Vector3d vtCE = ptC - ptCE ;
|
|
|
|
double dProjMove = ( vtCS * vtMove) / dLMove ;
|
|
|
|
Vector3d vtCSP = vtCS - ( ( vtCS * vtMove) / ( dLMove * dLMove)) * vtMove ;
|
|
|
|
double dSQDist = vtCSP.SqLenXY() ;
|
|
double dSQDistS = vtCS.SqLenXY() ;
|
|
double dSQDistE = vtCE.SqLenXY() ;
|
|
|
|
// parte cilindrica
|
|
|
|
if ( dProj2 > - m_dRadius && dProj2 < 0) {
|
|
|
|
if ( dProj1 > - dCH && dProj1 < 0) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
else if ( dProj2 >= 0 && dProj2 < m_dRadius) {
|
|
|
|
if ( dProj1 < 0 && ( ( dProj2 < dLen2 && dProj1 > - ( dLen1 / dLen2) * dProj2) || ( dProj2 >= dLen2 && dProj1 > - dLen1))) {
|
|
|
|
double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ;
|
|
/* Oppure
|
|
double dPar1 = ( dLen1 / dLen2) * dProj2 + dProj1 ;
|
|
double dPar2 = ( dLen2 / dLen1) * dPar1 ; */
|
|
double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dProj2 < dLen2 && dProj1 <= - ( dLen1 / dLen2) * dProj2 && dProj1 > - ( dLen1 / dLen2) * dProj2 - dCH) {
|
|
|
|
dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dProj2 >= dLen2 && dProj1 <= - dLen1 && dProj1 > - dLen1 - dCH) {
|
|
|
|
double dL = dProj2 - dLen2 ;
|
|
double dH = sqrt( m_dRadius * m_dRadius - dL * dL) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
else if ( dProj2 >= m_dRadius && dProj1 < - ( dLen1 / dLen2) * ( dProj2 - m_dRadius)) {
|
|
|
|
if ( dProj2 < dLen2 && dProj1 > - ( dLen1 / dLen2) * dProj2) {
|
|
|
|
double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ;
|
|
double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dProj2 < dLen2 && dProj1 <= - ( dLen1 / dLen2) * dProj2 && dProj1 > - ( dLen1 / dLen2) * dProj2 - dCH) {
|
|
|
|
dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dProj2 >= dLen2 && dProj2 < dLen2 + m_dRadius) {
|
|
|
|
if ( dProj1 > - dLen1) {
|
|
|
|
double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ;
|
|
double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dProj1 <= - dLen1 && dProj1 > - dLen1 - dCH) {
|
|
|
|
double dL = dProj2 - dLen2 ;
|
|
double dH = sqrt( m_dRadius * m_dRadius - dL * dL) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// parte non cilindrica
|
|
if ( dProjMove > - m_dRadius && dProjMove < 0) {
|
|
|
|
if ( dSQDistS < m_dRadius * m_dRadius) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dSQDistS) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
else if ( dProjMove >= 0 && dProjMove < dLMove) {
|
|
|
|
if ( dSQDist < m_dRadius * m_dRadius) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dSQDist) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
else {
|
|
|
|
if ( dSQDistE < m_dRadius * m_dRadius) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dSQDistE) ;
|
|
|
|
dMin = dZ - dH ; dMax = dZ + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ConusPlaneGen( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
double dMin, dMax ;
|
|
unsigned int nStartI, nStartJ, nEndI, nEndJ ;
|
|
|
|
bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
|
|
|
|
if ( Control == false)
|
|
return true ;
|
|
|
|
double dMinRad = min( m_dRadius, m_dTipRadius) ;
|
|
double dMaxRad = max( m_dRadius, m_dTipRadius) ;
|
|
double dCylH = m_dHeight - m_dTipHeight ;
|
|
double dZH = ptLs.z ;
|
|
|
|
m_nToolType = CylindricalMill ;
|
|
m_dHeight = dCylH ;
|
|
|
|
MillingXYPlaneGen( ptLs, ptLe, vtToolDir) ;
|
|
|
|
m_nToolType = ConusMill ;
|
|
m_dHeight = m_dHeight + m_dTipHeight ;
|
|
|
|
Point3d ptI, ptF ;
|
|
|
|
Vector3d vtV1 ;
|
|
|
|
if ( m_dTipRadius < m_dRadius) {
|
|
|
|
vtV1 = vtToolDir ;
|
|
ptI = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLs - vtV1 * dCylH : ptLe - vtV1 * dCylH) ;
|
|
ptF = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLe - vtV1 * dCylH : ptLs - vtV1 * dCylH) ;
|
|
}
|
|
|
|
else {
|
|
vtV1 = - vtToolDir ;
|
|
ptI = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLe + vtV1 * m_dHeight : ptLs + vtV1 * m_dHeight) ;
|
|
ptF = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLs + vtV1 * m_dHeight : ptLe + vtV1 * m_dHeight) ;
|
|
}
|
|
|
|
Point3d ptIxy( ptI.x, ptI.y, 0) ;
|
|
|
|
Vector3d vtMove = ptF - ptI ;
|
|
Vector3d vtLong = ( vtMove * vtV1) * vtV1 ; double dLen1 = vtLong.LenXY() ;
|
|
Vector3d vtOrt = vtMove - vtLong ; double dLen2 = vtOrt.LenXY() ;
|
|
Vector3d vtTemp = vtV1 ; vtTemp.Rotate( Z_AX, 90) ;
|
|
|
|
vtMove.Normalize() ;
|
|
|
|
Vector3d vtV2 = ( vtMove * vtTemp > 0 ? vtTemp : - vtTemp) ;
|
|
Vector3d vtV3 = vtV1 ^ vtV2 ;
|
|
|
|
double dTan = ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ;
|
|
|
|
double dCos = dTan * dRatio ;
|
|
double dSin = ( abs( dCos) < 1 ? sqrt( 1 - dCos * dCos) : 0) ;
|
|
|
|
double dDen = sqrt( 1 + dTan * dTan) ;
|
|
|
|
double dDeltaR = dMaxRad - dMinRad ;
|
|
double dMinLim = dMinRad * dCos ;
|
|
double dMaxLim = dMaxRad * dCos ;
|
|
|
|
|
|
// Versori normali e prodotti scalari per determinare i piani
|
|
Vector3d vtNInf = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ;
|
|
Vector3d vtNSup = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * vtV3 ;
|
|
|
|
Point3d ptV = ptI - vtV1 * ( dMaxRad * m_dTipHeight) / ( dMaxRad - dMinRad) ;
|
|
Vector3d vtR0 = ptV - ORIG ;
|
|
double dDotInf = vtR0 * vtNInf ;
|
|
double dDotSup = vtR0 * vtNSup ;
|
|
|
|
|
|
for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) {
|
|
|
|
for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
|
|
Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ;
|
|
|
|
|
|
Vector3d vtC = ptC - ptIxy ;
|
|
|
|
double dProj1 = vtC * vtV1 ; double dProj2 = vtC * vtV2 ;
|
|
|
|
if ( dRatio <= m_dTipHeight / dDeltaR) {
|
|
|
|
if ( dProj1 > - m_dTipHeight && dProj1 < 0 &&
|
|
dProj2 > - dMaxRad - dTan * dProj1 &&
|
|
dProj2 < dMaxLim + dProj1 * ( dMaxLim - dMinLim) / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad + dTan * dProj1 ;
|
|
double dH = sqrt( dr * dr - dProj2 * dProj2) ;
|
|
|
|
dMin = dZH - dH ; dMax = dZH + dH ;
|
|
|
|
SubtractIntervals( i, j , dMin, dMax) ;
|
|
}
|
|
else if ( dProj1 > dLen1 - m_dTipHeight && dProj1 < dLen1 &&
|
|
dProj2 > dLen2 - dMaxRad - dTan * dProj1 &&
|
|
dProj2 < dLen2 + dMaxLim + dProj1 * ( dMaxLim - dMinLim) / m_dTipHeight) { // Se due sistemi di riferimento hanno stessi versori di base e differiscono semplicemente per le origini,
|
|
// le proiezioni di un vettore sugli assi nei due sistemi differiscono per le componenti del vettore che congiunge le origini.
|
|
double dr = dMaxRad + dTan * ( dProj1 - dLen1) ;
|
|
double dH = sqrt( dr * dr - ( dProj2 - dLen2) * ( dProj2 - dLen2)) ;
|
|
|
|
dMin = dZH - dH ; dMax = dZH + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dProj1 >= 0 && dProj1 < dLen1 &&
|
|
dProj2 > - dMaxRad + dProj1 * dLen2 / dLen1 &&
|
|
dProj2 < dMaxLim + dProj1 * dLen2 / dLen1) {
|
|
|
|
double dr = abs( dProj2 - dProj1 * dLen2 / dLen1) ; // Proj2 del punto meno Proj2 del centro del cerchio
|
|
double dH = sqrt( dMaxRad * dMaxRad - dr * dr) ;
|
|
|
|
dMin = dZH - dH ; dMax = dZH + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dProj1 > - m_dTipHeight && dProj1 < - m_dTipHeight + dLen1 && // Idem con patate
|
|
dProj2 > dMinLim + dProj1 * ( dLen2 / dLen1) &&
|
|
dProj2 < dMinRad + dProj1 * ( dLen2 / dLen1)) {
|
|
|
|
double dr = dProj2 - dProj1 * dLen2 / dLen1 ;
|
|
double dH = sqrt( dMinRad * dMinRad - dr * dr) ;
|
|
|
|
dMin = dZH - dH ; dMax = dZH + dH ;
|
|
|
|
SubtractIntervals( i, j , dMin, dMax) ;
|
|
}
|
|
else { // L'unico dominio non normale lo detrerminiamo per sottrazione :)
|
|
|
|
dMin = ( dDotInf - ptC.x * vtNInf.x - ptC.y * vtNInf.y) / vtNInf.z ;
|
|
dMax = ( dDotSup - ptC.x * vtNSup.x - ptC.y * vtNSup.y) / vtNSup.z ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
else {
|
|
|
|
if ( dProj1 > - m_dTipHeight && dProj1 <= 0 &&
|
|
dProj2 > - dMaxRad - dProj1 * ( dMaxRad - dMinRad) / m_dTipHeight &&
|
|
dProj2 < dMaxRad + dProj1 * ( dMaxRad - dMinRad) / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad + dProj1 * ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - dProj2 * dProj2) ;
|
|
|
|
dMin = dZH - dH ; dMax = dZH + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dProj1 > 0 && dProj1 < dLen1 &&
|
|
dProj2 > - dMaxRad + dProj1 * ( dLen2 / dLen1) &&
|
|
dProj2 < dMaxRad + dProj1 * ( dLen2 / dLen1)) {
|
|
|
|
double dr = abs( dProj2 - dProj1 * ( dLen2 / dLen1)) ;
|
|
double dH = sqrt( dMaxRad * dMaxRad - dr * dr) ;
|
|
|
|
dMin = dZH - dH ; dMax = dZH + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
|
|
// DeltaZ != 0
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingXYVert( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
unsigned int nStartI, nStartJ, nEndI, nEndJ ;
|
|
double dMin, dMax ;
|
|
|
|
// Determinazione dell'interferenza dell'utensile con lo Zmap, bouding box e limiti su indici
|
|
bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
|
|
|
|
if ( ! Control)
|
|
return true ;
|
|
|
|
double dCylH = m_dHeight - m_dTipHeight ;
|
|
double dZDown = min( ptLs.z, ptLe.z) ;
|
|
double dZUp = max( ptLs.z, ptLe.z) ;
|
|
|
|
// Definizione di un sistema di riferimento
|
|
Vector3d vtV1 = - vtToolDir ;
|
|
Vector3d vtV2 = vtV1 ; vtV2.Rotate(Z_AX, 90) ;
|
|
|
|
Point3d ptIC = ptLs ; Point3d ptINC = ptLs + dCylH * vtV1 ;
|
|
|
|
Point3d ptICxy( ptIC.x, ptIC.y, 0) ; Point3d ptINCxy( ptINC.x, ptINC.y, 0) ;
|
|
|
|
for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) {
|
|
|
|
for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
|
|
double dX = ( i + 0.5) * m_dStep , dY = ( j + 0.5) * m_dStep ;
|
|
|
|
Point3d ptC( dX, dY, 0) ; Vector3d vtCC = ptC - ptICxy ; Vector3d vtNCC = ptC - ptINCxy ;
|
|
|
|
double dCPL = vtCC * vtV1 ; double dCPT = vtCC * vtV2 ;
|
|
|
|
double dNCPL = vtNCC * vtV1 ; double dNCPT = vtNCC * vtV2 ;
|
|
|
|
// Parte cilindrica
|
|
if ( dCPL > 0 && dCPL < dCylH && dCPT > - m_dRadius && dCPT < m_dRadius) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dCPT * dCPT) ;
|
|
|
|
dMin = dZDown - dH ; dMax = dZUp + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
|
|
// Parte non cilindrica
|
|
if ( m_nToolType == BallEndMill) {
|
|
|
|
double dSqLen = vtNCC.SqLenXY() ;
|
|
|
|
if ( dNCPL >= 0 && dSqLen < m_dRadius * m_dRadius) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dSqLen) ;
|
|
|
|
dMin = dZDown - dH ; dMax = dZUp + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
else if ( m_nToolType == BullNoseMill) {
|
|
|
|
if ( dNCPL >= 0 && dNCPL < m_dTipHeight) {
|
|
|
|
double dR = m_dTipRadius + sqrt( m_dRCorner * m_dRCorner - dNCPL * dNCPL) ;
|
|
|
|
if ( dNCPT > - dR && dNCPT < dR) {
|
|
|
|
double dH = sqrt( dR * dR - dNCPT * dNCPT) ;
|
|
|
|
dMin = dZDown - dH ; dMax = dZUp + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
else if ( m_nToolType == ConusMill) {
|
|
|
|
if ( dNCPL >= 0 && dNCPL < m_dTipHeight &&
|
|
dNCPT > - m_dRadius - dNCPL * ( m_dTipRadius - m_dRadius) / m_dTipHeight &&
|
|
dNCPT < m_dRadius + dNCPL * ( m_dTipRadius - m_dRadius) / m_dTipHeight) {
|
|
|
|
double dr = m_dRadius + dNCPL * ( m_dTipRadius - m_dRadius) / m_dTipHeight ;
|
|
|
|
double dH = sqrt( dr * dr - dNCPT * dNCPT) ;
|
|
|
|
dMin = dZDown - dH ; dMax = dZUp + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingXYLongVert( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
if ( m_nToolType == CylindricalMill ||
|
|
m_nToolType == BallEndMill)
|
|
|
|
return XYLongVertCylBall( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else if ( m_nToolType == ConusMill)
|
|
|
|
return XYLongVertConus( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else
|
|
// Casi al momento non gestiti
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::XYLongVertCylBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
unsigned int nStartI, nEndI, nStartJ, nEndJ ;
|
|
double dMin, dMax ;
|
|
|
|
bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
|
|
|
|
// Se Control è falso non vi è interferenza fra utensile e Zmap
|
|
if ( ! Control)
|
|
return true ;
|
|
|
|
double dDeltaZ = ptLe.z - ptLs.z;
|
|
double dCylH = m_dHeight - m_dTipHeight ;
|
|
|
|
Point3d ptI, ptF, ptBI, ptBF ;
|
|
Vector3d vtV1, vtV2 ;
|
|
Vector3d vtMove = ptLe - ptLs ;
|
|
|
|
// Studio della parte sferica
|
|
if ( ptLs.z < ptLe.z) {
|
|
|
|
ptBI = ptLs - vtToolDir * dCylH ;
|
|
ptBF = ptLe - vtToolDir * dCylH ;
|
|
}
|
|
|
|
else {
|
|
ptBI = ptLe - vtToolDir * dCylH ;
|
|
ptBF = ptLs - vtToolDir * dCylH ;
|
|
}
|
|
|
|
Point3d ptBIxy( ptBI.x, ptBI.y, 0) ;
|
|
Vector3d vtBMove = ptBF - ptBI ; vtBMove.Normalize() ;
|
|
Vector3d vtBV1 = ( vtToolDir * vtBMove > 0 ? vtToolDir : - vtToolDir) ;
|
|
|
|
double dDeltaBZ = ptBF.z - ptBI.z ;
|
|
double dOriz = vtBMove * Z_AX ;
|
|
double dVert = vtBMove * vtBV1 ;
|
|
|
|
double dSemiAxMin = m_dRadius * dOriz ;
|
|
|
|
// Studio delle simmetrie della parte cilindrica
|
|
if ( vtToolDir * vtMove < 0 && dDeltaZ < 0) {
|
|
|
|
ptI = ptLe - vtToolDir * dCylH ;
|
|
ptF = ptLs - vtToolDir * dCylH ;
|
|
vtMove = - vtMove ;
|
|
vtV1 = - vtToolDir ;
|
|
dDeltaZ = - dDeltaZ ;
|
|
}
|
|
|
|
else if ( vtToolDir * vtMove > 0 && dDeltaZ > 0) {
|
|
ptI = ptLs - vtToolDir * dCylH ;
|
|
ptF = ptLe - vtToolDir * dCylH ;
|
|
vtV1 = - vtToolDir ;
|
|
}
|
|
|
|
else if ( vtToolDir * vtMove > 0 && dDeltaZ < 0) {
|
|
ptI = ptLe ;
|
|
ptF = ptLs ;
|
|
vtV1 = vtToolDir ;
|
|
vtMove = - vtMove ;
|
|
dDeltaZ = - dDeltaZ ;
|
|
}
|
|
|
|
else {
|
|
ptI = ptLs ;
|
|
ptF = ptLe ;
|
|
vtV1 = vtToolDir ;
|
|
}
|
|
|
|
Point3d ptIxy( ptI.x, ptI.y, 0) ; double dZI = ptI.z ;
|
|
|
|
vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ;
|
|
|
|
double dLen = abs( vtMove * vtV1) ;
|
|
|
|
// 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 - ptIxy ;
|
|
|
|
double dProj1 = - vtC * vtV1 ; double dProj2 = vtC * vtV2 ;
|
|
|
|
Vector3d vtBC = ptC - ptBIxy ;
|
|
|
|
double dBpr1 = vtBC * vtBV1 ; double dBpr2 = vtBC * vtV2 ;
|
|
|
|
// Parte cilindrica
|
|
|
|
if ( dProj2 > - m_dRadius && dProj2 < m_dRadius &&
|
|
dProj1 > 0 && dProj1 < dLen + dCylH) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ;
|
|
|
|
// Massimi
|
|
if ( dProj1 > 0 && dProj1 < dLen) {
|
|
|
|
double dZ0 = ptI.z + dProj1 * ( dDeltaZ / dLen) ;
|
|
|
|
dMax = dZ0 + dH ;
|
|
}
|
|
else if ( dProj1 >= dLen && dProj1 < dLen + dCylH)
|
|
|
|
dMax = ptI.z + dDeltaZ + dH ;
|
|
|
|
// Minimi
|
|
if ( dProj1 > 0 && dProj1 < dCylH)
|
|
|
|
dMin = ptI.z - dH ;
|
|
|
|
else if ( dProj1 >= dCylH && dProj1 < dLen + dCylH) {
|
|
|
|
double dZ0 = ptI.z + ( dProj1 - dCylH) * ( dDeltaZ / dLen) ;
|
|
|
|
dMin = dZ0 - dH ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
|
|
// Parte Non cilindrica
|
|
if ( m_nToolType == BallEndMill) {
|
|
|
|
double dSqDistO = dBpr2 * dBpr2 ;
|
|
double dSqDistI = vtBC.SqLenXY() ;
|
|
double dSqDistF = ( dBpr1 - dLen) * ( dBpr1 - dLen) + dBpr2 * dBpr2 ;
|
|
|
|
if ( ( dBpr1 < 0 && dSqDistI < m_dRadius * m_dRadius) ||
|
|
( dBpr1 >= 0 && dBpr1 < dLen && dSqDistO < m_dRadius * m_dRadius) ||
|
|
( dBpr1 >= dLen && dSqDistF < m_dRadius * m_dRadius)) {
|
|
|
|
// Massimi
|
|
if ( dBpr1 < - dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dSqDistI) ;
|
|
|
|
dMax = ptBI.z + dH ;
|
|
}
|
|
else if ( dBpr1 >= - dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius)) &&
|
|
dBpr1 < dLen - dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) {
|
|
|
|
double dZ0 = ptBI.z + dVert * sqrt( m_dRadius * m_dRadius - dSqDistO) ;
|
|
|
|
dMax = dZ0 + dDeltaBZ * ( dBpr1 + dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) / dLen ;
|
|
}
|
|
else {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dSqDistF) ;
|
|
|
|
dMax = ptBF.z + dH ;
|
|
}
|
|
|
|
// Minimi
|
|
if ( dBpr1 < dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dSqDistI) ;
|
|
|
|
dMin = ptBI.z - dH ;
|
|
}
|
|
else if ( dBpr1 >= dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius)) &&
|
|
dBpr1 < dLen + dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) {
|
|
|
|
double dZ0 = ptBI.z - dVert * sqrt( m_dRadius * m_dRadius - dSqDistO) ;
|
|
|
|
dMin = dZ0 + dDeltaBZ * ( dBpr1 - dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) / dLen ;
|
|
}
|
|
else {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dSqDistF) ;
|
|
|
|
dMin = ptBF.z - dH ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
/*
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::XYLongVertConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) {
|
|
|
|
double dMin, dMax ;
|
|
unsigned int nStartI, nEndI, nStartJ, nEndJ ;
|
|
|
|
bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
|
|
|
|
if ( Control == false)
|
|
|
|
return true ;
|
|
|
|
// Parte cilindrica
|
|
m_nToolType = CylindricalMill ;
|
|
|
|
double dSafeHeight = m_dHeight ;
|
|
double dSafeTipHeight = m_dTipHeight ;
|
|
double dCylH = m_dHeight - m_dTipHeight ;
|
|
|
|
m_dHeight = dCylH ;
|
|
m_dTipHeight = 0 ;
|
|
|
|
XYLongVertCylBall( ptLs, ptLe, vtToolDir) ;
|
|
|
|
m_nToolType = ConusMill ;
|
|
m_dHeight = dSafeHeight ;
|
|
m_dTipHeight = dSafeTipHeight ;
|
|
|
|
// Parte conica
|
|
|
|
Point3d ptI, ptF ;
|
|
Vector3d vtV1 ;
|
|
|
|
double dMinRad = min( m_dRadius, m_dTipRadius) ;
|
|
double dMaxRad = max( m_dRadius, m_dTipRadius) ;
|
|
double dDeltaR = dMaxRad - dMinRad ;
|
|
|
|
double dStem ;
|
|
|
|
if ( m_dRadius > m_dTipRadius) {
|
|
|
|
vtV1 = vtToolDir ;
|
|
dStem = - dCylH ;
|
|
}
|
|
else {
|
|
|
|
vtV1 = - vtToolDir ;
|
|
dStem = m_dHeight ;
|
|
}
|
|
|
|
|
|
if ( vtV1 * ( ptLe - ptLs) * ( ptLe.z - ptLs.z) > 0) {
|
|
|
|
ptI = ( ptLe.z - ptLs.z < 0 ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ;
|
|
ptF = ( ptLe.z - ptLs.z < 0 ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ;
|
|
}
|
|
else {
|
|
|
|
ptI = ( ptLe.z - ptLs.z > 0 ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ;
|
|
ptF = ( ptLe.z - ptLs.z > 0 ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ;
|
|
}
|
|
|
|
double dZI = ptI.z ;
|
|
double dDeltaZ = ptF.z - ptI.z ;
|
|
|
|
Vector3d vtV2 = vtV1 ; vtV2.Rotate(Z_AX, 90) ;
|
|
Vector3d vtV3 = vtV1 ^ vtV2 ;
|
|
Vector3d vtMove = ptF - ptI ;
|
|
Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dPLen = vtMoveXY.LenXY() ;
|
|
|
|
Point3d ptIxy( ptI.x, ptI.y, 0) ;
|
|
|
|
Point3d ptV = ptI - vtV1 * ( ( dMaxRad * m_dTipHeight) / dDeltaR) ;
|
|
|
|
// Apertura del cono e parametri per determinare i piani
|
|
double dTan = ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
double dRatio = ( vtMove * vtV1) / ( vtMove * vtV3) ;
|
|
double dCos = dTan * dRatio ;
|
|
double dSen = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ;
|
|
|
|
// Versori normali e prodotti scalari per per determinare i piani
|
|
Vector3d vtNs = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + ( dCos / sqrt( 1 + dTan * dTan)) * vtV3 - ( sqrt( 1 - dCos * dCos) / sqrt( 1 + dTan * dTan)) * vtV2 ;
|
|
Vector3d vtNd = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + ( dCos / sqrt( 1 + dTan * dTan)) * vtV3 + ( sqrt( 1 - dCos * dCos) / sqrt( 1 + dTan * dTan)) * vtV2 ;
|
|
Vector3d vtR0 = ptV - ORIG ;
|
|
double dDots = vtR0 * vtNs ;
|
|
double dDotd = vtR0 * vtNd ;
|
|
|
|
|
|
// 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 - ptIxy ;
|
|
|
|
double dProj1 = vtC * vtV1 ; double dProj2 = vtC * vtV2 ; double dOrtLen = abs( dProj2) ;
|
|
|
|
if ( ( dProj1 > 0 && dProj1 < dPLen && dOrtLen < dMaxRad) ||
|
|
( dProj1 >= dPLen && dProj1 < dPLen + m_dTipHeight &&
|
|
dOrtLen < dMaxRad + ( dProj1 - dPLen) * ( dDeltaR / m_dTipHeight))) {
|
|
|
|
// DeltaZ < 0
|
|
if ( dDeltaZ < 0) {
|
|
|
|
if ( dRatio <= 1 / dTan) {
|
|
|
|
if ( dProj1 < m_dTipHeight && dOrtLen < dMaxRad * dSen - dProj1 * dDeltaR * dSen / m_dTipHeight) { // Il limite inferiore d dProj1 è già stato imposto dall' if più esterno
|
|
|
|
double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ;
|
|
|
|
dMax = dZI + dH ;
|
|
}
|
|
else if ( dProj1 > 0 && dProj1 < dPLen &&
|
|
dOrtLen > dMaxRad * dSen && dOrtLen < dMaxRad) {
|
|
|
|
double dH = sqrt( dMaxRad * dMaxRad - dOrtLen * dOrtLen) ;
|
|
|
|
dMax = dZI + dH + dProj1 * dDeltaZ / dPLen ;
|
|
}
|
|
else if ( dProj1 > m_dHeight && dProj1 < dPLen + m_dHeight &&
|
|
dOrtLen < dMinRad * dSen) {
|
|
|
|
double dH = sqrt( dMinRad * dMinRad - dOrtLen * dOrtLen) ;
|
|
|
|
dMax = dZI + dH + ( dProj1 - m_dTipHeight) * dDeltaZ / dPLen ;
|
|
}
|
|
else if ( dProj1 >= dPLen &&
|
|
dOrtLen > dMaxRad * dSen - ( dProj1 - dPLen) * dDeltaR * dSen / m_dTipHeight) { // I limiti superiori sono già stati imposti dall' if più esterno
|
|
|
|
double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ;
|
|
|
|
double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ;
|
|
|
|
dMax = dZI + dDeltaZ + dH ;
|
|
}
|
|
else
|
|
|
|
dMin = ( dOrtLen > 0 ? (dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z : (dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z) ;
|
|
|
|
|
|
|
|
if ( dProj1 < dPLen) { // Limiti su dOrtLen già imposti dall' if esterno
|
|
|
|
double dH = sqrt( dMaxRad * dMaxRad - dOrtLen* dOrtLen) ;
|
|
|
|
dMin = dZI - dH + ( dProj1 - dPLen) * dDeltaZ / dPLen ;
|
|
}
|
|
else if ( dProj1 >= dPLen) { // Limiti su dOrtLen e su dProj1 già imposti dall' if esterno
|
|
|
|
double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ;
|
|
|
|
double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ;
|
|
|
|
dMax = dZI + dDeltaZ - dH ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMax, dMin) ;
|
|
}
|
|
else {
|
|
// dRatio >
|
|
}
|
|
}
|
|
else { // dDeltaZ > 0
|
|
|
|
if () { // dRatio <
|
|
|
|
}
|
|
else { // dRatio >
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
*/
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::XYLongVertConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
double dZL1, dZL2 ;
|
|
unsigned int nStartI, nEndI, nStartJ, nEndJ ;
|
|
|
|
bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
|
|
|
|
if ( ! Control)
|
|
return true ;
|
|
|
|
// Parte cilindrica
|
|
m_nToolType = CylindricalMill ;
|
|
|
|
double dSafeHeight = m_dHeight ;
|
|
double dSafeTipHeight = m_dTipHeight ;
|
|
double dCylH = m_dHeight - m_dTipHeight ;
|
|
|
|
m_dHeight = dCylH ;
|
|
m_dTipHeight = 0 ;
|
|
|
|
XYLongVertCylBall( ptLs, ptLe, vtToolDir) ;
|
|
|
|
m_nToolType = ConusMill ;
|
|
m_dHeight = dSafeHeight ;
|
|
m_dTipHeight = dSafeTipHeight ;
|
|
|
|
// Parte conica
|
|
|
|
Point3d ptI, ptF ;
|
|
Vector3d vtV1 ;
|
|
|
|
double dMinRad = min( m_dRadius, m_dTipRadius) ;
|
|
double dMaxRad = max( m_dRadius, m_dTipRadius) ;
|
|
double dDeltaR = dMaxRad - dMinRad ;
|
|
|
|
double dStem ;
|
|
|
|
if ( m_dRadius > m_dTipRadius) {
|
|
|
|
vtV1 = vtToolDir ;
|
|
dStem = - dCylH ;
|
|
}
|
|
else {
|
|
vtV1 = - vtToolDir ;
|
|
dStem = m_dHeight ;
|
|
}
|
|
|
|
if ( vtV1 * ( ptLe - ptLs) * ( ptLe.z - ptLs.z) > 0) {
|
|
|
|
ptI = ( ptLe.z - ptLs.z < 0 ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ;
|
|
ptF = ( ptLe.z - ptLs.z < 0 ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ;
|
|
}
|
|
|
|
else {
|
|
ptI = ( ptLe.z - ptLs.z > 0 ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ;
|
|
ptF = ( ptLe.z - ptLs.z > 0 ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ;
|
|
}
|
|
|
|
double dZI = ptI.z ;
|
|
double dDeltaZ = ptF.z - ptI.z ;
|
|
double dFactor = ( dDeltaZ > 0 ? - 1 : 1) ;
|
|
|
|
Vector3d vtV2 = vtV1 ; vtV2.Rotate(Z_AX, 90) ;
|
|
Vector3d vtV3 = vtV1 ^ vtV2 ;
|
|
Vector3d vtMove = ptF - ptI ;
|
|
Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dPLen = vtMoveXY.LenXY() ;
|
|
|
|
Point3d ptIxy( ptI.x, ptI.y, 0) ;
|
|
|
|
Point3d ptV = ptI - vtV1 * ( ( dMaxRad * m_dTipHeight) / dDeltaR) ;
|
|
|
|
// Apertura del cono e parametri per determinare i piani
|
|
double dTan = ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
double dRatio = ( dDeltaZ > 0 ? - ( vtMove * vtV1) / ( vtMove * vtV3) : ( vtMove * vtV1) / ( vtMove * vtV3)) ;
|
|
|
|
double dCos = dTan * dRatio ;
|
|
double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ;
|
|
|
|
double dDen = sqrt( 1 + dTan * dTan) ;
|
|
|
|
// Versori normali e prodotti scalari per per determinare i piani
|
|
Vector3d vtNs = - ( dTan / dDen) * vtV1 + dFactor * ( dCos / dDen) * vtV3 - dFactor * ( dSin / dDen) * vtV2 ;
|
|
Vector3d vtNd = - ( dTan /dDen) * vtV1 + dFactor * ( dCos / dDen) * vtV3 + dFactor * ( dSin / dDen) * vtV2 ;
|
|
Vector3d vtR0 = ptV - ORIG ;
|
|
double dDots = vtR0 * vtNs ;
|
|
double dDotd = vtR0 * vtNd ;
|
|
|
|
|
|
// 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 - ptIxy ;
|
|
|
|
double dProj1 = - vtC * vtV1 ; double dProj2 = vtC * vtV2 ; double dOrtLen = abs( dProj2) ;
|
|
|
|
if ( ( dProj1 > 0 && dProj1 < dPLen && dOrtLen < dMaxRad) ||
|
|
( dProj1 >= dPLen && dProj1 < dPLen + m_dTipHeight &&
|
|
dOrtLen < dMaxRad + ( dProj1 - dPLen) * ( dDeltaR / m_dTipHeight))) {
|
|
|
|
|
|
if ( dRatio <= 1 / dTan) {
|
|
|
|
if ( dProj1 < m_dTipHeight && dOrtLen < dMaxRad * dSin - dProj1 * dDeltaR * dSin / m_dTipHeight) { // Il limite inferiore d dProj1 è già stato imposto dall' if più esterno
|
|
|
|
double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ;
|
|
|
|
dZL1 = dZI + dFactor * dH ;
|
|
}
|
|
else if ( dProj1 > 0 && dProj1 < dPLen &&
|
|
dOrtLen > dMaxRad * dSin && dOrtLen < dMaxRad) {
|
|
|
|
double dH = sqrt( dMaxRad * dMaxRad - dOrtLen * dOrtLen) ;
|
|
|
|
dZL1 = dZI + dFactor * dH + dProj1 * dDeltaZ / dPLen ;
|
|
}
|
|
else if ( dProj1 > m_dTipHeight && dProj1 < dPLen + m_dHeight &&
|
|
dOrtLen < dMinRad * dSin) {
|
|
|
|
double dH = sqrt( dMinRad * dMinRad - dOrtLen * dOrtLen) ;
|
|
|
|
dZL1 = dZI + dFactor * dH + ( dProj1 - m_dTipHeight) * dDeltaZ / dPLen ;
|
|
}
|
|
else if ( dProj1 >= dPLen &&
|
|
dOrtLen > dMaxRad * dSin - ( dProj1 - dPLen) * dDeltaR * dSin / m_dTipHeight) { // I limiti superiori sono già stati imposti dall' if più esterno
|
|
|
|
double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ;
|
|
|
|
double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ;
|
|
|
|
dZL1 = dZI + dDeltaZ + dFactor * dH ;
|
|
}
|
|
else {
|
|
|
|
if ( dDeltaZ < 0)
|
|
|
|
dZL1 = ( dProj2 > 0 ? (dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z : (dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z) ;
|
|
else
|
|
dZL1 = ( dProj2 > 0 ? (dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z : (dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z) ;
|
|
}
|
|
|
|
|
|
|
|
if ( dProj1 < dPLen) { // Limiti su dOrtLen già imposti dall' if esterno
|
|
|
|
double dH = sqrt( dMaxRad * dMaxRad - dOrtLen* dOrtLen) ;
|
|
|
|
dZL2 = dZI - dFactor * dH + dProj1 * dDeltaZ / dPLen ;
|
|
}
|
|
else if ( dProj1 >= dPLen) { // Limiti su dOrtLen e su dProj1 già imposti dall' if esterno
|
|
|
|
double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ;
|
|
|
|
double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ;
|
|
|
|
dZL2 = dZI + dDeltaZ - dFactor * dH ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dZL1, dZL2) ;
|
|
}
|
|
else {
|
|
|
|
if ( dProj1 < dPLen && dOrtLen < dMaxRad) {
|
|
|
|
double dH = sqrt( dMaxRad * dMaxRad - dOrtLen * dOrtLen) ;
|
|
|
|
dZL1 = dZI + dH + dProj1 * dDeltaZ / dPLen ;
|
|
dZL2 = dZI - dH + dProj1 * dDeltaZ / dPLen ;
|
|
}
|
|
else if ( dProj1 >= dPLen) {
|
|
|
|
double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ;
|
|
|
|
double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ;
|
|
|
|
dZL1 = dZI + dDeltaZ + dH ;
|
|
dZL2 = dZI + dDeltaZ - dH ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dZL1, dZL2) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
|
|
if ( m_nToolType == CylindricalMill)
|
|
|
|
return MillingXYCyl( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else if ( m_nToolType == BallEndMill)
|
|
|
|
return MillingXYBall( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else if ( m_nToolType == ConusMill)
|
|
|
|
return MillingXYConus( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else
|
|
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingXYCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ;
|
|
double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ;
|
|
|
|
// Prima verifica sull'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL)
|
|
return true ;
|
|
|
|
Point3d ptI, ptF ;
|
|
|
|
if ( ptLs.z < ptLe.z) {
|
|
ptI = ptLs ;
|
|
ptF = ptLe ;
|
|
}
|
|
else {
|
|
ptI = ptLe ;
|
|
ptF = ptLs ;
|
|
}
|
|
|
|
// Quote dei punti ptI e ptF
|
|
double dZI = ptI.z ; double dZF = ptF.z ;
|
|
|
|
Point3d ptIT = ptI - vtToolDir * m_dHeight ;
|
|
Point3d ptFT = ptF - vtToolDir * m_dHeight ;
|
|
|
|
// Bounding box
|
|
double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ;
|
|
double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ;
|
|
double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ;
|
|
double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ;
|
|
|
|
// Seconda verifica dell'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
|
|
Vector3d vtMove = ptF - ptI ; //double dLenPath = vtMove.Len() ;
|
|
|
|
// Determino sistema di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento
|
|
Vector3d vtV1 = vtToolDir ;
|
|
Vector3d vtV2 = vtMove ; vtV2.Normalize() ;
|
|
Vector3d vtV3 = vtV1 ^ vtV2 ;
|
|
|
|
// Determinazione punti notevoli del volume spazzato dall'utensile
|
|
Point3d ptPlaneSup, ptPlaneInf ;
|
|
|
|
if ( vtV3.z > 0) {
|
|
ptPlaneInf = ptI - m_dRadius * vtV3 ;
|
|
ptPlaneSup = ptI + m_dRadius * vtV3 ;
|
|
}
|
|
else {
|
|
ptPlaneInf = ptI + m_dRadius * vtV3 ;
|
|
ptPlaneSup = ptI - m_dRadius * vtV3 ;
|
|
}
|
|
|
|
// Prodotti scalari per costruire i piani passanti per i punti notevoli
|
|
Vector3d vtR0Inf = ptPlaneInf - ORIG ;
|
|
Vector3d vtR0Sup = ptPlaneSup - ORIG ;
|
|
|
|
double dPInf = vtR0Inf * vtV3 ; double dPSup = vtR0Sup * vtV3 ;
|
|
|
|
// Determinazione delle proiezioni sul piano delle entità geometriche fondamentali
|
|
Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPlanePath = vtPlaneMove.Len() ; vtPlaneMove.Normalize() ;
|
|
Vector3d vtPlaneLim( m_dRadius * vtV3.x, m_dRadius * vtV3.y, 0) ; double dPlaneLim = vtPlaneLim.Len() ;
|
|
Point3d ptIxy( ptI.x, ptI.y, 0) ;
|
|
|
|
Vector3d vtTemp = vtV1 ; vtTemp.Rotate( Z_AX, 90) ;
|
|
Vector3d vtW2 = ( vtTemp * vtV2 > 0 ? vtTemp : - vtTemp) ;
|
|
|
|
// Determinazione limiti sugli indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
// Ciclo
|
|
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 ;
|
|
double dZInf = ( dPInf - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y
|
|
double dZSup = ( dPSup - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y
|
|
|
|
Point3d ptC( dX, dY, 0) ;
|
|
Vector3d vtC = ptC - ptIxy ;
|
|
|
|
double dProj1 = vtC * vtV1 ; // vtV1 è vtToolDir che per il momento giace nel piano
|
|
double dProj2 = vtC * vtW2 ; // vtPlaneMove è stato normalizzato dopo averne calcolato la lunghezza
|
|
|
|
if ( dProj1 < 0 && dProj1 > - m_dHeight && dProj2 > - m_dRadius && dProj2 < dPlanePath + m_dRadius) {
|
|
|
|
|
|
// Minimi
|
|
if ( dProj2 > - m_dRadius && dProj2 < dPlaneLim) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ;
|
|
|
|
dMin = dZI - dH ;
|
|
}
|
|
else if ( dProj2 >= dPlaneLim && dProj2 < dPlanePath + dPlaneLim) {
|
|
|
|
dMin = dZInf ;
|
|
}
|
|
else if ( dProj2 >= dPlanePath + dPlaneLim && dProj2 < dPlanePath + m_dRadius) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ;
|
|
|
|
dMin = dZF - dH ;
|
|
}
|
|
// Massimi
|
|
if ( dProj2 > - m_dRadius && dProj2 < - dPlaneLim) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ;
|
|
|
|
dMax = dZI + dH ;
|
|
}
|
|
else if ( dProj2 >= - dPlaneLim && dProj2 < dPlanePath - dPlaneLim) {
|
|
|
|
dMax = dZSup ;
|
|
}
|
|
else if ( dProj2 >= dPlanePath - dPlaneLim && dProj2 < dPlanePath + m_dRadius) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ;
|
|
|
|
dMax = dZF + dH ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingXYBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ;
|
|
double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ;
|
|
|
|
// Prima verifica sull'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL)
|
|
return true ;
|
|
|
|
Point3d ptI, ptF ;
|
|
|
|
if ( ptLs.z < ptLe.z) {
|
|
ptI = ptLs ;
|
|
ptF = ptLe ;
|
|
}
|
|
else {
|
|
ptI = ptLe ;
|
|
ptF = ptLs ;
|
|
}
|
|
|
|
// Quote dei punti ptI e ptF e DeltaZ
|
|
double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ;
|
|
|
|
Point3d ptIT = ptI - vtToolDir * m_dHeight ;
|
|
Point3d ptFT = ptF - vtToolDir * m_dHeight ;
|
|
|
|
// Bounding box
|
|
double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ;
|
|
double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ;
|
|
double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ;
|
|
double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ;
|
|
|
|
// Seconda verifica dell'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
|
|
Vector3d vtMove = ptF - ptI ;
|
|
|
|
// Determino sistema di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento
|
|
Vector3d vtV1 = vtToolDir ;
|
|
Vector3d vtV2 = vtMove ; vtV2.Normalize() ;
|
|
Vector3d vtV3 = vtV1 ^ vtV2 ;
|
|
|
|
// Determinazione punti notevoli del volume spazzato dall'utensile
|
|
Point3d ptPlaneSup, ptPlaneInf ;
|
|
|
|
if ( vtV3.z > 0) {
|
|
ptPlaneInf = ptI - m_dRadius * vtV3 ;
|
|
ptPlaneSup = ptI + m_dRadius * vtV3 ;
|
|
}
|
|
else {
|
|
ptPlaneInf = ptI + m_dRadius * vtV3 ;
|
|
ptPlaneSup = ptI - m_dRadius * vtV3 ;
|
|
}
|
|
|
|
// Prodotti scalari per costruire i piani passanti per i punti notevoli
|
|
Vector3d vtR0Inf = ptPlaneInf - ORIG ;
|
|
Vector3d vtR0Sup = ptPlaneSup - ORIG ;
|
|
|
|
double dPInf = vtR0Inf * vtV3 ; double dPSup = vtR0Sup * vtV3 ;
|
|
|
|
// Determinazione delle proiezioni sul piano delle entità geometriche fondamentali
|
|
Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPlanePath = vtPlaneMove.Len() ; vtPlaneMove.Normalize() ;
|
|
Vector3d vtPlaneLim( m_dRadius * vtV3.x, m_dRadius * vtV3.y, 0) ; double dPlaneLim = vtPlaneLim.Len() ;
|
|
Point3d ptIxy( ptI.x, ptI.y, 0) ;
|
|
|
|
Vector3d vtTemp = vtToolDir ; vtTemp.Rotate( Z_AX, 90) ;
|
|
Vector3d vtW2 = ( vtTemp * vtV2 > 0 ? vtTemp : - vtTemp) ;
|
|
|
|
// Determinazione limiti sugli indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
// Ciclo
|
|
for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) {
|
|
for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
|
|
double dMin, dMax ;
|
|
double dCylH = m_dHeight - m_dRadius ;
|
|
|
|
double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ;
|
|
double dZInf = ( dPInf - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y
|
|
double dZSup = ( dPSup - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y
|
|
|
|
Point3d ptC( dX, dY, 0) ;
|
|
Vector3d vtC = ptC - ptIxy ;
|
|
|
|
double dProj1 = vtC * vtV1 ; // vtV1 è vtToolDir che per il momento giace nel piano
|
|
double dProj2 = vtC * vtW2 ; // vtPlaneMove è stato normalizzato dopo averne calcolato la lunghezza
|
|
|
|
// Parte cilindrica
|
|
if ( dProj1 < 0 && dProj1 > - dCylH && dProj2 > - m_dRadius && dProj2 < dPlanePath + m_dRadius) {
|
|
|
|
// Minimi
|
|
if ( dProj2 > - m_dRadius && dProj2 < dPlaneLim) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ;
|
|
|
|
dMin = dZI - dH ;
|
|
}
|
|
else if ( dProj2 >= dPlaneLim && dProj2 < dPlanePath + dPlaneLim) {
|
|
|
|
dMin = dZInf ;
|
|
}
|
|
else if ( dProj2 >= dPlanePath + dPlaneLim && dProj2 < dPlanePath + m_dRadius) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ;
|
|
|
|
dMin = dZF - dH ;
|
|
}
|
|
// Massimi
|
|
if ( dProj2 > - m_dRadius && dProj2 < - dPlaneLim) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ;
|
|
|
|
dMax = dZI + dH ;
|
|
}
|
|
else if ( dProj2 >= - dPlaneLim && dProj2 < dPlanePath - dPlaneLim) {
|
|
|
|
dMax = dZSup ;
|
|
}
|
|
else if ( dProj2 >= dPlanePath - dPlaneLim && dProj2 < dPlanePath + m_dRadius) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ;
|
|
|
|
dMax = dZF + dH ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
// Parte sferica
|
|
else if ( dProj1 <= - dCylH && ( ( dProj2 > - m_dRadius && dProj2 < 0 && dProj2 * dProj2 + (- dProj1 - dCylH) * (- dProj1 - dCylH) < m_dRadius * m_dRadius) ||
|
|
( dProj2 >= 0 && dProj2 < dPlanePath && dProj1 > - m_dHeight) ||
|
|
( dProj2 >= dPlanePath && dProj2 < dPlanePath + m_dRadius && ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath) + (- dProj1 - dCylH) * (- dProj1 - dCylH) < m_dRadius * m_dRadius))) {
|
|
|
|
|
|
double dSemiMin = dPlaneLim ; double dSemiMax = m_dRadius ; // Semi-assi dell'ellisse
|
|
double dl = - dProj1 - dCylH ;
|
|
|
|
// Massimi
|
|
if ( dProj2 < - dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) {
|
|
|
|
double dr = sqrt( dProj2 * dProj2 + dl * dl) ;
|
|
double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ;
|
|
|
|
dMax = dZI + dH ;
|
|
}
|
|
else if ( dProj2 < dPlanePath - dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) {
|
|
|
|
double dCos = abs( vtV3 * Z_AX) ;
|
|
|
|
dMax = dZI + sqrt( m_dRadius * m_dRadius - dl * dl) * dCos + ( dDeltaZ / dPlanePath) * ( dProj2 + dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) ;
|
|
}
|
|
else {
|
|
|
|
double dL = dProj2 - dPlanePath ;
|
|
double dr = sqrt( dL * dL + dl * dl) ;
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ;
|
|
|
|
dMax = dZF + dH ;
|
|
}
|
|
|
|
// Minimi
|
|
if ( dProj2 < dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) {
|
|
|
|
double dr = sqrt( dProj2 * dProj2 + dl * dl) ;
|
|
double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ;
|
|
|
|
dMin = dZI - dH ;
|
|
}
|
|
else if ( dProj2 < dPlanePath + dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) {
|
|
|
|
double dCos = abs( vtV3 * Z_AX) ;
|
|
|
|
dMin = dZI - sqrt( m_dRadius * m_dRadius - dl * dl) * dCos + ( dDeltaZ / dPlanePath) * ( dProj2 - dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) ;
|
|
}
|
|
else {
|
|
|
|
double dr = sqrt( ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath) + dl * dl) ;
|
|
double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ;
|
|
|
|
dMin = dZF - dH ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingXYConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
double dMin, dMax ;
|
|
unsigned int nStartI, nStartJ, nEndI, nEndJ ;
|
|
|
|
bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
|
|
|
|
if ( ! Control)
|
|
return true ;
|
|
|
|
double dCylH = m_dHeight - m_dTipHeight ;
|
|
|
|
// Parte cilindrica
|
|
m_nToolType = CylindricalMill ;
|
|
m_dHeight = dCylH ;
|
|
|
|
MillingXY( ptLs, ptLe, vtToolDir) ;
|
|
|
|
m_nToolType = ConusMill ;
|
|
m_dHeight = m_dHeight + m_dTipHeight ;
|
|
|
|
Vector3d vtV1, vtV2, vtV3 ;
|
|
Point3d ptI, ptF ;
|
|
|
|
double dStem ;
|
|
|
|
double dMinRad = min( m_dRadius, m_dTipRadius) ;
|
|
double dMaxRad = max( m_dRadius, m_dTipRadius) ;
|
|
double dDeltaR = dMaxRad - dMinRad ;
|
|
|
|
// Studio della parte conica
|
|
if ( m_dRadius > m_dTipRadius) {
|
|
|
|
vtV1 = vtToolDir ;
|
|
dStem = - dCylH ;
|
|
}
|
|
else {
|
|
|
|
vtV1 = - vtToolDir ;
|
|
dStem = m_dHeight ;
|
|
}
|
|
|
|
ptI = ( ptLs.z < ptLe.z ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ;
|
|
ptF = ( ptLs.z < ptLe.z ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ;
|
|
|
|
Point3d ptIxy( ptI.x, ptI.y, 0) ; double dZI = ptI.z ; double dDeltaZ = ptF.z - ptI.z ;
|
|
|
|
Vector3d vtMove = ptF - ptI ;
|
|
Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dPLen = vtMoveXY.LenXY() ;
|
|
Vector3d vtU2 = vtV1 ; vtU2.Rotate(Z_AX, 90) ;
|
|
|
|
if ( vtMoveXY * vtU2 < 0)
|
|
|
|
vtU2 = - vtU2 ;
|
|
|
|
vtV2 = vtMove ; vtV2.Normalize() ;
|
|
vtV3 = vtV1 ^ vtV2 ;
|
|
|
|
Point3d ptV = ptI - vtV1 * ( dMaxRad * m_dTipHeight / ( dMaxRad - dMinRad)) ;
|
|
|
|
Vector3d vtV3XY( vtV3.x, vtV3.y, 0) ;
|
|
|
|
double dPrV3 = vtV3XY.LenXY() ;
|
|
double dRl = dMaxRad * dPrV3 ;
|
|
double drl = dMinRad * dPrV3 ;
|
|
double dDl = dDeltaR * dPrV3 ;
|
|
|
|
// 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 = ( 1 - dCos * dCos > 0 ? 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) {
|
|
|
|
double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ;
|
|
|
|
Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ;
|
|
|
|
double dProj1 = - vtC * vtV1 ; double dProj2 = vtC * vtU2 ;
|
|
|
|
if ( dProj1 > 0 && dProj1 < m_dTipHeight &&
|
|
dProj2 > - dMaxRad + dProj1 * dDeltaR / m_dTipHeight &&
|
|
dProj2 < dPLen + dMaxRad - dProj1 * dDeltaR / m_dTipHeight) {
|
|
/*
|
|
if ( dProj2 < - dRl + dProj1 * dDl / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - dProj2 * dProj2) ;
|
|
|
|
dMin = dZI - dH ;
|
|
dMax = dZI + dH ;
|
|
}
|
|
else if ( dProj2 >= - dRl + dProj1 * dDl / m_dTipHeight &&
|
|
dProj2 < dRl - dProj1 * dDl / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - dProj2 * dProj2) ;
|
|
|
|
dMin = dZI - dH ;
|
|
dMax = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ;
|
|
}
|
|
else if ( dProj2 >= dRl - dProj1 * dDl / m_dTipHeight &&
|
|
dProj2 < dPLen - dRl + dProj1 * dDl / m_dTipHeight) {
|
|
|
|
dMin = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ;
|
|
dMax = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ;
|
|
}
|
|
else if ( dProj2 >= dPLen - dRl + dProj1 * dDl / m_dTipHeight &&
|
|
dProj2 < dPLen + dRl - dProj1 * dDl / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - ( dProj2 - dPLen) * ( dProj2 - dPLen)) ;
|
|
|
|
dMin = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ;
|
|
dMax = dZI + dDeltaZ + dH ;
|
|
}
|
|
else {
|
|
|
|
double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - ( dProj2 - dPLen) * ( dProj2 - dPLen)) ;
|
|
|
|
dMin = dZI + dDeltaZ - dH ;
|
|
dMax = dZI + dDeltaZ + dH ;
|
|
} */
|
|
|
|
// Massimi
|
|
if ( dProj2 < - dRl + dProj1 * dDl / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - dProj2 * dProj2) ;
|
|
|
|
dMax = dZI + dH ;
|
|
}
|
|
else if ( dProj2 >= - dRl + dProj1 * dDl / m_dTipHeight &&
|
|
dProj2 < dPLen - dRl + dProj1 * dDl / m_dTipHeight)
|
|
|
|
dMax = ( vtV3.z < 0 ? ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z : ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z) ;
|
|
else {
|
|
|
|
double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - ( dProj2 - dPLen) * ( dProj2 - dPLen)) ;
|
|
|
|
dMax = dZI + dDeltaZ + dH ;
|
|
}
|
|
|
|
// Minimi
|
|
if ( dProj2 < dRl - dProj1 * dDl / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - dProj2 * dProj2) ;
|
|
|
|
dMin = dZI - dH ;
|
|
}
|
|
else if ( dProj2 >= dRl - dProj1 * dDl / m_dTipHeight &&
|
|
dProj2 < dPLen + dRl - dProj1 * dDl / m_dTipHeight)
|
|
|
|
dMin = ( vtV3.z < 0 ? ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z : ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z) ;
|
|
|
|
else {
|
|
|
|
double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - ( dProj2 - dPLen) * ( dProj2 - dPLen)) ;
|
|
|
|
dMin = dZI + dDeltaZ - dH ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingXYPlus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) {
|
|
|
|
if ( m_nToolType == CylindricalMill)
|
|
|
|
return MillingXYPlusCyl( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else if ( m_nToolType == BallEndMill)
|
|
|
|
return MillingXYPlusBall( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else if ( m_nToolType == ConusMill)
|
|
|
|
return MillingXYPlusConus( ptLs, ptLe, vtToolDir) ;
|
|
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingXYPlusCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ;
|
|
double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ;
|
|
|
|
// Prima verifica sull'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL)
|
|
return true ;
|
|
|
|
Point3d ptI, ptF ;
|
|
|
|
if ( ptLs.z <= ptLe.z) {
|
|
ptI = ptLs ;
|
|
ptF = ptLe ;
|
|
}
|
|
else {
|
|
ptI = ptLe ;
|
|
ptF = ptLs ;
|
|
}
|
|
|
|
// Quote dei punti ptI e ptF e DeltaZ
|
|
double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ;
|
|
|
|
Point3d ptIT = ptI - vtToolDir * m_dHeight ;
|
|
Point3d ptFT = ptF - vtToolDir * m_dHeight ;
|
|
|
|
// Bounding box
|
|
double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ;
|
|
double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ;
|
|
double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ;
|
|
double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ;
|
|
|
|
// Seconda verifica dell'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
|
|
// Vettori di riferimento nello spazio e controllo per simmetria
|
|
Vector3d vtMove = ptF - ptI ;
|
|
Vector3d vtTool = vtToolDir ;
|
|
|
|
if ( vtToolDir * vtMove > 0) {
|
|
|
|
Point3d ptTemp = ptI ;
|
|
ptI = ptIT ; ptIT = ptTemp ;
|
|
ptTemp = ptF ;
|
|
ptF = ptFT ;
|
|
ptFT = ptTemp ;
|
|
vtTool = - vtTool ;
|
|
}
|
|
|
|
Vector3d vtMoveLong = ( vtMove * vtTool) * vtTool ; double dLen1 = vtMoveLong.Len() ;
|
|
Vector3d vtMoveOrt = vtMove - vtMoveLong ; double dLen2 = vtMoveOrt.Len() ;
|
|
|
|
// Vettori di riferimento nel piano
|
|
Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPLen = vtPlaneMove.LenXY() ;
|
|
Vector3d vtPlaneMoveLong( vtMoveLong.x, vtMoveLong.y, 0) ; double dPLen1 = vtPlaneMoveLong.LenXY() ;
|
|
Vector3d vtPlaneMoveOrt( vtMoveOrt.x, vtMoveOrt.y, 0) ; double dPLen2 = vtPlaneMoveOrt.LenXY() ; vtPlaneMoveOrt.Normalize() ;
|
|
|
|
// Punti iniziale e finale proiettati sul piano
|
|
Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ;
|
|
|
|
// Determino i sistemi di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento
|
|
Vector3d vtV1 = vtTool ;
|
|
Vector3d vtV2 = vtMoveOrt ; vtV2.Normalize() ;
|
|
Vector3d vtV3 = vtV1 ^ vtV2 ;
|
|
|
|
// Determinazione punti notevoli del volume spazzato dall'utensile
|
|
Point3d ptPlaneSup, ptPlaneInf ;
|
|
|
|
if ( vtV3.z > 0) {
|
|
ptPlaneInf = ptI - m_dRadius * vtV3 ;
|
|
ptPlaneSup = ptI + m_dRadius * vtV3 ;
|
|
}
|
|
else {
|
|
ptPlaneInf = ptI + m_dRadius * vtV3 ;
|
|
ptPlaneSup = ptI - m_dRadius * vtV3 ;
|
|
}
|
|
|
|
Point3d ptPlaneSupxy( ptPlaneSup.x, ptPlaneSup.y, 0) ;
|
|
Point3d ptPlaneInfxy( ptPlaneInf.x, ptPlaneInf.y, 0) ;
|
|
|
|
double dr = sqrt( ( ptPlaneSupxy - ptIxy) * ( ptPlaneSupxy - ptIxy)) ;
|
|
|
|
// Determinazione degli analoghi punti sulla punta dell'utensile e delle loro proiezioni sul piano XY
|
|
Point3d ptPlTInf = ptPlaneInf - m_dHeight * vtTool ; Point3d ptPlTInfxy( ptPlTInf.x, ptPlTInf.y, 0) ;
|
|
Point3d ptPlTSup = ptPlaneSup - m_dHeight * vtTool ; Point3d ptPlTSupxy( ptPlTSup.x, ptPlTSup.y, 0) ;
|
|
|
|
// Prodotti scalari per costruire i piani passanti per i punti notevoli
|
|
Vector3d vtR0Inf = ptPlaneInf - ORIG ;
|
|
Vector3d vtR0Sup = ptPlaneSup - ORIG ;
|
|
Vector3d vtR0 = ptI - ORIG ;
|
|
double dPInf = vtR0Inf * vtV3 ; double dPSup = vtR0Sup * vtV3 ; double dP = vtR0 * vtV3 ;
|
|
|
|
// Determinazione limiti sugli indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
// Ciclo
|
|
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 ;
|
|
double dZPInf = ( dPInf - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y
|
|
double dZPSup = ( dPSup - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano superiore come funzione di x e y
|
|
|
|
// Punto e vettori del ciclo
|
|
Point3d ptC( dX, dY, 0) ; Vector3d vtCi = ptC - ptIxy ;
|
|
// Proiezione fondamentale
|
|
double dPro1 = vtCi * vtV1 ; double dPro2 = vtCi * vtPlaneMoveOrt ;
|
|
|
|
|
|
// Se il punto cade nella proiezione sul piano XY del volume spazzato si taglia
|
|
if ( ((dPro2 > - m_dRadius && dPro2 < m_dRadius) && (((dPro2 < dPLen2 - m_dRadius && (dPro1 > - m_dHeight - (dPLen1 / dPLen2) * (dPro2 + m_dRadius) && dPro1 < 0))) || (dPro2 >= dPLen2 - m_dRadius && (dPro1 > - m_dHeight - dPLen1 && dPro1 < 0))))
|
|
|| ((dPro2 >= m_dRadius && dPro2 < dPLen2 + m_dRadius) && ((dPro2 < dPLen2 - m_dRadius && (dPro1 > - (dPLen1 / dPLen2) * (dPro2 + m_dRadius) - m_dHeight && dPro1 < - (dPLen1 / dPLen2) * (dPro2 - m_dRadius))) || (dPro2 >= dPLen2 - m_dRadius && (dPro1 > - m_dHeight - dPLen1 && dPro1 < - (dPLen1 / dPLen2) * (dPro2 - m_dRadius)))))) {
|
|
|
|
// Massimi //////////////////////////////////////////////////////////////////////////
|
|
// Prima zona cilindrica superiore
|
|
if ( ( dPro2 > - m_dRadius && dPro2 < - dr) && ( dPro1 > - m_dHeight && dPro1 < 0)) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dPro2 * dPro2) ;
|
|
|
|
dMax = dZI + dH ;
|
|
}
|
|
|
|
// Vettore per seconda zona cilindrica superiore
|
|
Vector3d vtCf = ptC - ptFxy ;
|
|
// Proiezione per seconda zona cilindrica sueriore
|
|
double dPr1 = vtCf * vtV1 ; double dPr2 = vtCf * vtPlaneMoveOrt ;
|
|
|
|
// Seconda zona cilindrica superiore
|
|
if ( ( dPr2 >= - dr && dPr2 < m_dRadius) && ( dPr1 > - m_dHeight && dPr1 <= 0)) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dPr2 * dPr2) ;
|
|
|
|
dMax = dZF + dH ;
|
|
}
|
|
|
|
// Vettore per Piano superiore e zona di fondo superiore
|
|
Vector3d vtCS = ptC - ptPlaneSupxy ;
|
|
// Proiezioni
|
|
double dPrS1 = vtCS * vtV1 ; double dPrS2 = vtCS * vtPlaneMoveOrt ;
|
|
|
|
// Piano superiore
|
|
if ( dPrS2 >= 0 && dPrS2 < dPLen2 && dPrS1 > - m_dHeight - ( dPLen1/dPLen2) * dPrS2 && dPrS1 <= - ( dPLen1/dPLen2) * dPrS2)
|
|
|
|
dMax = dZPSup ;
|
|
|
|
// Vettore per zona di punta superiore
|
|
Vector3d vtCTS = ptC - ptPlTSupxy ;
|
|
// Proiezioni
|
|
double dPrTS1 = vtCTS * vtV1 ; double dPrTS2 = vtCTS * vtPlaneMoveOrt ;
|
|
|
|
// Zona di punta superiore
|
|
if ( dPrTS1 <= 0 && dPrTS1 > - dPLen1)
|
|
if ( dPrTS2 <= - ( dPLen2 / dPLen1) * dPrTS1 && dPrTS2 > - ( m_dRadius - dr) - ( dPLen2 / dPLen1) * dPrTS1) {
|
|
|
|
double dDist = - ( dPLen2 / dPLen1) * dPrTS1 - dPrTS2 ;
|
|
double dL = dDist + dr ;
|
|
double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ;
|
|
double dl = sqrt( dPrTS1 * dPrTS1 + ( ( dPLen2 / dPLen1) * dPrTS1) * ( ( dPLen2 / dPLen1) * dPrTS1)) ;
|
|
|
|
dMax = dZI + ( dDeltaZ / dPLen) * dl + dH ;
|
|
}
|
|
|
|
// Zona di fondo superiore
|
|
if ( dPrS1 < 0 && dPrS1 > - dPLen1)
|
|
if ( dPrS2 > - ( dPLen2 / dPLen1) * dPrS1 && dPrS2 < m_dRadius + dr - ( dPLen2 / dPLen1) * dPrS1) {
|
|
|
|
double dL = abs( dr - ( dPLen2 / dPLen1) * dPrS1 - dPrS2) ;
|
|
double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ;
|
|
double dl = sqrt( dPrS1 * dPrS1 + ( ( dPLen2 / dPLen1) * dPrS1) * ( ( dPLen2 / dPLen1) * dPrS1)) ;
|
|
|
|
dMax = dZI + ( dDeltaZ / dPLen) * dl + dH ;
|
|
}
|
|
|
|
// Minimi //////////////////////////////////////////////////////////////////////////
|
|
// Prima zona cilindrica inferiore
|
|
if ( ( dPro2 > - m_dRadius && dPro2 < dr) && ( dPro1 > - m_dHeight && dPro1 < 0)) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dPro2 * dPro2) ;
|
|
|
|
dMin = dZI - dH ;
|
|
}
|
|
|
|
// Seconda zona cilindrica inferiore
|
|
if ( ( dPr2 >= dr && dPr2 < m_dRadius) && ( dPr1 > - m_dHeight && dPr1 <= 0)) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dPr2 * dPr2) ;
|
|
|
|
dMin = dZF - dH ;
|
|
}
|
|
|
|
// Vettore per piano inferiore e zona di fondo inferiore
|
|
Vector3d vtCI = ptC - ptPlaneInfxy ;
|
|
// Proiezioni
|
|
double dPrI1 = vtCI * vtV1 ; double dPrI2 = vtCI * vtPlaneMoveOrt ;
|
|
|
|
// Piano inferiore
|
|
if ( dPrI2 >= 0 && dPrI2 < dPLen2 && dPrI1 > - m_dHeight - ( dPLen1/dPLen2) * dPrI2 && dPrI1 <= - ( dPLen1/dPLen2) * dPrI2)
|
|
|
|
dMin = dZPInf ;
|
|
|
|
// Zona di fondo inferiore
|
|
if ( dPrI1 <= 0 && dPrI1 > - dPLen1)
|
|
if ( dPrI2 > - ( dPLen2 / dPLen1) * dPrI1 && dPrI2 < ( m_dRadius - dr) - ( dPLen2 / dPLen1) * dPrI1) {
|
|
|
|
double dDist = dPrI2 + ( dPLen2 / dPLen1) * dPrI1 ;
|
|
double dL = dDist + dr ;
|
|
double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ;
|
|
double dl = sqrt( dPrI1 * dPrI1 + ( ( dPLen2 / dPLen1) * dPrI1) * ( ( dPLen2 / dPLen1) * dPrI1)) ;
|
|
|
|
dMin = dZI + ( dDeltaZ / dPLen) * dl - dH ;
|
|
}
|
|
|
|
// Vettore per zona di punta inferiore
|
|
Vector3d vtCTI = ptC - ptPlTInfxy ;
|
|
// Proiezioni
|
|
double dPrTI1 = vtCTI * vtV1 ; double dPrTI2 = vtCTI * vtPlaneMoveOrt ;
|
|
|
|
// zona di punta inferiore
|
|
if ( dPrTI1 <= 0 && dPrTI1 > - dPLen1)
|
|
if ( dPrTI2 > - m_dRadius - dr - ( dPLen2 / dPLen1) * dPrTI1 && dPrTI2 < - ( dPLen2 / dPLen1) * dPrTI1) {
|
|
|
|
double dL = abs( - dr - ( dPLen2 / dPLen1) * dPrTI1 - dPrTI2) ;
|
|
double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ;
|
|
double dl = sqrt( dPrTI1 * dPrTI1 + ( ( dPLen2 / dPLen1) * dPrTI1) * ( ( dPLen2 / dPLen1) * dPrTI1)) ;
|
|
|
|
dMin = dZI + ( dDeltaZ / dPLen) * dl - dH ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingXYPlusBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
// Parte cilindrica
|
|
|
|
double dCylH = m_dHeight - m_dRadius ;
|
|
|
|
m_dHeight = dCylH ;
|
|
|
|
MillingXYPlusCyl( ptLs, ptLe, vtToolDir) ;
|
|
|
|
m_dHeight = m_dHeight + m_dRadius ;
|
|
////////////////////////////////////////
|
|
Point3d ptI, ptF ;
|
|
|
|
if ( ptLs.z < ptLe.z) {
|
|
|
|
ptI = ptLs ;
|
|
ptF = ptLe ;
|
|
}
|
|
else {
|
|
|
|
ptI = ptLe ;
|
|
ptF = ptLs ;
|
|
}
|
|
|
|
double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ;
|
|
|
|
Point3d ptCI = ptI - dCylH * vtToolDir ;
|
|
Point3d ptCF = ptF - dCylH * vtToolDir ;
|
|
|
|
Point3d ptCIxy( ptCI.x, ptCI.y, 0) ;
|
|
|
|
// Bounding box
|
|
double dMinX = min( ptCI.x, ptCF.x) - m_dRadius ;
|
|
double dMaxX = max( ptCI.x, ptCF.x) + m_dRadius ;
|
|
double dMinY = min( ptCI.y, ptCF.y) - m_dRadius ;
|
|
double dMaxY = max( ptCI.y, ptCF.y) + m_dRadius ;
|
|
|
|
Vector3d vtMove = ptF - ptI ;
|
|
Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPLen = vtPlaneMove.LenXY() ; vtMove.Normalize() ;
|
|
|
|
// Sistema di riferimento nel piano
|
|
Vector3d vtV2 = vtPlaneMove ; vtV2.Normalize() ; double dComp1 = vtV2 * X_AX ; double dComp2 = vtV2 * Y_AX ;
|
|
Vector3d vtV1 = dComp2 * X_AX - dComp1 * Y_AX ;
|
|
|
|
// Determino il semi-asse minore
|
|
double dOriz = vtMove * Z_AX ; double dVert = vtMove * vtV2 ;
|
|
|
|
double dSemiAxMin = m_dRadius * dOriz ;
|
|
|
|
// Determinazione limiti sugli indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
// Ciclo
|
|
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 - ptCIxy ;
|
|
|
|
double dProj1 = vtC * vtV1 ; double dProj2 = vtC * vtV2 ;
|
|
|
|
double dSqRadDistI = dProj1 * dProj1 + dProj2 * dProj2 ;
|
|
double dSqRadDistF = dProj1 * dProj1 + ( dProj2 - dPLen) * ( dProj2 - dPLen) ;
|
|
double dSqAxDist = dProj1 * dProj1 ;
|
|
|
|
if ( ( dProj2 < 0 && dSqRadDistI < m_dRadius * m_dRadius) ||
|
|
( dProj2 >= 0 && dProj2 < dPLen && dSqAxDist < m_dRadius * m_dRadius) ||
|
|
( dProj2 >= dPLen && dSqRadDistF < m_dRadius * m_dRadius)) {
|
|
|
|
// Massimi
|
|
if ( dProj2 < - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistI) ;
|
|
|
|
dMax = dZI + dH ;
|
|
}
|
|
else if ( dProj2 >= - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) &&
|
|
dProj2 < dPLen - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) {
|
|
|
|
double dProj0 = - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) ;
|
|
double dZ0 = dZI + dVert * sqrt( m_dRadius * m_dRadius - dSqAxDist) ;
|
|
|
|
dMax = dZ0 + ( dDeltaZ / dPLen) * ( dProj2 - dProj0) ;
|
|
}
|
|
else {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistF) ;
|
|
|
|
dMax = dZF + dH ;
|
|
}
|
|
|
|
// Minimi
|
|
if ( dProj2 < dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistI) ;
|
|
|
|
dMin = dZI - dH ;
|
|
}
|
|
else if ( dProj2 >= dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) &&
|
|
dProj2 < dPLen + dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) {
|
|
|
|
double dProj0 = dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) ;
|
|
double dZ0 = dZI - dVert * sqrt( m_dRadius * m_dRadius - dSqAxDist) ;
|
|
|
|
dMin = dZ0 + ( dDeltaZ / dPLen) * ( dProj2 - dProj0) ;
|
|
}
|
|
else {
|
|
|
|
double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistF) ;
|
|
|
|
dMin = dZF - dH ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingXYPlusConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
double dMin, dMax ;
|
|
|
|
bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir) ;
|
|
|
|
if ( Control == false)
|
|
|
|
return true ;
|
|
|
|
double dMinRad = min( m_dRadius, m_dTipRadius) ;
|
|
double dMaxRad = max( m_dRadius, m_dTipRadius) ;
|
|
double dDeltaR = dMaxRad - dMinRad ;
|
|
|
|
double dCylH = m_dHeight - m_dTipHeight ;
|
|
|
|
// Parte cilindrica
|
|
m_nToolType = CylindricalMill ;
|
|
m_dHeight = dCylH ;
|
|
|
|
MillingXYPlusCyl( ptLs, ptLe, vtToolDir) ;
|
|
|
|
m_nToolType = ConusMill ;
|
|
m_dHeight = m_dHeight + m_dTipHeight ;
|
|
|
|
// Variabili di interesse per la parte conica
|
|
Vector3d vtV1, vtV2, vtV3 ;
|
|
Point3d ptI, ptF ;
|
|
|
|
double dStem ;
|
|
|
|
// Studio della parte conica
|
|
if ( m_dRadius > m_dTipRadius) {
|
|
|
|
vtV1 = vtToolDir ;
|
|
dStem = - dCylH ;
|
|
}
|
|
else {
|
|
|
|
vtV1 = - vtToolDir ;
|
|
dStem = m_dHeight ;
|
|
}
|
|
|
|
ptI = ( ptLs.z < ptLe.z ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ;
|
|
ptF = ( ptLs.z < ptLe.z ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ;
|
|
|
|
Point3d ptIxy( ptI.x, ptI.y, 0) ;
|
|
|
|
Vector3d vtMove = ptF - ptI ;
|
|
Vector3d vtMoveLong = ( vtMove * vtV1) * vtV1 ;
|
|
Vector3d vtMoveOrt = vtMove - vtMoveLong ;
|
|
Vector3d vtMoveLongXY( vtMoveLong.x, vtMoveLong.y, 0) ;
|
|
Vector3d vtMoveOrtXY( vtMoveOrt.x, vtMoveOrt.y, 0) ;
|
|
|
|
double dPLen1 = vtMoveLongXY.LenXY() ;
|
|
double dPLen2 = vtMoveOrtXY.LenXY() ;
|
|
double dPLen = sqrt( dPLen1 * dPLen1 + dPLen2 * dPLen2) ;
|
|
|
|
vtV2 = ( vtMove * vtV1 > 0 ? vtMoveOrt : - vtMoveOrt) ; vtV2.Normalize() ;
|
|
vtV3 = vtV1 ^ vtV2 ;
|
|
|
|
Vector3d vtU2 = vtMoveOrtXY ; vtU2.Normalize() ;
|
|
|
|
Point3d ptV = ptI - vtV1 * ( ( dMaxRad * m_dTipHeight) / ( dDeltaR)) ;
|
|
|
|
// Apertura del cono e parametri per determinare i piani
|
|
double dTan = ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ;
|
|
|
|
double dCos = dTan * dRatio ; // dCos è compreso fra 0 e 1 poiché alpha è compreso fra 0 e Pi mezzi
|
|
double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ;
|
|
|
|
double dDen = sqrt( 1 + dTan * dTan) ;
|
|
|
|
double dZI = ptI.z ;
|
|
double dDeltaZ = ptF.z - ptI.z ;
|
|
// double dCornerSlope = atan2( dDeltaZ, dPLen1) ; // dCornerSlope è compreso fra 0 ° e 90 °, per come è costruito il movimento, ma espresso in radianti
|
|
|
|
// Punti di tagenza piano cono
|
|
Point3d ptPrs = ptI - vtV1 * m_dTipHeight + dMinRad * ( dCos * vtV2 + sqrt( 1 - dCos * dCos) * vtV3) ;
|
|
Point3d ptPRs = ptI + dMaxRad * ( dCos * vtV2 + sqrt( 1 - dCos * dCos) * vtV3) ;
|
|
Point3d ptPrd = ptI - vtV1 * m_dTipHeight + dMinRad * ( dCos * vtV2 - sqrt( 1 - dCos * dCos) * vtV3) ;
|
|
Point3d ptPRd = ptI + dMaxRad * ( dCos * vtV2 - sqrt( 1 - dCos * dCos) * vtV3) ;
|
|
|
|
Point3d ptRInf = ( ptPRs.z < ptPRd.z ? ptPRs : ptPRd) ;
|
|
Point3d ptRSup = ( ptPRs.z < ptPRd.z ? ptPRd : ptPRs) ;
|
|
Point3d ptrInf = ( ptPrs.z < ptPrd.z ? ptPrs : ptPrd) ;
|
|
Point3d ptrSup = ( ptPrs.z < ptPrd.z ? ptPrd : ptPrs) ;
|
|
|
|
// Versori normali e prodotti scalari per per determinare i piani
|
|
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 ;
|
|
|
|
// Sistema di riferimento del movimento
|
|
Vector3d vtU3 = vtV1 ^ vtU2 ;
|
|
Frame3d MoveFrame ; MoveFrame.Set( ptI, vtV1, vtU2, vtU3) ;
|
|
|
|
ptRInf.LocToLoc( m_LocalFrame, MoveFrame) ; double dPRInf = ptRInf.y ;
|
|
ptRSup.LocToLoc( m_LocalFrame, MoveFrame) ; double dPRSup = ptRSup.y ;
|
|
ptrInf.LocToLoc( m_LocalFrame, MoveFrame) ; double dPrInf = ptrInf.y ;
|
|
ptrSup.LocToLoc( m_LocalFrame, MoveFrame) ; double dPrSup = ptrSup.y ;
|
|
|
|
// dMinX dMaxX dMinY dMaxY
|
|
double dMinX = min( min( ptI.x, ptF.x), min( ptI.x - vtV1.x * m_dTipHeight, ptF.x - vtV1.x * m_dTipHeight)) - dMaxRad;
|
|
double dMinY = min( min( ptI.y, ptF.y), min( ptI.y - vtV1.y * m_dTipHeight, ptF.y - vtV1.y * m_dTipHeight)) - dMaxRad;
|
|
double dMaxX = max( max( ptI.x, ptF.x), max( ptI.x - vtV1.x * m_dTipHeight, ptF.x - vtV1.x * m_dTipHeight)) + dMaxRad;
|
|
double dMaxY = max( max( ptI.y, ptF.y), max( ptI.y - vtV1.y * m_dTipHeight, ptF.y - vtV1.y * m_dTipHeight)) + dMaxRad;
|
|
|
|
// Verifica dell'interferenza dell'utensile con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
|
|
// Limiti su indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) {
|
|
|
|
for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
|
|
double dX, dY ; dX = ( i + 0.5) * m_dStep ; dY = ( j + 0.5) * m_dStep ;
|
|
|
|
Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ;
|
|
|
|
double dI1 = vtC * vtV1 ; double dI2 = vtC * vtU2 ;
|
|
|
|
|
|
if ( dRatio <= 1 / dTan) {
|
|
|
|
|
|
if ( vtMove * vtV1 > 0) {
|
|
|
|
|
|
double dLimInf = max( - dMaxRad - dI1 * ( dMaxRad - dMinRad) / m_dTipHeight, - dMaxRad + dI1 * ( dPLen2 / dPLen1)) ;
|
|
double dLimSup = min( dMinRad + ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1), dPLen2 + dMinRad + ( dI1 - dPLen1 + m_dTipHeight) * ( dMaxRad - dMinRad) / m_dTipHeight) ;
|
|
|
|
if ( dI1 > - m_dTipHeight && dI1 < dPLen1 && dI2 > dLimInf && dI2 < dLimSup) {
|
|
|
|
// Massimi
|
|
if ( dI1 > 0 && dI2 < dPRSup + dI1 * ( dPLen2 / dPLen1)) {
|
|
|
|
double dr = dI1 * ( dPLen2 / dPLen1) - dI2 ; // Non serve prenderne il valore assoluto poiché viene elevato a quadrato
|
|
double dl = dI1 * sqrt( 1 + (dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ;
|
|
double dH = ( dMaxRad * dMaxRad - dr * dr > 0 ? sqrt( dMaxRad * dMaxRad - dr * dr) : 0) ;
|
|
|
|
dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ;
|
|
}
|
|
else if ( dI1 < dPLen1 - m_dTipHeight && dI2 > dPrSup + ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) {
|
|
|
|
double dr = dI2 - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1) ; // Non serve prenderne il valore assoluto poiché viene elevato a quadrato
|
|
double dl = ( dI1 + m_dTipHeight) * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ;
|
|
double dH = ( dMinRad * dMinRad - dr * dr > 0 ? sqrt( dMinRad * dMinRad - dr * dr) : 0) ;
|
|
// Controllare da qui
|
|
dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ;
|
|
}
|
|
else if ( dI1 <= 0 && dI2 < dPRSup + dI1 * ( dPRSup - dPrSup) / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - dI2 * dI2) ;
|
|
|
|
dMax = dZI + dH ;
|
|
}
|
|
else if ( dI1 >= dPLen1 - m_dTipHeight && dI2 > dPLen2 + dPRSup + ( dI1 - dPLen1) * ( dPRSup - dPrSup) / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad + ( dI1 - dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2)) ;
|
|
|
|
dMax = dZI + dDeltaZ + dH ;
|
|
}
|
|
else
|
|
|
|
dMax = max( ( dDotd - vtNd.x * dX - vtNd.y * dY) / vtNd.z, ( dDots - vtNs.x * dX - vtNs.y * dY) / vtNs.z) ;
|
|
|
|
|
|
|
|
// Minimi
|
|
if ( dI1 > 0 && dI2 < dPRInf + dI1 * ( dPLen2 / dPLen1)) {
|
|
|
|
double dr = dI1 * ( dPLen2 / dPLen1) - dI2 ; // Non serve prenderne il valore assoluto poiché viene elevato a quadrato
|
|
double dl = dI1 * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ;
|
|
double dH = ( dMaxRad * dMaxRad - dr * dr > 0 ? sqrt( dMaxRad * dMaxRad - dr * dr) : 0) ;
|
|
|
|
dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ;
|
|
}
|
|
else if ( dI1 < dPLen1 - m_dTipHeight && dI2 > dPrInf + ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) {
|
|
|
|
double dr = dI2 - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1) ; // Non serve prenderne il valore assoluto poiché viene elevato a quadrato
|
|
double dl = ( dI1 + m_dTipHeight) * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ;
|
|
double dH = ( dMinRad * dMinRad - dr * dr > 0 ? sqrt( dMinRad * dMinRad - dr * dr) : 0) ;
|
|
|
|
dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ;
|
|
}
|
|
else if ( dI1 <= 0 && dI2 < dPRInf + dI1 * ( dPRInf - dPrInf) / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - dI2 * dI2) ;
|
|
|
|
dMin = dZI - dH ;
|
|
}
|
|
else if ( dI1 >= dPLen1 - m_dTipHeight && dI2 > dPLen2 + dPRInf + ( dI1 - dPLen1) * ( dPRInf - dPrInf) / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad + ( dI1 - dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2)) ;
|
|
|
|
dMin = dZI + dDeltaZ - dH ;
|
|
}
|
|
else
|
|
|
|
dMin = min( ( dDotd - vtNd.x * dX - vtNd.y * dY) / vtNd.z, ( dDots - vtNs.x * dX - vtNs.y * dY) / vtNs.z) ;
|
|
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
// vtMove * vtV1 < 0
|
|
else {
|
|
|
|
double dLimInf = max( - dMaxRad - dI1 * ( dMaxRad - dMinRad) / m_dTipHeight, - dMinRad - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) ;
|
|
double dLimSup = min( dMaxRad - dI1 * ( dPLen2 / dPLen1), dPLen2 + dMaxRad + ( dI1 + dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight) ;
|
|
|
|
if ( dI1 > - dPLen1 - m_dTipHeight && dI1 < 0 && dI2 > dLimInf && dI2 < dLimSup) {
|
|
|
|
// Massimi
|
|
if ( dI1 > - m_dTipHeight && dI2 < dPRSup + dI1 * ( dPRSup - dPrSup) / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
double dH = ( dr * dr - dI2 * dI2 > 0 ? sqrt( dr * dr - dI2 * dI2) : 0) ;
|
|
|
|
dMax = dZI + dH ;
|
|
}
|
|
else if ( dI1 < - dPLen1 && dI2 > dPLen2 + dPRSup + (dI1 + dPLen1) * ( dPRSup - dPrSup) / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad + ( dI1 + dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
double dH = ( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2) > 0 ? sqrt( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2)) : 0) ;
|
|
|
|
dMax = dZI + dDeltaZ + dH ;
|
|
}
|
|
else if ( dI1 < - m_dTipHeight && dI2 < dPrSup - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) {
|
|
|
|
double dr = - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1) - dI2 ;
|
|
double dH = ( dMinRad * dMinRad - dr * dr > 0 ? sqrt( dMinRad * dMinRad - dr * dr) : 0) ;
|
|
double dl = - ( dI1 + m_dTipHeight) * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ;
|
|
|
|
dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ;
|
|
}
|
|
else if ( dI1 > - dPLen1 && dI2 > dPRSup - dI1 * ( dPLen2 / dPLen1)) {
|
|
|
|
double dr = dI2 + dI1 * ( dPLen2 / dPLen1) ;
|
|
double dH = ( dMaxRad * dMaxRad - dr * dr > 0 ? sqrt( dMaxRad * dMaxRad - dr * dr) : 0) ;
|
|
double dl = - dI1 * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ;
|
|
|
|
dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ;
|
|
}
|
|
else
|
|
|
|
dMax = max( ( dDots - vtNs.x * dX - vtNs.y * dY) / vtNs.z, ( dDotd - vtNd.x * dX - vtNd.y * dY) / vtNd.z ) ;
|
|
|
|
|
|
// Minimi
|
|
if ( dI1 > - m_dTipHeight && dI2 < dPRInf + dI1 * ( dPRInf - dPrInf) / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
double dH = ( dr * dr - dI2 * dI2 > 0 ? sqrt( dr * dr - dI2 * dI2) : 0) ;
|
|
|
|
dMin =dZI - dH ;
|
|
}
|
|
else if ( dI1 < - dPLen1 && dI2 > dPLen2 + dPRInf + ( dI1 + dPLen1) * ( dPRInf - dPrInf) / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad + ( dI1 + dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
double dH = ( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2) > 0 ? sqrt( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2)) : 0) ;
|
|
|
|
dMin = dZI + dDeltaZ - dH ;
|
|
|
|
}
|
|
else if ( dI1 < - m_dTipHeight && dI2 < dPrInf - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) {
|
|
|
|
double dr = - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1) - dI2 ;
|
|
double dH = ( dMinRad * dMinRad - dr * dr > 0 ? sqrt( dMinRad * dMinRad - dr * dr) : 0) ;
|
|
double dl = - ( dI1 + m_dTipHeight) * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ;
|
|
|
|
dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ;
|
|
}
|
|
else if ( dI1 > - dPLen1 && dI2 > dPRInf - dI1 * ( dPLen2 / dPLen1)) {
|
|
|
|
double dr = dI2 + dI1 * ( dPLen2 / dPLen1) ;
|
|
double dH = ( dMaxRad * dMaxRad - dr * dr > 0 ? sqrt( dMaxRad * dMaxRad - dr * dr) : 0) ;
|
|
double dl = - dI1 * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ;
|
|
|
|
dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ;
|
|
}
|
|
else
|
|
|
|
dMin = min( ( dDotd - vtNd.x * dX - vtNd.y * dY) / vtNd.z, ( dDots - vtNs.x * dX - vtNs.y * dY) / vtNs.z) ;
|
|
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
// dRatio <= 1 / dTan
|
|
else {
|
|
|
|
if ( dI1 > - m_dTipHeight && dI1 < 0 &&
|
|
dI2 > - dMaxRad - dI1 * ( dMaxRad - dMinRad) / m_dTipHeight &&
|
|
dI2 < dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight) {
|
|
|
|
double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ;
|
|
double dH = sqrt( dr * dr - dI2 * dI2) ;
|
|
|
|
dMin = dZI - dH ;
|
|
dMax = dZI + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( dI1 >= 0 && dI1 < dPLen1 &&
|
|
dI2 > - dMaxRad + dI1 * ( dPLen2 / dPLen1) &&
|
|
dI2 < dMaxRad + dI1 * ( dPLen2 / dPLen1)) {
|
|
|
|
double dl = dI1 * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ;
|
|
double dr = dI2 - dI1 * dPLen2 / dPLen1 ;
|
|
double dH = sqrt( dMaxRad * dMaxRad - dr * dr) ;
|
|
|
|
dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ;
|
|
dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
// Virtual milling per componenti
|
|
|
|
// Versore utensile nella direzione dell'asse Z
|
|
|
|
// Foratura
|
|
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::DrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
// Posizioni iniziale e finale dell'utensile
|
|
Point3d ptI = ptLs ;
|
|
Point3d ptF = ptLe ;
|
|
|
|
// vettore movimento
|
|
Vector3d vtMove = ptLe - ptLs ;
|
|
|
|
CurveComposite ToolProfile ;
|
|
|
|
// Settaggio profilo
|
|
if ( m_ToolArcLineApprox.GetCurveCount() == 0)
|
|
// Se l'utensile non è stato approssimato uso l'originale
|
|
ToolProfile.CopyFrom( & m_ToolOutline) ;
|
|
else
|
|
// altrimenti usi l'approssimazione
|
|
ToolProfile.CopyFrom( & m_ToolArcLineApprox) ;
|
|
|
|
// Dichiaro un puntatore a curva da usare nel ciclo
|
|
const ICurve* pCurve ;
|
|
|
|
pCurve = ToolProfile.GetFirstCurve() ;
|
|
|
|
// Ciclo sulle curve
|
|
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 ;
|
|
|
|
LongCylV( 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 ;
|
|
|
|
LongConusV( ptI, ptF, 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 ;
|
|
|
|
LongConusV( 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
|
|
Ball( 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 = ToolProfile.GetNextCurve() ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::LongCylV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) {
|
|
|
|
unsigned int nStartI, nStartJ, nEndI, nEndJ ;
|
|
|
|
bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ;
|
|
|
|
if ( Control == false)
|
|
|
|
return true ;
|
|
|
|
Point3d ptI = ( ( ptLe - ptLs) * vtToolDir > 0 ? ptLe : ptLs) ;
|
|
Point3d ptF = ( ( ptLe - ptLs) * vtToolDir > 0 ? ptLs - dHei * vtToolDir : ptLe - dHei * vtToolDir) ;
|
|
|
|
if ( ptI.z > ptF.z) {
|
|
|
|
Point3d ptTemp = ptI ;
|
|
ptI = ptF ;
|
|
ptF = ptTemp ;
|
|
}
|
|
|
|
Point3d ptO( ptI.x, ptI.y, 0) ;
|
|
|
|
double dZI = ptI.z ;
|
|
double dZF = ptF.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 - ptO ;
|
|
|
|
double dSqDist = vtC * vtC ;
|
|
|
|
if ( dSqDist < dRad * dRad)
|
|
|
|
SubtractIntervals( i, j, dZI, dZF) ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::LongConusV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) {
|
|
|
|
unsigned int nStartI, nStartJ, nEndI, nEndJ ;
|
|
|
|
bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ;
|
|
|
|
if ( Control == false)
|
|
|
|
return true ;
|
|
|
|
Point3d ptO( ptLs.x, ptLs.y, 0) ;
|
|
|
|
double dZMin, dZMax ;
|
|
|
|
double dAngC = dHei / ( dMaxRad - dMinRad) ;
|
|
|
|
if ( vtToolDir.z > 0) {
|
|
|
|
dZMin = ( ptLs.z < ptLe.z ? ptLs.z - dHei : ptLe.z - dHei) ;
|
|
dZMax = ( ptLs.z < ptLe.z ? ptLe.z : ptLs.z) ;
|
|
}
|
|
else {
|
|
|
|
dZMin = ( ptLs.z < ptLe.z ? ptLs.z : ptLe.z) ;
|
|
dZMax = ( ptLs.z < ptLe.z ? ptLe.z + dHei : ptLs.z + dHei) ;
|
|
}
|
|
|
|
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 < dMinRad * dMinRad)
|
|
|
|
SubtractIntervals( i, j, dZMin, dZMax) ;
|
|
|
|
else if ( dSqDist < dMaxRad * dMaxRad) {
|
|
|
|
double dr = sqrt( dSqDist) ;
|
|
|
|
if ( vtToolDir.z > 0)
|
|
|
|
SubtractIntervals( i, j, dZMin + dAngC * ( dr - dMinRad), dZMax) ;
|
|
else
|
|
SubtractIntervals( i, j, dZMin, dZMax - dAngC * ( dr - dMinRad)) ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
// Fresatura
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
// Posizioni iniziale e finale dell'utensile
|
|
Point3d ptI = ptLs ;
|
|
Point3d ptF = ptLe ;
|
|
|
|
// vettore movimento
|
|
Vector3d vtMove = ptLe - ptLs ;
|
|
|
|
CurveComposite ToolProfile ;
|
|
|
|
// Settaggio profilo
|
|
if ( m_ToolArcLineApprox.GetCurveCount() == 0)
|
|
// Se l'utensile non è stato approssimato uso l'originale
|
|
ToolProfile.CopyFrom( & m_ToolOutline) ;
|
|
else
|
|
// altrimenti usi l'approssimazione
|
|
ToolProfile.CopyFrom( & m_ToolArcLineApprox) ;
|
|
|
|
// Dichiaro un puntatore a curva da usare nel ciclo
|
|
const ICurve* pCurve ;
|
|
|
|
pCurve = ToolProfile.GetFirstCurve() ;
|
|
|
|
// Ciclo sulle curve
|
|
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 ;
|
|
|
|
MillCylV( 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 ;
|
|
|
|
MillConusV( 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 ;
|
|
|
|
MillConusV( 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
|
|
Ball( 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 = ToolProfile.GetNextCurve() ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillCylV( 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 ;
|
|
|
|
Point3d ptI, ptF ;
|
|
|
|
if ( ( ptLe - ptLs) * vtToolDir < 0 && vtToolDir.z > 0) {
|
|
|
|
ptI = ptLe ;
|
|
ptF = ptLs ;
|
|
}
|
|
else if ( ( ptLe - ptLs) * vtToolDir < 0 && vtToolDir.z < 0) {
|
|
|
|
ptI = ptLs - dHei * vtToolDir ;
|
|
ptF = ptLe - dHei * vtToolDir ;
|
|
}
|
|
else if ( ( ptLe - ptLs) * vtToolDir > 0 && vtToolDir.z < 0) {
|
|
|
|
ptI = ptLe - dHei * vtToolDir ;
|
|
ptF = ptLs - dHei * vtToolDir ;
|
|
}
|
|
else {
|
|
|
|
ptI = ( vtToolDir.z > 0 ? ptLs : ptLs - vtToolDir * dHei) ;
|
|
ptF = ( vtToolDir.z > 0 ? ptLe : ptLe - vtToolDir * dHei) ;
|
|
}
|
|
|
|
Point3d ptIxy( ptI.x, ptI.y, 0) ;
|
|
Point3d ptFxy( ptF.x, ptF.y, 0) ;
|
|
|
|
Vector3d vtV1 = ptFxy - ptIxy ; double dPLen = vtV1.LenXY() ; vtV1.Normalize() ;
|
|
Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ;
|
|
|
|
double dZI = ptI.z ;
|
|
double dDeltaZ = ptF.z - ptI.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 - ptIxy ; //Vector3d vtCF = ptC - ptFxy ;
|
|
|
|
double dX1 = vtC * vtV1 ; double dX2 = vtC * vtV2 ;
|
|
|
|
double dLimX1 = sqrt( dRad * dRad - dX2 * dX2) ;
|
|
|
|
if ( dX2 > - dRad && dX2 < dRad &&
|
|
dX1 > - dLimX1 &&
|
|
dX1 < dPLen + dLimX1) {
|
|
|
|
// Massimi
|
|
if( dX1 > - dLimX1 && dX1 < dPLen - dLimX1)
|
|
|
|
dMax = dZI + ( dX1 + dLimX1) * dDeltaZ / dPLen ;
|
|
|
|
else if ( dX1 >= dPLen - dLimX1 &&
|
|
dX1 < dPLen + dLimX1)
|
|
|
|
dMax = dZI + dDeltaZ ;
|
|
|
|
// Minimi
|
|
if ( dX1 > - dLimX1 && dX1 < dLimX1)
|
|
|
|
dMin = dZI - dHei ;
|
|
|
|
else if ( dX1 >= dLimX1 &&
|
|
dX1 < dPLen + dLimX1)
|
|
|
|
dMin = dZI - dHei + ( dX1 - dLimX1) * dDeltaZ / dPLen ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillConusV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir,
|
|
double dHei, double dMaxRad, double dMinRad)
|
|
{
|
|
double dMin, dMax, dPLim, dMLim ;
|
|
unsigned int nStartI, nStartJ, nEndI, nEndJ ;
|
|
|
|
bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ;
|
|
|
|
if ( ! Control)
|
|
return true ;
|
|
|
|
Point3d ptI = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLs : ptLe) ;
|
|
Point3d ptF = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLe : ptLs) ;
|
|
|
|
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( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
// Direzione generica del versore utensile
|
|
// Foratura
|
|
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Drilling( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
if ( m_nToolType == CylindricalMill)
|
|
|
|
LongCyl( ptLs, ptLe, vtToolDir, m_dHeight, m_dRadius) ;
|
|
|
|
else if ( m_nToolType == BallEndMill) {
|
|
|
|
double dCylH = m_dHeight - m_dTipHeight ;
|
|
|
|
LongCyl( ptLs, ptLe, vtToolDir, dCylH, m_dRadius) ;
|
|
|
|
Point3d ptBs = ptLs - vtToolDir * ( m_dHeight - m_dTipHeight) ;
|
|
Point3d ptBe = ptLe - vtToolDir * ( m_dHeight - m_dTipHeight) ;
|
|
|
|
Ball( ptBs, ptBe, m_dRadius) ;
|
|
}
|
|
|
|
else if ( m_nToolType == BullNoseMill)
|
|
// Caso al momento non gestito
|
|
return false ;
|
|
|
|
else if ( m_nToolType == ConusMill) {
|
|
|
|
double dCylH = m_dHeight - m_dTipHeight ;
|
|
|
|
LongCyl( ptLs, ptLe, vtToolDir, dCylH, m_dRadius) ;
|
|
|
|
double dMinRad = ( m_dRadius > m_dTipRadius ? m_dTipRadius : m_dRadius) ;
|
|
double dMaxRad = ( m_dRadius > m_dTipRadius ? m_dRadius : m_dTipRadius) ;
|
|
|
|
Point3d ptCs = ( m_dRadius > m_dTipRadius ? ptLs - dCylH * vtToolDir : ptLs - m_dHeight * vtToolDir) ;
|
|
Point3d ptCe = ( m_dRadius > m_dTipRadius ? ptLe - dCylH * vtToolDir : ptLe - m_dHeight * vtToolDir) ;
|
|
Vector3d vtDir = ( m_dRadius > m_dTipRadius ? vtToolDir : - vtToolDir) ;
|
|
|
|
LongConus( ptCs, ptCe, vtDir, m_dTipHeight, dMaxRad, dMinRad) ;
|
|
}
|
|
|
|
else if ( m_nToolType == GenericTool)
|
|
// Caso al momento non gestito
|
|
return false ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::DrillingGT( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
// Posizioni iniziale e finale dell'utensile
|
|
Point3d ptI = ptLs ;
|
|
Point3d ptF = ptLe ;
|
|
|
|
// vettore movimento
|
|
Vector3d vtMove = ptLe - ptLs ;
|
|
|
|
CurveComposite ToolProfile ;
|
|
|
|
// Settaggio profilo
|
|
if ( m_ToolArcLineApprox.GetCurveCount() == 0)
|
|
// Se l'utensile non è stato approssimato uso l'originale
|
|
ToolProfile.CopyFrom( & m_ToolOutline) ;
|
|
else
|
|
// altrimenti usi l'approssimazione
|
|
ToolProfile.CopyFrom( & m_ToolArcLineApprox) ;
|
|
|
|
// Dichiaro un puntatore a curva da usare nel ciclo
|
|
const ICurve* pCurve ;
|
|
|
|
pCurve = ToolProfile.GetFirstCurve() ;
|
|
|
|
// Ciclo sulle curve
|
|
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 ;
|
|
|
|
LongCyl( 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 ;
|
|
|
|
LongConus( 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 ;
|
|
|
|
LongConus( 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
|
|
Ball( 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 = ToolProfile.GetNextCurve() ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
// Componenti elementari degli utensili
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::LongCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad)
|
|
{
|
|
double dMin, dMax;
|
|
unsigned int nStartI, nEndI, nStartJ, nEndJ ;
|
|
|
|
bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ;
|
|
|
|
if ( ! Control)
|
|
return true ;
|
|
|
|
// Studio delle simmetrie
|
|
Vector3d vtMove = ptLe - ptLs ;
|
|
|
|
Point3d ptI = ( vtMove * vtToolDir > 0 ? ptLe : ptLs) ;
|
|
Point3d ptF = ( vtMove * vtToolDir > 0 ? ptLs - dHei * vtToolDir : ptLe - 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 ;
|
|
|
|
// 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( dRad * dRad - dProjI2 * dProjI2) &&
|
|
dProjI1 < dLOri + dCos * sqrt( dRad * dRad - dProjI2 * dProjI2) &&
|
|
dProjI2 * dProjI2 < dRad * dRad) {
|
|
|
|
// Massimi
|
|
if ( dProjI1 < dLOri - dCos * sqrt( dRad * dRad - dProjI2 * dProjI2)) {
|
|
|
|
double dZ0 = dSin * sqrt( dRad * dRad - dProjI2 * dProjI2) ;
|
|
double dI10 = - dCos * sqrt( dRad * dRad - 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( dRad * dRad - dProjI2 * dProjI2))
|
|
|
|
dMin = ( dDotI - vtV.x * dX - vtV.y *dY) / vtV.z ;
|
|
|
|
else {
|
|
|
|
double dZ0 = - dSin * sqrt( dRad * dRad - dProjI2 * dProjI2) ;
|
|
double dI10 = dCos * sqrt( dRad * dRad - dProjI2 * dProjI2) ;
|
|
|
|
dMin = dZI + dZ0 + ( dProjI1 - dI10) * dDeltaZ / dLOri ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::LongBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dRad)
|
|
{
|
|
double dMin, dMax ;
|
|
unsigned int nStartI, nStartJ, nEndI, nEndJ ;
|
|
|
|
bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, 0) ;
|
|
|
|
if ( ! Control)
|
|
return true ;
|
|
|
|
Point3d ptI = ( ( ptLe - ptLs) * vtToolDir < 0 ? ptLs : ptLe) ;
|
|
Point3d ptF = ( ( ptLe - ptLs) * vtToolDir < 0 ? ptLe : ptLs) ;
|
|
|
|
Point3d ptIxy( ptI.x, ptI.y, 0) ;
|
|
Point3d ptFxy( ptF.x, ptF.y, 0) ;
|
|
|
|
double dDeltaZ = ptF.z - ptI.z ;
|
|
double dZI = ptI.z ;
|
|
|
|
Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ;
|
|
Vector3d vtMoveVer( 0, 0, vtMove.z) ; double dLVer = abs( vtMove.z) ;
|
|
Vector3d vtMoveOri( vtMove.x, vtMove.y, 0) ; double dLOri = vtMoveOri.LenXY() ;
|
|
|
|
// Definizione del sistema di riferimento nel piano
|
|
Vector3d vtU1 = vtMoveOri ;
|
|
|
|
if ( vtU1.LenXY() < EPS_SMALL) {
|
|
|
|
double dLenVector = sqrt(vtMove.x * vtMove.x + vtMove.y * vtMove.y) ;
|
|
|
|
vtU1 = ( 1 + dLenVector) / dLenVector * vtU1 ;
|
|
}
|
|
|
|
|
|
vtU1.Normalize() ;
|
|
|
|
Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ;
|
|
|
|
double dCos = dLVer / dLen ; // Sempre positivo
|
|
double dSin = dLOri / dLen ; // Sempre positivo
|
|
|
|
double dSemiMin = dRad * abs( dCos) ;
|
|
|
|
Vector3d vtV = vtMove ; vtV.Normalize() ;
|
|
|
|
Vector3d vtRI = ptI - ORIG ; double dDotI = vtRI * 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 dPI1 = vtCI * vtU1 ; double dPI2 = vtCI * vtU2 ;
|
|
double dPF1 = vtCF * vtU1 ; double dPF2 = vtCF * vtU2 ;
|
|
|
|
double dLimP1 = sqrt( dRad * dRad - dPI2 * dPI2) ;
|
|
|
|
// Dexel nella regione interessata dalla lavorazione
|
|
if ( ( dPI1 > - dCos * dLimP1 &&
|
|
dPI1 < dLOri && dPI2 * dPI2 < dRad * dRad) ||
|
|
( dPF1 * dPF1 + dPF2 * dPF2 < dRad * dRad)) {
|
|
|
|
if ( dDeltaZ > 0) {
|
|
|
|
// Massimi
|
|
if ( dPI1 < dLOri - dCos * dLimP1) {
|
|
|
|
double dPI0 = - dCos * dLimP1 ;
|
|
double dZ0 = dSin * dLimP1 ;
|
|
|
|
dMax = dZI + dZ0 + ( dPI1 - dPI0) * dDeltaZ / dLOri ;
|
|
}
|
|
else {
|
|
|
|
double dSqD = dPF1 * dPF1 + dPF2 * dPF2 ;
|
|
double dH = sqrt( dRad * dRad - dSqD) ;
|
|
|
|
dMax = dZI + dDeltaZ + dH ;
|
|
}
|
|
|
|
// Minimi
|
|
if ( dPI1 < dCos * dLimP1)
|
|
|
|
dMin = ( dDotI - dX * vtV.x - dY * vtV.y) / vtV.z ;
|
|
|
|
else if ( dPI1 < dLOri + dCos * dLimP1) {
|
|
|
|
double dPI0 = dCos * dLimP1 ;
|
|
double dZ0 = - dSin * dLimP1 ;
|
|
|
|
dMin = dZI + dZ0 + ( dPI1 - dPI0) * dDeltaZ / dLOri ;
|
|
}
|
|
else {
|
|
|
|
double dSqD = dPF1 * dPF1 + dPF2 * dPF2 ;
|
|
double dH = sqrt( dRad * dRad - dSqD) ;
|
|
|
|
dMin = dZI + dDeltaZ - dH ;
|
|
}
|
|
}
|
|
else {
|
|
|
|
// Massimi
|
|
if ( dPI1 < dCos * dLimP1)
|
|
|
|
dMax = ( dDotI - dX * vtV.x - dY * vtV.y) / vtV.z ;
|
|
|
|
else if ( dPI1 < dLOri + dCos * dLimP1) {
|
|
|
|
double dPI0 = dCos * dLimP1 ;
|
|
double dZ0 = + dSin * dLimP1 ;
|
|
|
|
dMax = dZI + dZ0 + ( dPI1 - dPI0) * dDeltaZ / dLOri ;
|
|
}
|
|
else {
|
|
|
|
double dSqD = dPF1 * dPF1 + dPF2 * dPF2 ;
|
|
double dH = sqrt( dRad * dRad - dSqD) ;
|
|
|
|
dMax = dZI + dDeltaZ + dH ;
|
|
}
|
|
|
|
// Minimi
|
|
if ( dPI1 < dLOri - dCos * dLimP1) {
|
|
|
|
double dPI0 = - dCos * dLimP1 ;
|
|
double dZ0 = - dSin * dLimP1 ;
|
|
|
|
dMin = dZI + dZ0 + ( dPI1 - dPI0) * dDeltaZ / dLOri ;
|
|
}
|
|
else {
|
|
|
|
double dSqD = dPF1 * dPF1 + dPF2 * dPF2 ;
|
|
double dH = sqrt( dRad * dRad - dSqD) ;
|
|
|
|
dMin = dZI + dDeltaZ - dH ;
|
|
}
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::LongConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir,
|
|
double dHei, double dMaxRad, double dMinRad)
|
|
{
|
|
double dMin, dMax ;
|
|
unsigned int nStartI, nStartJ, nEndI, nEndJ ;
|
|
|
|
bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ;
|
|
|
|
if ( ! Control)
|
|
return true ;
|
|
|
|
Vector3d vtMove = ptLe - ptLs ; 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 ;
|
|
|
|
// 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 ? ptLs : ptLe) ;
|
|
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 = ( ptLs.z < ptLe.z ? ptLs : ptLe) ;
|
|
Point3d ptCylF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ;
|
|
|
|
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) ;
|
|
|
|
|
|
// 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 < dMaxRad * dMaxRad &&
|
|
dPCyl1 > - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad)) &&
|
|
dPCyl1 < dLOri + dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad))) {
|
|
|
|
// Massimi
|
|
if ( dPCyl1 < dLOri - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad))) {
|
|
|
|
double dZ0 = dSin * sqrt( dMaxRad * dMaxRad - dPCyl2 * dPCyl2) ;
|
|
double dP0 = - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad)) ;
|
|
|
|
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) / ( dMaxRad * dMaxRad)))
|
|
|
|
dMin = ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z ;
|
|
|
|
else {
|
|
|
|
double dZ0 = - dSin * sqrt( dMaxRad * dMaxRad - dPCyl2 * dPCyl2) ;
|
|
double dP0 = dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad)) ;
|
|
|
|
dMin = dZCylI + dZ0 + ( dPCyl1 - dP0) * dDeltaZ / ( dLOri) ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
|
|
// Parte conica
|
|
Vector3d vtD = Z_AX ;
|
|
|
|
ptC.LocToLoc( m_LocalFrame, ConusFrame) ;
|
|
|
|
vtD.LocToLoc( m_LocalFrame, ConusFrame) ;
|
|
|
|
std::vector <double> vdCoef(3);
|
|
std::vector <double> 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, m_LocalFrame) ;
|
|
|
|
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( 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( 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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) {
|
|
|
|
ptR2.LocToLoc( ConusFrame, m_LocalFrame) ;
|
|
|
|
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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) {
|
|
|
|
ptR2.LocToLoc( ConusFrame, m_LocalFrame) ;
|
|
|
|
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( 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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) {
|
|
|
|
ptR1.LocToLoc( ConusFrame, m_LocalFrame) ;
|
|
ptR2.LocToLoc( ConusFrame, m_LocalFrame) ;
|
|
|
|
dMin = min( ptR1.z, ptR2.z) ;
|
|
dMax = max( ptR1.z, ptR2.z) ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) {
|
|
|
|
ptR1.LocToLoc( ConusFrame, m_LocalFrame) ;
|
|
|
|
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( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
// Fresatura
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Milling( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
|
|
if ( m_nToolType == CylindricalMill)
|
|
|
|
return MillCyl( ptLs, ptLe, vtToolDir, m_dHeight, m_dRadius) ;
|
|
|
|
else if ( m_nToolType == BallEndMill) {
|
|
|
|
double dCylH = m_dHeight - m_dTipHeight ;
|
|
|
|
MillCyl( ptLs, ptLe, vtToolDir, dCylH, m_dRadius) ;
|
|
|
|
Point3d ptBs = ptLs - vtToolDir * ( m_dHeight - m_dTipHeight) ;
|
|
Point3d ptBe = ptLe - vtToolDir * ( m_dHeight - m_dTipHeight) ;
|
|
|
|
Ball( ptBs, ptBe, m_dRadius) ;
|
|
return true ;
|
|
}
|
|
|
|
else if ( m_nToolType == BullNoseMill)
|
|
// Caso al momento non gestito
|
|
return false ;
|
|
|
|
else if ( m_nToolType == ConusMill) {
|
|
|
|
double dCylH = m_dHeight - m_dTipHeight ;
|
|
|
|
MillCyl( ptLs, ptLe, vtToolDir, dCylH, m_dRadius) ;
|
|
|
|
double dMinRad = ( m_dRadius > m_dTipRadius ? m_dTipRadius : m_dRadius) ;
|
|
double dMaxRad = ( m_dRadius > m_dTipRadius ? m_dRadius : m_dTipRadius) ;
|
|
|
|
Point3d ptCs = ( m_dRadius > m_dTipRadius ? ptLs - dCylH * vtToolDir : ptLs - m_dHeight * vtToolDir) ;
|
|
Point3d ptCe = ( m_dRadius > m_dTipRadius ? ptLe - dCylH * vtToolDir : ptLe - m_dHeight * vtToolDir) ;
|
|
Vector3d vtDir = ( m_dRadius > m_dTipRadius ? vtToolDir : - vtToolDir) ;
|
|
|
|
MillConus( ptCs, ptCe, vtDir, m_dTipHeight, dMaxRad, dMinRad) ;
|
|
return true ;
|
|
}
|
|
|
|
else if ( m_nToolType == GenericTool)
|
|
// Caso al momento non gestito
|
|
return false ;
|
|
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingGT( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir)
|
|
{
|
|
// Posizioni iniziale e finale dell'utensile
|
|
Point3d ptI = ptLs ;
|
|
Point3d ptF = ptLe ;
|
|
|
|
// vettore movimento
|
|
Vector3d vtMove = ptLe - ptLs ;
|
|
|
|
CurveComposite ToolProfile ;
|
|
int i = m_ToolArcLineApprox.GetCurveCount() ;
|
|
|
|
// Settaggio profilo
|
|
if ( m_ToolArcLineApprox.GetCurveCount() == 0)
|
|
// Se l'utensile non è stato approssimato uso l'originale
|
|
ToolProfile.CopyFrom( & m_ToolOutline) ;
|
|
else
|
|
// altrimenti usi l'approssimazione
|
|
ToolProfile.CopyFrom( & m_ToolArcLineApprox) ;
|
|
|
|
// Dichiaro un puntatore a curva da usare nel ciclo
|
|
const ICurve* pCurve = ToolProfile.GetFirstCurve() ;
|
|
|
|
// Ciclo sulle curve
|
|
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 ;
|
|
|
|
MillCyl( 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 ;
|
|
|
|
MillConus( 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 ;
|
|
|
|
MillConus( 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
|
|
Ball( 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 = ToolProfile.GetNextCurve() ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
// Componenti elementari degli utensili
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillCyl( 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 ;
|
|
|
|
Point3d ptI ;
|
|
Point3d ptF ;
|
|
Vector3d vtV1 ;
|
|
|
|
// Studio delle simmetrie
|
|
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() ;
|
|
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 dDeltaFz = ptFT.z - ptF.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
|
|
Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ;
|
|
Vector3d 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 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
|
|
if ( dPI1 > - dCos * sqrt( dRad * dRad - dPI2 * dPI2) &&
|
|
dPI1 < dL + dCos * sqrt( dRad * dRad - dPI2 * dPI2) &&
|
|
dPI2 * dPI2 < dRad * dRad) {
|
|
|
|
// Minimi
|
|
if ( dPI1 < dL - dCos * sqrt( dRad * dRad - dPI2 * dPI2)) {
|
|
|
|
double dZ0 = - dSin * sqrt( dRad * dRad - dPI2 * dPI2) ;
|
|
double dI10 = - dCos * sqrt( dRad * dRad - dPI2 * dPI2) ;
|
|
|
|
dMin = dZI + dZ0 + ( dPI1 - dI10) * dDeltaZ / dL ;
|
|
}
|
|
else
|
|
|
|
dMin = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ;
|
|
|
|
// Massimi
|
|
if ( dPI1 < dCos * sqrt( dRad * dRad - dPI2 * dPI2))
|
|
|
|
dMax = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ;
|
|
|
|
else {
|
|
|
|
double dZ0 = dSin * sqrt( dRad * dRad - dPI2 * dPI2) ;
|
|
double dI10 = dCos * sqrt( dRad * dRad - dPI2 * dPI2) ;
|
|
|
|
dMax = dZI + dZ0 + ( dPI1 - dI10) * dDeltaZ / dL ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
|
|
// Parte cilindrica F
|
|
if ( dPF1 > - dCos * sqrt( dRad * dRad - dPF2 * dPF2) &&
|
|
dPF1 < dL + dCos * sqrt( dRad * dRad - dPF2 * dPF2) &&
|
|
dPF2 * dPF2 < dRad * dRad) {
|
|
|
|
// Minimi
|
|
if ( dPF1 < dL - dCos * sqrt( dRad * dRad - dPF2 * dPF2)) {
|
|
|
|
double dZ0 = - dSin * sqrt( dRad * dRad - dPF2 * dPF2) ;
|
|
double dI10 = - dCos * sqrt( dRad * dRad - dPF2 * dPF2) ;
|
|
|
|
dMin = dZF + dZ0 + ( dPF1 - dI10) * dDeltaZ / dL ;
|
|
}
|
|
else
|
|
|
|
dMin = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ;
|
|
|
|
// Massimi
|
|
if ( dPF1 < dCos * sqrt( dRad * dRad - dPF2 * dPF2))
|
|
|
|
dMax = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ;
|
|
|
|
else {
|
|
|
|
double dZ0 = dSin * sqrt( dRad * dRad - dPF2 * dPF2) ;
|
|
double dI10 = dCos * sqrt( dRad * dRad - dPF2 * dPF2) ;
|
|
|
|
dMax = dZF + dZ0 + ( dPF1 - dI10) * dDeltaZ / dL ;
|
|
}
|
|
|
|
SubtractIntervals( 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( m_LocalFrame, CylFrame) ;
|
|
ptInt2.LocToLoc( m_LocalFrame, CylFrame) ;
|
|
ptInt3.LocToLoc( m_LocalFrame, CylFrame) ;
|
|
ptInt4.LocToLoc( m_LocalFrame, RotFrame) ;
|
|
ptInt5.LocToLoc( m_LocalFrame, CylFrame) ;
|
|
ptInt6.LocToLoc( m_LocalFrame, 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, m_LocalFrame) ;
|
|
|
|
|
|
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, 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( CylFrame, 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( RotFrame, m_LocalFrame) ;
|
|
|
|
if ( bFlag == false) {
|
|
|
|
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, m_LocalFrame) ;
|
|
|
|
if ( bFlag == false) {
|
|
|
|
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, 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) ;
|
|
}
|
|
|
|
// Traslazione dell'ellisse
|
|
|
|
Vector3d vtK = Z_AX ;
|
|
|
|
vtK.LocToLoc( m_LocalFrame, CylFrame) ;
|
|
ptC.LocToLoc( m_LocalFrame, CylFrame) ;
|
|
|
|
std::vector <double> vdCoef(3);
|
|
std::vector <double> vdRoots;
|
|
|
|
vdCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dRad * dRad ;
|
|
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( 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( 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, 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( 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( 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( 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( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
|
|
ptC.LocToLoc( CylFrame, TCylFrame) ;
|
|
vtK.LocToLoc( CylFrame, TCylFrame) ;
|
|
|
|
std::vector <double> vdTCoef(3);
|
|
std::vector <double> vdTRoots;
|
|
|
|
vdTCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dRad * dRad ;
|
|
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( 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( 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, 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( 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( 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( 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( 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 <double> vdICylCoef(3);
|
|
std::vector <double> 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 <double> vdFCylCoef(3);
|
|
std::vector <double> 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 <double> vdEllipseCoef(3);
|
|
std::vector <double> 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 <double> vdTEllipseCoef(3);
|
|
std::vector <double> 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::MillBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dRad)
|
|
{
|
|
unsigned int nStartI, nStartJ, nEndI, nEndJ ;
|
|
bool bControl = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, 0, 0) ;
|
|
if ( ! bControl)
|
|
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) ;
|
|
|
|
Vector3d vtMove = ptF - ptI ;
|
|
|
|
Vector3d vtV1( vtMove.x, vtMove.y, 0) ; vtV1.Normalize() ;
|
|
Vector3d vtV2( vtV1) ; vtV2.Rotate( Z_AX, 90) ;
|
|
|
|
double dZI = ptI.z ;
|
|
double dDeltaZ = ptF.z - ptI.z ;
|
|
double dPLen = vtMove.LenXY() ;
|
|
|
|
double dSin = dPLen / vtMove.Len() ;
|
|
double dCos = dDeltaZ / vtMove.Len() ;
|
|
|
|
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 dP1 = vtC * vtV1 ; double dP2 = vtC * vtV2 ;
|
|
|
|
if ( ( dP1 >= 0 && dP1 <= dPLen && abs( dP2) < dRad) ||
|
|
( dP1 * dP1 + dP2 * dP2 < dRad * dRad) ||
|
|
( ( dP1 - dPLen) * ( dP1 - dPLen) + dP2 * dP2 < dRad * dRad)) {
|
|
|
|
// Massimi
|
|
if ( dP1 < - dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad))) {
|
|
|
|
double dH = sqrt( dRad * dRad - dP1 * dP1 - dP2 * dP2) ;
|
|
dMax = dZI + dH ;
|
|
}
|
|
else if ( dP1 < dPLen - dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad))) {
|
|
|
|
double dP0 = - dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad)) ;
|
|
double dZ0 = dRad * dSin * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad)) ;
|
|
|
|
dMax = dZI + dZ0 + ( dP1 - dP0) * dDeltaZ / dPLen ;
|
|
}
|
|
else {
|
|
|
|
double dH = sqrt( dRad * dRad - ( dP1 - dPLen) * ( dP1 - dPLen) - dP2 * dP2) ;
|
|
dMax = dZI + dDeltaZ + dH ;
|
|
}
|
|
|
|
// Minimi
|
|
if ( dP1 < dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad))) {
|
|
|
|
double dH = sqrt( dRad * dRad - dP1 * dP1 - dP2 * dP2) ;
|
|
dMin = dZI - dH ;
|
|
}
|
|
else if ( dP1 < dPLen + dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad))) {
|
|
|
|
double dP0 = dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad)) ;
|
|
double dZ0 = - dRad * dSin * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad)) ;
|
|
|
|
dMin = dZI + dZ0 + ( dP1 - dP0) * dDeltaZ / dPLen ;
|
|
}
|
|
else {
|
|
|
|
double dH = sqrt( dRad * dRad - ( dP1 - dPLen) * ( dP1 - dPLen) - dP2 * dP2) ;
|
|
dMin = dZI + dDeltaZ - dH ;
|
|
}
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir,
|
|
double dHei, double dMaxRad, double dMinRad)
|
|
{
|
|
double dMin, dMax ;
|
|
unsigned int nStartI, nStartJ, nEndI, nEndJ ;
|
|
|
|
bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ;
|
|
|
|
if ( ! Control)
|
|
return true ;
|
|
|
|
double dDeltaR = dMaxRad - dMinRad ;
|
|
|
|
Point3d ptI = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLs : ptLe) ;
|
|
Point3d ptF = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLe : ptLs) ;
|
|
|
|
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 MillConusAux( 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 ptS = 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 - ptS ;
|
|
|
|
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 IConeFrame ; IConeFrame.Set( ptIV, vtV1, vtV2, vtV3) ;
|
|
Frame3d FConeFrame ; FConeFrame.Set( ptFV, vtV1, vtV2, vtV3) ;
|
|
Frame3d PlSFrame ; PlSFrame.Set( ptS, 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 ;
|
|
|
|
// Cono I
|
|
ptC.LocToLoc( m_LocalFrame, IConeFrame) ;
|
|
vtK.LocToLoc( m_LocalFrame, IConeFrame) ;
|
|
|
|
std::vector <double> vdIConeCoef(3);
|
|
std::vector <double> 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, m_LocalFrame) ;
|
|
|
|
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( 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( 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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) {
|
|
|
|
ptR2.LocToLoc( IConeFrame, m_LocalFrame) ;
|
|
|
|
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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) {
|
|
|
|
ptR2.LocToLoc( IConeFrame, m_LocalFrame) ;
|
|
|
|
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( 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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) {
|
|
|
|
ptR1.LocToLoc( IConeFrame, m_LocalFrame) ;
|
|
ptR2.LocToLoc( IConeFrame, m_LocalFrame) ;
|
|
|
|
dMin = min( ptR1.z, ptR2.z) ;
|
|
dMax = max( ptR1.z, ptR2.z) ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) {
|
|
|
|
ptR1.LocToLoc( IConeFrame, m_LocalFrame) ;
|
|
|
|
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( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
|
|
// Cono F
|
|
ptC.LocToLoc( IConeFrame, FConeFrame) ;
|
|
vtK.LocToLoc( IConeFrame, FConeFrame) ;
|
|
|
|
std::vector <double> vdFConeCoef(3);
|
|
std::vector <double> 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, m_LocalFrame) ;
|
|
|
|
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( 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( 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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) {
|
|
|
|
ptR2.LocToLoc( FConeFrame, m_LocalFrame) ;
|
|
|
|
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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) {
|
|
|
|
ptR2.LocToLoc( FConeFrame, m_LocalFrame) ;
|
|
|
|
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( 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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) {
|
|
|
|
ptR1.LocToLoc( FConeFrame, m_LocalFrame) ;
|
|
ptR2.LocToLoc( FConeFrame, m_LocalFrame) ;
|
|
|
|
dMin = min( ptR1.z, ptR2.z) ;
|
|
dMax = max( ptR1.z, ptR2.z) ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) {
|
|
|
|
ptR1.LocToLoc( FConeFrame, m_LocalFrame) ;
|
|
|
|
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( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
|
|
// Solido interno
|
|
|
|
ptC.LocToLoc( FConeFrame, m_LocalFrame) ;
|
|
vtK.LocToLoc( FConeFrame, m_LocalFrame) ;
|
|
|
|
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( m_LocalFrame, PlSFrame) ;
|
|
ptInt2.LocToLoc( m_LocalFrame, PlDFrame) ;
|
|
ptInt3.LocToLoc( m_LocalFrame, PlBFrame) ;
|
|
ptInt4.LocToLoc( m_LocalFrame, PlTFrame) ;
|
|
ptInt5.LocToLoc( m_LocalFrame, PlIFrame) ;
|
|
ptInt6.LocToLoc( m_LocalFrame, 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, m_LocalFrame) ;
|
|
|
|
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, m_LocalFrame) ;
|
|
|
|
if ( bFlag == false) {
|
|
|
|
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, m_LocalFrame) ;
|
|
|
|
if ( bFlag == false) {
|
|
|
|
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, m_LocalFrame) ;
|
|
|
|
if ( bFlag == false) {
|
|
|
|
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, m_LocalFrame) ;
|
|
|
|
if ( bFlag == false) {
|
|
|
|
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, m_LocalFrame) ;
|
|
|
|
if ( bFlag == false) {
|
|
|
|
dLim1 = ptInt6.z ;
|
|
bFlag = true ;
|
|
}
|
|
else
|
|
|
|
dLim2 = ptInt6.z ;
|
|
}
|
|
|
|
if( bFlag == true) {
|
|
|
|
dMin = min( dLim1, dLim2) ;
|
|
dMax = max( dLim1, dLim2) ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
|
|
// Traslazioni ellissi
|
|
|
|
ptC.LocToLoc( m_LocalFrame, LargeEllipse) ;
|
|
vtK.LocToLoc( m_LocalFrame, LargeEllipse) ;
|
|
|
|
std::vector <double> vdLargeCoef(3);
|
|
std::vector <double> vdLargeRoots;
|
|
|
|
vdLargeCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dMaxRad * dMaxRad ;
|
|
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( m_LocalFrame, LargeEllipse) ;
|
|
ptPf.LocToLoc( m_LocalFrame, FLargeEllipse) ;
|
|
|
|
if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dMaxRad * dMaxRad &&
|
|
ptPf.y * ptPf.y + ptPf.z * ptPf.z < dMaxRad * dMaxRad) {
|
|
|
|
ptPi.LocToLoc( LargeEllipse, m_LocalFrame) ;
|
|
ptPf.LocToLoc( FLargeEllipse, m_LocalFrame) ;
|
|
|
|
dMin = min( ptPi.z, ptPf.z) ;
|
|
dMax = max( ptPi.z, ptPf.z) ;
|
|
|
|
SubtractIntervals( 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, m_LocalFrame) ;
|
|
|
|
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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptInter1.x > 0 && ptInter2.x < dLLong) {
|
|
|
|
ptInter1.LocToLoc( LargeEllipse, m_LocalFrame) ;
|
|
ptInter2.LocToLoc( LargeEllipse, m_LocalFrame) ;
|
|
|
|
dMin = min( ptInter1.z, ptInter2.z) ;
|
|
dMax = max( ptInter1.z, ptInter2.z) ;
|
|
|
|
SubtractIntervals( 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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) {
|
|
|
|
ptInter2.LocToLoc( LargeEllipse, m_LocalFrame) ;
|
|
|
|
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( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
|
|
ptC.LocToLoc( LargeEllipse, SmallEllipse) ;
|
|
vtK.LocToLoc( LargeEllipse, SmallEllipse) ;
|
|
|
|
std::vector <double> vdSmallCoef(3);
|
|
std::vector <double> vdSmallRoots;
|
|
|
|
vdSmallCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dMinRad * dMinRad ;
|
|
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( m_LocalFrame, SmallEllipse) ;
|
|
ptPf.LocToLoc( m_LocalFrame, FSmallEllipse) ;
|
|
|
|
if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dMinRad * dMinRad &&
|
|
ptPf.y * ptPf.y + ptPf.z * ptPf.z < dMinRad * dMinRad) {
|
|
|
|
ptPi.LocToLoc( SmallEllipse, m_LocalFrame) ;
|
|
ptPf.LocToLoc( FSmallEllipse, m_LocalFrame) ;
|
|
|
|
dMin = min( ptPi.z, ptPf.z) ;
|
|
dMax = max( ptPi.z, ptPf.z) ;
|
|
|
|
SubtractIntervals( 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, m_LocalFrame) ;
|
|
|
|
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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptTInter1.x > 0 && ptTInter2.x < dLLong) {
|
|
|
|
ptTInter1.LocToLoc( SmallEllipse, m_LocalFrame) ;
|
|
ptTInter2.LocToLoc( SmallEllipse, m_LocalFrame) ;
|
|
|
|
dMin = min( ptTInter1.z, ptTInter2.z) ;
|
|
dMax = max( ptTInter1.z, ptTInter2.z) ;
|
|
|
|
SubtractIntervals( 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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptTInter1.x < 0 && ptTInter2.x > 0 && ptTInter2.x < dLLong) {
|
|
|
|
ptTInter2.LocToLoc( SmallEllipse, m_LocalFrame) ;
|
|
|
|
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( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillConusAux( 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) ;
|
|
|
|
|
|
Point3d ptV = ptI - vtV1 * dL ;
|
|
Point3d ptT = ptI - vtV1 * dHei ;
|
|
|
|
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( m_LocalFrame, ConeFrame) ;
|
|
Vector3d vtKE = vtK ; vtKE.LocToLoc( m_LocalFrame, 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( m_LocalFrame, ConeFrame) ;
|
|
|
|
std::vector <double> vdConeCoef(3);
|
|
std::vector <double> 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, m_LocalFrame) ;
|
|
|
|
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( 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( 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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) {
|
|
|
|
ptR2.LocToLoc( ConeFrame, m_LocalFrame) ;
|
|
|
|
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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) {
|
|
|
|
ptR2.LocToLoc( ConeFrame, m_LocalFrame) ;
|
|
|
|
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( 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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) {
|
|
|
|
ptR1.LocToLoc( ConeFrame, m_LocalFrame) ;
|
|
ptR2.LocToLoc( ConeFrame, m_LocalFrame) ;
|
|
|
|
dMin = min( ptR1.z, ptR2.z) ;
|
|
dMax = max( ptR1.z, ptR2.z) ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) {
|
|
|
|
ptR1.LocToLoc( ConeFrame, m_LocalFrame) ;
|
|
|
|
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( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
|
|
// Tralsazione dell'ellisse
|
|
|
|
ptC.LocToLoc( ConeFrame, IEllipseFrame) ;
|
|
|
|
std::vector <double> vdEllipseCoef(3);
|
|
std::vector <double> vdEllipseRoots;
|
|
|
|
vdEllipseCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dMaxRad * dMaxRad ;
|
|
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( m_LocalFrame, IEllipseFrame) ;
|
|
ptPf.LocToLoc( m_LocalFrame, FEllipseFrame) ;
|
|
|
|
if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dMaxRad * dMaxRad &&
|
|
ptPf.y * ptPf.y + ptPf.z * ptPf.z < dMaxRad * dMaxRad) {
|
|
|
|
ptPi.LocToLoc( IEllipseFrame, m_LocalFrame) ;
|
|
ptPf.LocToLoc( FEllipseFrame, m_LocalFrame) ;
|
|
|
|
dMin = min( ptPi.z, ptPf.z) ;
|
|
dMax = max( ptPi.z, ptPf.z) ;
|
|
|
|
SubtractIntervals( 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, 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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptInter1.x > 0 && ptInter2.x < dLLong) {
|
|
|
|
ptInter1.LocToLoc( IEllipseFrame, m_LocalFrame) ;
|
|
ptInter2.LocToLoc( IEllipseFrame, m_LocalFrame) ;
|
|
|
|
dMin = min( ptInter1.z, ptInter2.z) ;
|
|
dMax = max( ptInter1.z, ptInter2.z) ;
|
|
|
|
SubtractIntervals( 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( i, j, dMin, dMax) ;
|
|
}
|
|
else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) {
|
|
|
|
ptInter2.LocToLoc( IEllipseFrame, 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( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
// Traslazioni
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Ball( const Point3d& ptLs, const Point3d& ptLe, double dRad)
|
|
{
|
|
double dMin, dMax ;
|
|
unsigned int nStartI, nStartJ, nEndI, nEndJ ;
|
|
|
|
bool Control = BBoxComponent( 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 ;
|
|
|
|
|
|
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 < dRad * dRad) {
|
|
|
|
double dH = sqrt( dRad * dRad - dSqLen) ;
|
|
|
|
dMin = dZI - dH ;
|
|
dMax = dZI + dDeltaZ + dH ;
|
|
|
|
SubtractIntervals( 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 < dRad * dRad || dFSqDist < dRad * dRad ||
|
|
( dX1 > 0 && dX1 < dPLen && dX2 * dX2 < dRad * dRad)) {
|
|
|
|
// Massimi
|
|
if ( dX1 < - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad * dR2 * dR2)) &&
|
|
dISqDist < dRad * dRad)
|
|
|
|
dMax = dZI + sqrt( dRad * dRad - dISqDist) ;
|
|
|
|
else if ( dX1 >= - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) &&
|
|
dX1 < dPLen - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)))
|
|
|
|
dMax = dZI + dR2 * sqrt( dRad * dRad - dX2 * dX2) + ( dX1 + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad))) * dVLen / dPLen ;
|
|
|
|
else if ( dX1 >= dPLen - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) &&
|
|
dFSqDist < dRad * dRad)
|
|
|
|
dMax = dZI + dDeltaZ + sqrt( dRad * dRad - dFSqDist) ;
|
|
|
|
// Minimi
|
|
if ( dX1 < dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) &&
|
|
dISqDist < dRad * dRad)
|
|
|
|
dMin = dZI - sqrt( dRad * dRad - dISqDist) ;
|
|
|
|
else if ( dX1 >= dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) &&
|
|
dX1 < dPLen + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)))
|
|
|
|
dMin = dZI - dR2 * sqrt( dRad * dRad - dX2 * dX2) + ( dX1 - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad))) * dVLen / dPLen ;
|
|
|
|
else if ( dX1 >= dPLen + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) &&
|
|
dFSqDist < dRad * dRad)
|
|
|
|
dMin = dZI + dDeltaZ - sqrt( dRad * dRad - dFSqDist) ;
|
|
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
|
|
// Bounding Box, interferenza dell'utensile con lo Zmap e limiti su indici
|
|
//----------------------------------------------------------------------------
|
|
inline bool
|
|
VolZmap::BoundingBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2,
|
|
unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ)
|
|
{
|
|
// 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 > m_nNx * m_dStep - EPS_SMALL)
|
|
return false ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return false ;
|
|
if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL)
|
|
return false ;
|
|
|
|
// Limiti su indici
|
|
nStI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
nEnI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
nStJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
nEnJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
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.
|
|
unsigned int nMaxNx, nMaxNy ;
|
|
|
|
double dMaxXValue, dMaxYValue ;
|
|
double dMinZValue, dMaxZValue ;
|
|
|
|
if ( nGrid == 1) {
|
|
|
|
nMaxNx = m_nNx ; nMaxNy = m_nNy ;
|
|
|
|
dMaxXValue = m_nNx * m_dStep ; dMaxYValue = m_nNy * m_dStep ;
|
|
|
|
dMinZValue = m_dMinZ ; dMaxZValue = m_dMaxZ ;
|
|
}
|
|
else if ( nGrid == 2) {
|
|
|
|
nMaxNx = m_nNx2 ; nMaxNy = m_nNy2 ;
|
|
|
|
dMaxXValue = m_nNx2 * m_dStep ; dMaxYValue = m_nNy2 * m_dStep ;
|
|
|
|
dMinZValue = m_dMinZ2 ; dMaxZValue = m_dMaxZ2 ;
|
|
}
|
|
else if ( nGrid == 3) {
|
|
|
|
nMaxNx = m_nNx3 ; nMaxNy = m_nNy3 ;
|
|
|
|
dMaxXValue = m_nNx3 * m_dStep ; dMaxYValue = m_nNy3 * m_dStep ;
|
|
|
|
dMinZValue = m_dMinZ3 ; dMaxZValue = m_dMaxZ3 ;
|
|
}
|
|
|
|
// 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 <unsigned int> ( dMinX / m_dStep)) ;
|
|
nEnI = ( dMaxX > dMaxXValue - EPS_SMALL ? nMaxNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
nStJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
nEnJ = ( dMaxY > dMaxYValue - EPS_SMALL ? nMaxNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
inline bool
|
|
VolZmap::BoundingBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2)
|
|
{
|
|
// 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 > m_nNx * m_dStep - EPS_SMALL)
|
|
return false ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return false ;
|
|
if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL)
|
|
return false ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
inline bool
|
|
VolZmap::BBoxComponent( 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)
|
|
{
|
|
// Determinazione del raggio massimo dell'utensile
|
|
double dMaxRad = max( dRad, dTipRad) ;
|
|
|
|
// Determinazione delle posizioni della punta dell'utensile 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 > m_nNx * m_dStep - EPS_SMALL)
|
|
return false ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return false ;
|
|
if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL)
|
|
return false ;
|
|
|
|
// Limiti su indici
|
|
nStI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
nEnI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
nStJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
nEnJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
return true ;
|
|
} |