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