d21f27ae2d
- migliorie a Zmap.
1035 lines
35 KiB
C++
1035 lines
35 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2015
|
|
//----------------------------------------------------------------------------
|
|
// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4
|
|
// Contenuto : Implementazione della classe Volume Zmap.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 22.01.15 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "VolZmap.h"
|
|
#include "GeoObjFactory.h"
|
|
#include "NgeWriter.h"
|
|
#include "NgeReader.h"
|
|
#include "\EgtDev\Include\EGkIntervals.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
GEOOBJ_REGISTER( VOL_ZMAP, NGE_V_ZMP, VolZmap) ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
VolZmap::VolZmap(void)
|
|
: m_nStatus( TO_VERIFY), m_nTempProp()
|
|
{
|
|
m_dStep = 0 ;
|
|
m_nNx = 0 ;
|
|
m_nNy = 0 ;
|
|
m_nDim = 0 ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
VolZmap::~VolZmap( void)
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
VolZmap*
|
|
VolZmap::Clone( void) const
|
|
{
|
|
// alloco oggetto
|
|
VolZmap* pVzm = new(nothrow) VolZmap ;
|
|
if ( pVzm != nullptr) {
|
|
if ( ! pVzm->CopyFrom( *this)) {
|
|
delete pVzm ;
|
|
return nullptr ;
|
|
}
|
|
}
|
|
|
|
return pVzm ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::CopyFrom( const IGeoObj* pGObjSrc)
|
|
{
|
|
const VolZmap* pVzm = dynamic_cast<const VolZmap*>( pGObjSrc) ;
|
|
if ( pVzm == nullptr)
|
|
return false ;
|
|
return CopyFrom( *pVzm) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::CopyFrom( const VolZmap& vzmSrc)
|
|
{
|
|
if ( &vzmSrc == this)
|
|
return true ;
|
|
m_OGrMgr.Reset() ;
|
|
m_LocalFrame = vzmSrc.m_LocalFrame ;
|
|
m_dStep = vzmSrc.m_dStep ;
|
|
m_nDim = vzmSrc.m_nDim ;
|
|
m_nNx = vzmSrc.m_nNx ;
|
|
m_nNy = vzmSrc.m_nNy ;
|
|
m_ZValues = vzmSrc.m_ZValues ;
|
|
m_nStatus = vzmSrc.m_nStatus ;
|
|
m_nTempProp = vzmSrc.m_nTempProp ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
GeoObjType
|
|
VolZmap::GetType( void) const
|
|
{
|
|
return static_cast<GeoObjType>( GEOOBJ_GETTYPE( VolZmap)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const string&
|
|
VolZmap::GetTitle( void) const
|
|
{
|
|
static const string sTitle = "Zmap" ;
|
|
return sTitle ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Dump( string& sOut, bool bMM, const char* szNewLine) const
|
|
{
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
VolZmap::GetNgeId( void) const
|
|
{
|
|
return GEOOBJ_GETNGEID( VolZmap) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Save( NgeWriter& ngeOut) const
|
|
{
|
|
// parametri di scrittura: sistema di riferimento, minimo incremento, numero di passi
|
|
// in direzione x e y, e per ogni casella, numero di valori e valori
|
|
if ( ! ngeOut.WriteFrame( m_LocalFrame, ";", true))
|
|
return false ;
|
|
if ( ! ngeOut.WriteDouble( m_dStep, ",", false))
|
|
return false ;
|
|
if ( ! ngeOut.WriteInt( m_nNx, ",", false))
|
|
return false ;
|
|
if ( ! ngeOut.WriteInt( m_nNy, ";", true))
|
|
return false ;
|
|
// ciclo sui dexel
|
|
for ( unsigned int i = 0 ; i < m_nDim ; ++ i) {
|
|
// numero di estremi
|
|
int nDim = int( m_ZValues[i].size()) ;
|
|
if ( ! ngeOut.WriteInt( nDim, ",", false))
|
|
return false ;
|
|
// se dexel nullo
|
|
if ( nDim == 0) {
|
|
// scrivo un valore dummy
|
|
if ( ! ngeOut.WriteDouble( 0, ";", true))
|
|
return false ;
|
|
}
|
|
// altrimenti
|
|
else {
|
|
for ( unsigned int k = 0 ; k < m_ZValues[i].size() ; ++ k) {
|
|
bool bEndL = ( k == m_ZValues[i].size() - 1) ;
|
|
if ( ! ngeOut.WriteDouble( m_ZValues[i][k], ( bEndL ? ";" : ","), bEndL))
|
|
return false ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Load( NgeReader& ngeIn)
|
|
{
|
|
m_nStatus = TO_VERIFY ;
|
|
// parametri di lettura: sistema di riferimento, minimo incremento, numero di passi
|
|
// in direzione x e y, e per ogni casella, numero di valori e valori
|
|
if ( ! ngeIn.ReadFrame( m_LocalFrame, ";", true))
|
|
return false ;
|
|
if ( ! ngeIn.ReadDouble( m_dStep, ",", false))
|
|
return false ;
|
|
int nTemp ;
|
|
if ( ! ngeIn.ReadInt( nTemp, ",", false))
|
|
return false ;
|
|
m_nNx = nTemp ;
|
|
if ( ! ngeIn.ReadInt( nTemp, ";", true))
|
|
return false ;
|
|
m_nNy = nTemp ;
|
|
|
|
// dimensione del vettore di dexel
|
|
m_nDim = m_nNx * m_nNy ;
|
|
m_ZValues.resize(m_nDim) ;
|
|
|
|
// ciclo sui dexel
|
|
for ( unsigned int i = 0 ; i < m_nDim ; ++ i) {
|
|
// leggo il numero di estremi nel dexel
|
|
if ( ! ngeIn.ReadInt( nTemp, ",", false))
|
|
return false ;
|
|
// devono essere pari
|
|
if ( ( nTemp % 2) != 0)
|
|
return false ;
|
|
// se dexel nullo
|
|
if ( nTemp == 0) {
|
|
// leggo un valore dummy
|
|
double dDummy ;
|
|
if ( ! ngeIn.ReadDouble( dDummy, ",", true))
|
|
return false ;
|
|
}
|
|
// altrimenti
|
|
else {
|
|
// dimensiono l'array
|
|
m_ZValues[i].resize(nTemp) ;
|
|
// leggo i valori
|
|
for ( unsigned int k = 0 ; k < m_ZValues[i].size() ; ++ k) {
|
|
bool bEndL = ( k == m_ZValues[i].size() - 1) ;
|
|
if ( ! ngeIn.ReadDouble( m_ZValues[i][k], ( bEndL ? ";" : ","), bEndL))
|
|
return false ;
|
|
}
|
|
}
|
|
}
|
|
|
|
m_nStatus = OK ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::GetLocalBBox( BBox3d& b3Loc, int nFlag) const
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
// reset box
|
|
b3Loc.Reset() ;
|
|
// ciclo sui dexel
|
|
double dY = 0.5 * m_dStep ;
|
|
for ( size_t i = 0 ; i < m_nNy ; ++ i) {
|
|
double dX = 0.5 * m_dStep ;
|
|
for ( size_t j = 0 ; j < m_nNx ; ++ j) {
|
|
size_t nPos = j + i * m_nNx ;
|
|
if ( m_ZValues[nPos].size() > 0) {
|
|
Point3d ptP = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ;
|
|
b3Loc.Add( ptP + m_ZValues[nPos][0] * m_LocalFrame.VersZ()) ;
|
|
b3Loc.Add( ptP + m_ZValues[nPos][m_ZValues[nPos].size()-1] * m_LocalFrame.VersZ()) ;
|
|
}
|
|
dX += m_dStep ;
|
|
}
|
|
dY += m_dStep ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
// reset box
|
|
b3Ref.Reset() ;
|
|
// trasformo il riferimento locale tramite quello passato
|
|
Frame3d frUse = m_LocalFrame ;
|
|
frUse.ToGlob( frRef) ;
|
|
// ciclo sui dexel
|
|
double dY = 0.5 * m_dStep ;
|
|
for ( size_t i = 0 ; i < m_nNy ; ++ i) {
|
|
double dX = 0.5 * m_dStep ;
|
|
for ( size_t j = 0 ; j < m_nNx ; ++ j) {
|
|
size_t nPos = j + i * m_nNx ;
|
|
if ( m_ZValues[nPos].size() > 0) {
|
|
Point3d ptP = frUse.Orig() + dX * frUse.VersX() + dY * frUse.VersY() ;
|
|
b3Ref.Add( ptP + m_ZValues[nPos][0] * frUse.VersZ()) ;
|
|
b3Ref.Add( ptP + m_ZValues[nPos][m_ZValues[nPos].size()-1] * frUse.VersZ()) ;
|
|
}
|
|
dX += m_dStep ;
|
|
}
|
|
dY += m_dStep ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Translate( const Vector3d& vtMove)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
// imposto ricalcolo della grafica
|
|
m_OGrMgr.Reset() ;
|
|
// traslo il riferimento
|
|
m_LocalFrame.Translate( vtMove) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
// imposto ricalcolo della grafica
|
|
m_OGrMgr.Reset() ;
|
|
// ruoto il riferimento
|
|
return m_LocalFrame.Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ToGlob( const Frame3d& frRef)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::ToLoc( const Frame3d& frRef)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK)
|
|
return false ;
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::CreateMap( const Point3d& ptO, double dPrec, double dLengthX, double dLengthY, double dLengthZ)
|
|
{
|
|
// Controlli sui parametri
|
|
if ( dPrec < EPS_SMALL || dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL)
|
|
return false ;
|
|
|
|
m_LocalFrame.Set( ptO, X_AX, Y_AX, Z_AX) ;
|
|
|
|
m_dStep = dPrec ;
|
|
|
|
m_nNx = static_cast <unsigned int> ( ceil( dLengthX / m_dStep)) ;
|
|
m_nNy = static_cast <unsigned int> ( ceil( dLengthY / m_dStep)) ;
|
|
|
|
m_nDim = m_nNx * m_nNy ;
|
|
|
|
m_ZValues.resize( m_nDim) ;
|
|
|
|
for ( int i = 0 ; i < int( m_nDim) ; i++) {
|
|
m_ZValues[i].resize(2) ;
|
|
|
|
m_ZValues[i][0] = 0 ;
|
|
m_ZValues[i][1] = dLengthZ ;
|
|
}
|
|
|
|
m_nStatus = OK ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::SubtractIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax)
|
|
{
|
|
unsigned int nPos ;
|
|
//unsigned int nKD ;
|
|
//unsigned int nKU ;
|
|
//unsigned int nDelta ; // Variazione di dimensione del vettore
|
|
|
|
// Controllo che dMin e dMax non siano quasi coincidenti
|
|
if ( abs( dMax - dMin) < EPS_SMALL)
|
|
|
|
return true ;
|
|
// Controllo che dMin < dMax
|
|
|
|
if ( dMax < dMin ) {
|
|
|
|
double dTemp = dMax ;
|
|
|
|
dMax = dMin ;
|
|
dMin = dMax ;
|
|
}
|
|
|
|
// Calcolo nPos
|
|
nPos = nJ*m_nNx + nI ; // O nJ*m_Nx + nI + 1 ?
|
|
|
|
unsigned int i = 0 ;
|
|
|
|
while ( i < m_ZValues[nPos].size() - 1) {
|
|
|
|
if ( m_ZValues[nPos].size() == 0)
|
|
return true ;
|
|
// Casi:
|
|
// Intervallo da sottrarre è tutto a sinistra di quello corrente, non vi è intersezione
|
|
if ( m_ZValues[nPos][i] > dMax - EPS_SMALL) {
|
|
|
|
}
|
|
// Intersezione
|
|
else if ( m_ZValues[nPos][i + 1] > dMax + EPS_SMALL) {
|
|
// L'intervallo corrente corrente viene limitato a sinistra
|
|
if ( m_ZValues[nPos][i] > dMin - EPS_SMALL) {
|
|
|
|
m_ZValues[nPos][i] = dMax ;
|
|
}
|
|
// L'intervallo si divide in due intervalli
|
|
else {
|
|
|
|
m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ;
|
|
|
|
for ( size_t j = m_ZValues[nPos].size() - 1 ; j >= i + 3 ; -- j)
|
|
|
|
m_ZValues[nPos][j] = m_ZValues[nPos][j - 2] ;
|
|
|
|
m_ZValues[nPos][i + 1] = dMin ;
|
|
m_ZValues[nPos][i + 2] = dMax ;
|
|
|
|
i = i + 2 ;
|
|
}
|
|
}
|
|
else {
|
|
// L'intervallo corrente viene eliminato
|
|
if ( m_ZValues[nPos][i] > dMin - EPS_SMALL) {
|
|
|
|
for ( unsigned int j = i ; j < m_ZValues[nPos].size() - 2 ; ++ j)
|
|
|
|
m_ZValues[nPos][j] = m_ZValues[nPos][j + 2] ;
|
|
|
|
m_ZValues[nPos].resize( m_ZValues[nPos].size() - 2) ;
|
|
|
|
i = i - 2 ;
|
|
}
|
|
// L'intervallo corrente viene limitato a destra
|
|
else if ( m_ZValues[nPos][i + 1] > dMin + EPS_SMALL) {
|
|
|
|
m_ZValues[nPos][i + 1] = dMin ;
|
|
}
|
|
// L'intervallo da sottrarre è tutto a destra di quello corrente, non vi è intersezione
|
|
else {
|
|
|
|
}
|
|
}
|
|
|
|
i = i + 2 ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::SubtractIntervals( const Point3d& ptP, double dMin, double dMax) // ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame)
|
|
{
|
|
Point3d ptPL = ptP ;
|
|
ptPL.ToLoc( m_LocalFrame) ; // ptPL è ora espresso rispetto al sistema di riferimento intrinseco.
|
|
|
|
double dX, dY, dZ ; // Coordinate di ptPL nel sistema intrinseco
|
|
double dhMin, dhMax ; // Altezze dMin e dMax RIESPRESSE nel sistema intrinseco (dMin e dMax sono altezze rispetto a ptP)
|
|
|
|
dX = ptPL.x ; dY = ptPL.y ; dZ = ptPL.z ;
|
|
dhMin = dZ + dMin ; dhMax = dZ + dMax ;
|
|
|
|
// Cerco il punto della griglia più vicino
|
|
|
|
double integerPartX = floor( dX / m_dStep) ;
|
|
double integerPartY = floor( dY / m_dStep) ;
|
|
|
|
unsigned int i = static_cast <unsigned int> (integerPartX) ; // Indici del punto di griglia più vicino.
|
|
unsigned int j = static_cast <unsigned int> (integerPartY) ; // i = 0, 1, ..., m_Nx - 1 ; j = 0, 1, ..., m_Ny - 1
|
|
|
|
// Controllo se le coordinate x e y del punto dato siano all'interno della griglia:
|
|
// se sono dentro la griglia chiamo l'altra subtract
|
|
if ( dX < m_dStep*m_nNx && dY < m_dStep*m_nNy
|
|
&& dX >= 0 && dY >= 0) { // Mettendo > - qlc può sempre capitare un punto compreso fra - qlc e 0 e si esce dai limiti dell vector
|
|
|
|
return SubtractIntervals( i, j, dhMin, dhMax) ;
|
|
}
|
|
// altrimenti non succede niente
|
|
else {
|
|
|
|
return true ;
|
|
}
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::AddIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax)
|
|
{
|
|
unsigned int nPos ;
|
|
//unsigned int nKD ;
|
|
//unsigned int nKU ;
|
|
//unsigned int nDelta ; // Variazione di dimensione del vettore
|
|
|
|
// Controllo che dMin e dMax non siano quasi coincidenti
|
|
if ( abs( dMax - dMin) < EPS_SMALL)
|
|
|
|
return true ;
|
|
|
|
// Controllo che dMin < dMax
|
|
if ( dMax < dMin ) {
|
|
|
|
double dTemp = dMax ;
|
|
|
|
dMax = dMin ;
|
|
dMin = dMax ;
|
|
}
|
|
|
|
// Calcolo nPos
|
|
nPos = nJ*m_nNx + nI ; // O nJ*m_Nx + nI + 1 ?
|
|
|
|
if ( m_ZValues[nPos].size() == 0) {
|
|
|
|
m_ZValues[nPos].resize( 2) ;
|
|
|
|
m_ZValues[nPos][0] = dMin ;
|
|
m_ZValues[nPos][1] = dMax ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
unsigned int i = 0 ;
|
|
|
|
while ( i < m_ZValues[nPos].size() - 1) {
|
|
|
|
if ( i > 0) {
|
|
// Caso in cui un intervallo precedente sconfini in quello corrente
|
|
if ( m_ZValues[nPos][i] < m_ZValues[nPos][i - 1] + EPS_SMALL) {
|
|
// Se l'intervallo corrente non è contenuto totalmente si esegue l'istruzione successiva
|
|
if ( m_ZValues[nPos][i - 1] < m_ZValues[nPos][i + 1] + EPS_SMALL)
|
|
|
|
m_ZValues[nPos][i - 1] = m_ZValues[nPos][i + 1] ;
|
|
|
|
for ( unsigned int j = i ; j < m_ZValues[nPos].size() - 2 ; ++ j)
|
|
|
|
m_ZValues[nPos][j] = m_ZValues[nPos][j + 2] ;
|
|
|
|
m_ZValues[nPos].resize( m_ZValues[nPos].size() - 2) ;
|
|
|
|
i = i - 2 ;
|
|
}
|
|
}
|
|
|
|
// Caso in cui devo aggiungere un intervallo a sinistra dell'intervallo corrente
|
|
if ( m_ZValues[nPos][i] > dMax + EPS_SMALL) {
|
|
|
|
m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ;
|
|
|
|
for ( size_t j = m_ZValues[nPos].size() - 1 ; j >= i + 2 ; -- j)
|
|
|
|
m_ZValues[nPos][j] = m_ZValues[nPos][j - 2] ;
|
|
|
|
m_ZValues[nPos][i] = dMin ;
|
|
m_ZValues[nPos][i + 1] = dMax ;
|
|
|
|
i = i + 2 ;
|
|
}
|
|
// Casi d'intersezione:
|
|
else if ( m_ZValues[nPos][i + 1] > dMax - EPS_SMALL) {
|
|
// Se l'intervallo da aggiungere sconfina a sinistra modifico il minimo dell'intervalo corrente
|
|
if (m_ZValues[nPos][i] > dMin - EPS_SMALL) {
|
|
|
|
m_ZValues[nPos][i] = dMin ;
|
|
}
|
|
}
|
|
else {
|
|
// Se l'intervallo corrente è tutto contenuto nell'intervallo da aggungere modifico gli estremi
|
|
if ( m_ZValues[nPos][i] > dMin + EPS_SMALL) {
|
|
|
|
m_ZValues[nPos][i] = dMin ;
|
|
m_ZValues[nPos][i + 1] = dMax ;
|
|
}
|
|
// Se l'intervallo da aggiungere sconfina a destra modifico il massimo dell'intervallo corrente
|
|
else if ( m_ZValues[nPos][i + 1] > dMin - EPS_SMALL) {
|
|
|
|
m_ZValues[nPos][i + 1] = dMax ;
|
|
}
|
|
else {
|
|
// Aggiungo intervallo a destra dell'ultimo intervallo
|
|
if ( i == m_ZValues[nPos].size() - 2) {
|
|
|
|
m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ;
|
|
|
|
m_ZValues[nPos][i + 2] = dMin ;
|
|
m_ZValues[nPos][i + 3] = dMax ;
|
|
|
|
i = i + 2 ;
|
|
}
|
|
}
|
|
}
|
|
|
|
i = i + 2 ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::AddIntervals( const Point3d& ptP, double dMin, double dMax) // ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame)
|
|
{
|
|
Point3d ptPL = ptP ;
|
|
ptPL.ToLoc( m_LocalFrame) ; // ptPL è ora espresso rispetto al sistema di riferimento intrinseco.
|
|
|
|
double dX, dY, dZ ; // Coordinate di ptPL nel sistema intrinseco
|
|
double dhMin, dhMax ; // Altezze dMin e dMax RIESPRESSE nel sistema intrinseco (dMin e dMax sono altezze rispetto a ptP)
|
|
|
|
dX = ptPL.x ; dY = ptPL.y ; dZ = ptPL.z ;
|
|
dhMin = dZ + dMin ; dhMax = dZ + dMax ;
|
|
|
|
// Cerco il punto della griglia più vicino
|
|
|
|
double integerPartX = floor( dX / m_dStep) ;
|
|
double integerPartY = floor( dY / m_dStep) ;
|
|
|
|
unsigned int i = static_cast <unsigned int> (integerPartX) ; // Indici del punto di griglia più vicino.
|
|
unsigned int j = static_cast <unsigned int> (integerPartY) ; // i = 0, 1, ..., m_Nx - 1 ; j = 0, 1, ..., m_Ny - 1
|
|
|
|
// Controllo se le coordinate x e y del punto dato siano all'interno della griglia:
|
|
// se sono dentro la griglia chiamo l'altra subtract
|
|
if ( dX < m_dStep*m_nNx && dY < m_dStep*m_nNy
|
|
&& dX >= 0 && dY >= 0) { // Mettendo > - qlc può sempre capitare un punto compreso fra - qlc e 0 e si esce dai limiti dell vector
|
|
|
|
return AddIntervals( i, j, dhMin, dhMax) ;
|
|
}
|
|
// altrimenti non succede niente
|
|
else {
|
|
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) const
|
|
{
|
|
// per ora solo perpendicolari a XY (1)
|
|
if ( nDir != 1)
|
|
return false ;
|
|
// verifiche sugli indici
|
|
if ( nPos1 < 0 || nPos1 >= int( m_nNx) || nPos2 < 0 || nPos2 >= int( m_nNy))
|
|
return false ;
|
|
int nPos = nPos1 + nPos2 * m_nNx ;
|
|
if ( nPos < 0 || nPos >= int( m_ZValues.size()))
|
|
return false ;
|
|
// calcolo coordinate punto
|
|
double dX = m_dStep * ( 0.5 + nPos1) ;
|
|
double dY = m_dStep * ( 0.5 + nPos2) ;
|
|
Point3d ptP = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ;
|
|
// creo le polilinee
|
|
for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) {
|
|
// aggiungo polilinea a lista
|
|
lstPL.emplace_back() ;
|
|
// inserisco punti estremi
|
|
lstPL.back().AddUPoint( 0, ptP + m_ZValues[nPos][i-1] * m_LocalFrame.VersZ()) ;
|
|
lstPL.back().AddUPoint( 1, ptP + m_ZValues[nPos][i] * m_LocalFrame.VersZ()) ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::GetAllTriangles( TRIA3DLIST& lstTria) const
|
|
{
|
|
const int DIM_CHUNK = 4 ;
|
|
for ( int i = 0 ; i < int( m_nNx) ; i += DIM_CHUNK) {
|
|
int nDimChunkX = min( DIM_CHUNK, int( m_nNx) - i) ;
|
|
for ( int j = 0 ; j < int( m_nNy) ; j += DIM_CHUNK) {
|
|
int nDimChunkY = min( DIM_CHUNK, int( m_nNy) - j) ;
|
|
GetChunkPrisms( i, j, nDimChunkX, nDimChunkY, lstTria) ;
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::GetChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, TRIA3DLIST& lstTria) const
|
|
{
|
|
// determino se è un semplice parallelepipedo
|
|
bool bIsSimple = true ;
|
|
double dBotZ ;
|
|
double dTopZ ;
|
|
for ( int i = 0 ; i < nDim1 && bIsSimple ; ++ i) {
|
|
for ( int j = 0 ; j < nDim2 && bIsSimple ; ++ j) {
|
|
int nPos = ( nPos1 + i) + ( nPos2 + j) * m_nNx ;
|
|
if ( nPos > int( m_nDim) ||
|
|
int( m_ZValues[nPos].size()) != 2)
|
|
bIsSimple = false ;
|
|
else if ( i == 0 && j == 0) {
|
|
dBotZ = m_ZValues[nPos][0] ;
|
|
dTopZ = m_ZValues[nPos][1] ;
|
|
}
|
|
else if ( abs( m_ZValues[nPos][0] - dBotZ) > EPS_SMALL ||
|
|
abs( m_ZValues[nPos][1] - dTopZ) > EPS_SMALL)
|
|
bIsSimple = false ;
|
|
}
|
|
}
|
|
|
|
// se semplice parallelepipedo
|
|
if ( bIsSimple) {
|
|
CalcChunkPrisms( nPos1, nPos2, nDim1, nDim2, lstTria) ;
|
|
}
|
|
// altrimenti
|
|
else {
|
|
// elaboro ogni singolo dexel
|
|
for ( int i = 0 ; i < nDim1 ; ++ i) {
|
|
for ( int j = 0 ; j < nDim2 ; ++ j) {
|
|
CalcDexelPrisms( nPos1 + i, nPos2 + j, lstTria) ;
|
|
}
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::CalcChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, TRIA3DLIST& lstTria) const
|
|
{
|
|
// verifiche sugli indici
|
|
if ( nPos1 < 0 || nPos1 + nDim1 > int( m_nNx) || nPos2 < 0 || nPos2 + nDim2 > int( m_nNy))
|
|
return false ;
|
|
int nPos = nPos1 + nPos2 * m_nNx ;
|
|
if ( nPos < 0 || nPos >= int( m_nDim))
|
|
return false ;
|
|
|
|
// calcolo coordinate punti
|
|
double dX = m_dStep * nPos1 ;
|
|
double dY = m_dStep * nPos2 ;
|
|
Point3d ptP1 = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ;
|
|
Point3d ptP2 = ptP1 + nDim1 * m_dStep * m_LocalFrame.VersX() ;
|
|
Point3d ptP3 = ptP2 + nDim2 * m_dStep * m_LocalFrame.VersY() ;
|
|
Point3d ptP4 = ptP1 + nDim2 * m_dStep * m_LocalFrame.VersY() ;
|
|
|
|
// creo le facce sopra e sotto
|
|
Vector3d vtDZt = m_ZValues[nPos][1] * m_LocalFrame.VersZ() ;
|
|
Vector3d vtDZb = m_ZValues[nPos][0] * m_LocalFrame.VersZ() ;
|
|
// faccia superiore P1t->P2t->P3t->P4t : sempre visibile
|
|
lstTria.emplace_back() ;
|
|
lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_LocalFrame.VersZ()) ;
|
|
lstTria.emplace_back() ;
|
|
lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_LocalFrame.VersZ()) ;
|
|
// faccia inferiore P1b->P4b->P3b->P2b : sempre visibile
|
|
lstTria.emplace_back() ;
|
|
lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_LocalFrame.VersZ()) ;
|
|
lstTria.emplace_back() ;
|
|
lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_LocalFrame.VersZ()) ;
|
|
|
|
// creo le facce laterali
|
|
for ( int j = 0 ; j < nDim2 ; ++ j) {
|
|
int nPosD = nPos + nDim1 - 1 + j * m_nNx ;
|
|
int nPosEst = ( nPos1 + nDim1 - 1 < int( m_nNx - 1) ? nPosD + 1 : - 1) ;
|
|
Point3d ptP2D = ptP2 + j * m_dStep * m_LocalFrame.VersY() ;
|
|
Point3d ptP3D = ptP2D + m_dStep * m_LocalFrame.VersY() ;
|
|
AddDexelSideFace( nPosD, nPosEst, ptP2D, ptP3D, m_LocalFrame.VersZ(), m_LocalFrame.VersX(), lstTria) ;
|
|
}
|
|
for ( int i = 0 ; i < nDim1 ; ++ i) {
|
|
int nPosD = nPos + ( nDim2 - 1) * m_nNx + i ;
|
|
int nPosNord = ( nPos2 + nDim2 - 1 < int( m_nNy - 1) ? nPosD + m_nNx : - 1) ;
|
|
Point3d ptP4D = ptP4 + i * m_dStep * m_LocalFrame.VersX() ;
|
|
Point3d ptP3D = ptP4D + m_dStep * m_LocalFrame.VersX() ;
|
|
AddDexelSideFace( nPosD, nPosNord, ptP3D, ptP4D, m_LocalFrame.VersZ(), m_LocalFrame.VersY(), lstTria) ;
|
|
}
|
|
for ( int j = 0 ; j < nDim2 ; ++ j) {
|
|
int nPosD = nPos + j * m_nNx ;
|
|
int nPosWest = ( nPos1 > 0 ? nPosD - 1 : - 1) ;
|
|
Point3d ptP1D = ptP1 + j * m_dStep * m_LocalFrame.VersY() ;
|
|
Point3d ptP4D = ptP1D + m_dStep * m_LocalFrame.VersY() ;
|
|
AddDexelSideFace( nPosD, nPosWest, ptP4D, ptP1D, m_LocalFrame.VersZ(), - m_LocalFrame.VersX(), lstTria) ;
|
|
}
|
|
for ( int i = 0 ; i < nDim1 ; ++ i) {
|
|
int nPosD = nPos + i ;
|
|
int nPosSud = ( nPos2 > 0 ? nPosD - m_nNx : - 1) ;
|
|
Point3d ptP1D = ptP1 + i * m_dStep * m_LocalFrame.VersX() ;
|
|
Point3d ptP2D = ptP1D + m_dStep * m_LocalFrame.VersX() ;
|
|
AddDexelSideFace( nPosD, nPosSud, ptP1D, ptP2D, m_LocalFrame.VersZ(), - m_LocalFrame.VersY(), lstTria) ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::CalcDexelPrisms( int nPos1, int nPos2, TRIA3DLIST& lstTria) const
|
|
{
|
|
// verifiche sugli indici
|
|
if ( nPos1 < 0 || nPos1 >= int( m_nNx) || nPos2 < 0 || nPos2 >= int( m_nNy))
|
|
return false ;
|
|
int nPos = nPos1 + nPos2 * m_nNx ;
|
|
if ( nPos < 0 || nPos >= int( m_nDim))
|
|
return false ;
|
|
|
|
// calcolo coordinate punto
|
|
double dX = m_dStep * nPos1 ;
|
|
double dY = m_dStep * nPos2 ;
|
|
Point3d ptP1 = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ;
|
|
Point3d ptP2 = ptP1 + m_dStep * m_LocalFrame.VersX() ;
|
|
Point3d ptP3 = ptP2 + m_dStep * m_LocalFrame.VersY() ;
|
|
Point3d ptP4 = ptP1 + m_dStep * m_LocalFrame.VersY() ;
|
|
|
|
// creo le facce sopra e sotto di ogni intervallo (sempre visibili)
|
|
for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) {
|
|
Vector3d vtDZt = m_ZValues[nPos][i] * m_LocalFrame.VersZ() ;
|
|
Vector3d vtDZb = m_ZValues[nPos][i-1] * m_LocalFrame.VersZ() ;
|
|
// faccia superiore P1t->P2t->P3t->P4t : sempre visibile
|
|
lstTria.emplace_back() ;
|
|
lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_LocalFrame.VersZ()) ;
|
|
lstTria.emplace_back() ;
|
|
lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_LocalFrame.VersZ()) ;
|
|
// faccia inferiore P1b->P4b->P3b->P2b : sempre visibile
|
|
lstTria.emplace_back() ;
|
|
lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_LocalFrame.VersZ()) ;
|
|
lstTria.emplace_back() ;
|
|
lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_LocalFrame.VersZ()) ;
|
|
}
|
|
|
|
// creo le facce laterali
|
|
int nPosEst = ( nPos1 < int( m_nNx - 1) ? nPos + 1 : - 1) ;
|
|
AddDexelSideFace( nPos, nPosEst, ptP2, ptP3, m_LocalFrame.VersZ(), m_LocalFrame.VersX(), lstTria) ;
|
|
int nPosNord = ( nPos2 < int( m_nNy - 1) ? nPos + m_nNx : - 1) ;
|
|
AddDexelSideFace( nPos, nPosNord, ptP3, ptP4, m_LocalFrame.VersZ(), m_LocalFrame.VersY(), lstTria) ;
|
|
int nPosWest = ( nPos1 > 0 ? nPos - 1 : - 1) ;
|
|
AddDexelSideFace( nPos, nPosWest, ptP4, ptP1, m_LocalFrame.VersZ(), - m_LocalFrame.VersX(), lstTria) ;
|
|
int nPosSud = ( nPos2 > 0 ? nPos - m_nNx : - 1) ;
|
|
AddDexelSideFace( nPos, nPosSud, ptP1, ptP2, m_LocalFrame.VersZ(), - m_LocalFrame.VersY(), lstTria) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::AddDexelSideFace( int nPos, int nPosAdj, const Point3d& ptP, const Point3d& ptQ,
|
|
const Vector3d& vtZ, const Vector3d& vtNorm, TRIA3DLIST& lstTria) const
|
|
{
|
|
Intervals intFace ;
|
|
for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2)
|
|
intFace.Add( m_ZValues[nPos][i-1], m_ZValues[nPos][i]) ;
|
|
if ( nPosAdj > 0) {
|
|
for ( int i = 1 ; i < int( m_ZValues[nPosAdj].size()) ; i += 2)
|
|
intFace.Subtract( m_ZValues[nPosAdj][i-1], m_ZValues[nPosAdj][i]) ;
|
|
}
|
|
double dMin, dMax ;
|
|
bool bFound = intFace.GetFirst( dMin, dMax) ;
|
|
while ( bFound) {
|
|
Vector3d vtDZt = dMax * vtZ ;
|
|
Vector3d vtDZb = dMin * vtZ ;
|
|
lstTria.emplace_back() ;
|
|
lstTria.back().Set( ptP + vtDZb, ptQ + vtDZb, ptQ + vtDZt, vtNorm) ;
|
|
lstTria.emplace_back() ;
|
|
lstTria.back().Set( ptQ + vtDZt, ptP + vtDZt, ptP + vtDZb, vtNorm) ;
|
|
bFound = intFace.GetNext( dMin, dMax) ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::SetTool( const string& pToolName, unsigned int nToolType, const CurveComposite* pToolOutline)
|
|
{
|
|
m_sToolName = pToolName ;
|
|
|
|
m_nToolType = nToolType ;
|
|
|
|
m_ToolOutline.CopyFrom( pToolOutline) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingStep( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtDs, const Vector3d& vtDe)
|
|
{
|
|
// Dimensioni dell'utensile
|
|
BBox3d Bounding ;
|
|
m_ToolOutline.GetLocalBBox( Bounding) ;
|
|
double dHeight = Bounding.GetMax().y - Bounding.GetMin().y ;
|
|
double dRadius = Bounding.GetMax().x - Bounding.GetMin().x ;
|
|
|
|
// Porto i dati del movimento nel riferimento intrinseco
|
|
Point3d ptLs = ptPs ;
|
|
ptLs.ToLoc( m_LocalFrame) ;
|
|
Point3d ptLe = ptPe ;
|
|
ptLe.ToLoc( m_LocalFrame) ;
|
|
Vector3d vtLs = vtDs ;
|
|
vtLs.ToLoc( m_LocalFrame) ;
|
|
Vector3d vtLe = vtDe ;
|
|
vtLe.ToLoc( m_LocalFrame) ;
|
|
|
|
// Direzione utensile costante e come asse Z dello Zmap
|
|
if ( AreSameVectorApprox( vtLs, vtLe) && vtLs.IsZplus()) {
|
|
// Movimento diretto come direzione utensile
|
|
if ( AreSamePointXYApprox( ptLs, ptLe))
|
|
return MillingDrill(ptLs, ptLe, dHeight, dRadius) ;
|
|
// Movimento perpendicolare a direzione utensile
|
|
else if ( abs( ptLe.z - ptLs.z) < EPS_SMALL)
|
|
return MillingPerp(ptLs, ptLe, dHeight, dRadius) ;
|
|
// Movimento generico (per ora non gestito)
|
|
else
|
|
return false ;
|
|
}
|
|
// Altri casi, non gestiti
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingDrill( const Point3d& ptLs, const Point3d& ptLe, double dHeight, double dRadius)
|
|
{
|
|
// Bounding box
|
|
double dMinX = min( ptLs.x, ptLe.x) - dRadius ;
|
|
double dMinY = min( ptLs.y, ptLe.y) - dRadius ;
|
|
double dMaxX = max( ptLs.x, ptLe.x) + dRadius ;
|
|
double dMaxY = max( ptLs.y, ptLe.y) + dRadius ;
|
|
|
|
// Verifico interferisca con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
|
|
// Determino i limiti sugli indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
// Determino quote estreme del tagliente
|
|
double dMax = ptLs.z - dHeight ;
|
|
double dMin = ptLe.z - dHeight ;
|
|
|
|
// Limite sul quadrato del raggio
|
|
double dSqRad = ( dRadius + EPS_SMALL) * ( dRadius + EPS_SMALL) ;
|
|
|
|
// Ciclo sui punti nei limiti
|
|
for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) {
|
|
double dX = ( i + 0.5) * m_dStep ;
|
|
for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
double dY = ( j + 0.5) * m_dStep ;
|
|
// punto
|
|
Point3d ptQ( dX, dY, 0) ;
|
|
// determino il quadrato della distanza
|
|
double dSqDist = SqDistXY( ptQ, ptLe) ;
|
|
// se distanza nei limiti, taglio
|
|
if ( dSqDist < dSqRad)
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::MillingPerp( Point3d& ptLs, Point3d& ptLe, double dHeight, double dRadius)
|
|
{
|
|
// Bounding box
|
|
double dMinX = min( ptLs.x, ptLe.x) - dRadius ;
|
|
double dMinY = min( ptLs.y, ptLe.y) - dRadius ;
|
|
double dMaxX = max( ptLs.x, ptLe.x) + dRadius ;
|
|
double dMaxY = max( ptLs.y, ptLe.y) + dRadius ;
|
|
|
|
// Verifico interferisca con lo Zmap
|
|
if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL)
|
|
return true ;
|
|
|
|
// Determino i limiti sugli indici
|
|
unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinX / m_dStep)) ;
|
|
unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast <unsigned int> ( dMaxX / m_dStep)) ;
|
|
unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast <unsigned int> ( dMinY / m_dStep)) ;
|
|
unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast <unsigned int> ( dMaxY / m_dStep)) ;
|
|
|
|
// Determino quote estreme del tagliente
|
|
double dMax = ptLs.z ;
|
|
double dMin = ptLs.z - dHeight ; // Questa andrà eliminata in futuro oppure la teniamo e la usiamo al bisogno
|
|
|
|
// Limite sul quadrato del raggio
|
|
double dSqRad = ( dRadius + EPS_SMALL) * ( dRadius + EPS_SMALL) ;
|
|
|
|
// Segmento di movimento (nel piano griglia)
|
|
Point3d ptStart( ptLs.x, ptLs.y, 0) ;
|
|
Point3d ptEnd( ptLe.x, ptLe.y, 0) ;
|
|
double dLen ;
|
|
Vector3d vtDir ;
|
|
DirDist( ptStart, ptEnd, vtDir, dLen) ;
|
|
|
|
// Ciclo sui punti nei limiti
|
|
for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) {
|
|
double dX = ( i + 0.5) * m_dStep ;
|
|
for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
double dY = ( j + 0.5) * m_dStep ;
|
|
// punto
|
|
Point3d ptQ( dX, dY, 0) ;
|
|
// determino il quadrato della distanza del punto dal segmento
|
|
double dProiez = vtDir * ( ptQ - ptStart) ;
|
|
if ( dProiez < 0)
|
|
dProiez = 0 ;
|
|
else if ( dProiez > dLen)
|
|
dProiez = dLen ;
|
|
Point3d ptMinDist = ptStart + vtDir * dProiez ;
|
|
double dSqDist = SqDistXY( ptQ, ptMinDist) ;
|
|
// se distanza nei limiti, taglio
|
|
if ( dSqDist < dSqRad)
|
|
SubtractIntervals( i, j, dMin, dMax) ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|