15f819fe31
- aggiunta intersezione tra curve composte (e gestione loro topologia) - corretto salvataggio entità testo - aggiunto EPS_SMALL a test su box - aggiunte funzioni di verifica validità e tipo parametro di curve - aggiunto comando TSC OUTTEXTICCI.
505 lines
24 KiB
C++
505 lines
24 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2014-2014
|
|
//----------------------------------------------------------------------------
|
|
// File : IntersCrvCompoCrvCompo.cpp Data : 24.06.14 Versione : 1.5f6
|
|
// Contenuto : Implementazione della classe intersezione curva composita/cc.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 24.06.14 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "IntersCrvCompoCrvCompo.h"
|
|
#include <algorithm>
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
SortGreater( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2)
|
|
{
|
|
double dU1 = ( aInfo1.bOverlap ? 0.5 * ( aInfo1.IciA[0].dU + aInfo1.IciA[1].dU) : aInfo1.IciA[0].dU) ;
|
|
double dU2 = ( aInfo2.bOverlap ? 0.5 * ( aInfo2.IciA[0].dU + aInfo2.IciA[1].dU) : aInfo2.IciA[0].dU) ;
|
|
return ( dU2 > dU1 + EPS_PARAM) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
MediaParamPoints( IntCrvInfo& Ici1, IntCrvInfo& Ici2)
|
|
{
|
|
// medio i parametri e i punti
|
|
// per non mediare i parametri tra gli estremi di curva chiusa
|
|
if ( fabs( Ici1.dU - Ici2.dU) < HSPAN_PARAM) {
|
|
Ici1.dU = 0.5 * ( Ici1.dU + Ici2.dU) ;
|
|
Ici2.dU = Ici1.dU ;
|
|
}
|
|
Ici1.ptI = 0.5 * ( Ici1.ptI + Ici2.ptI) ;
|
|
Ici2.ptI = Ici1.ptI ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Prev della curva B ma tenendo conto della direzione di A
|
|
// => se controverse va preso Next
|
|
int
|
|
GetCrvBDirAPrev( IntCrvCrvInfo& Icci)
|
|
{
|
|
// non è overlap, è il prev del primo punto
|
|
if ( ! Icci.bOverlap)
|
|
return Icci.IciB[0].nPrevTy ;
|
|
// è overlap equiverso, è il prev del primo punto
|
|
if ( Icci.bCBOverEq)
|
|
return Icci.IciB[0].nPrevTy ;
|
|
// è overlap controverso, è il next del primo punto
|
|
return Icci.IciB[0].nNextTy ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Next della curva B ma tenendo conto della direzione di A
|
|
// => se controverse va preso Prev
|
|
int
|
|
GetCrvBDirANext( IntCrvCrvInfo& Icci)
|
|
{
|
|
// non è overlap, è il next del primo punto
|
|
if ( ! Icci.bOverlap)
|
|
return Icci.IciB[0].nNextTy ;
|
|
// è overlap equiverso, è il next del secondo punto
|
|
if ( Icci.bCBOverEq)
|
|
return Icci.IciB[1].nNextTy ;
|
|
// è overlap controverso, è il prev del secondo punto
|
|
return Icci.IciB[1].nPrevTy ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
CalcATypeFromDisk( const ICurveComposite& CCompoA, double dUA, ICurve::Side nSideA,
|
|
const ICurveComposite& CCompoB, double dUB, int& nType)
|
|
{
|
|
// devo studiare un intorno dell'intersezione
|
|
Point3d ptP ;
|
|
// direzione di arrivo (FROM_MINUS) o partenza (FROM_PLUS) curva A
|
|
Vector3d vtADir ;
|
|
if ( ! CCompoA.IsValidParam( dUA, nSideA) ||
|
|
! CCompoA.GetPointTang( dUA, nSideA, ptP, vtADir))
|
|
return false ;
|
|
if ( nSideA == ICurve::FROM_MINUS)
|
|
vtADir *= - 1 ;
|
|
// direzioni di arrivo (prev) e partenza (next) curva B
|
|
Vector3d vtBpDir ;
|
|
if ( ! CCompoB.IsValidParam( dUB, ICurve::FROM_MINUS) ||
|
|
! CCompoB.GetPointTang( dUB, ICurve::FROM_MINUS, ptP, vtBpDir))
|
|
return false ;
|
|
vtBpDir *= - 1 ;
|
|
Vector3d vtBnDir ;
|
|
if ( ! CCompoB.IsValidParam( dUB, ICurve::FROM_PLUS) ||
|
|
! CCompoB.GetPointTang( dUB, ICurve::FROM_PLUS, ptP, vtBnDir))
|
|
return false ;
|
|
// angolo del versore DirA rispetto a DirBn
|
|
double dAngADeg ;
|
|
if ( ! vtBnDir.GetAngleXY( vtADir, dAngADeg))
|
|
return false ;
|
|
if ( dAngADeg < 0)
|
|
dAngADeg += ANG_FULL ;
|
|
// angolo del versore DirBp rispetto a DirBn
|
|
double dAngBpDeg ;
|
|
if ( ! vtBnDir.GetAngleXY( vtBpDir, dAngBpDeg))
|
|
return false ;
|
|
if ( dAngBpDeg < 0)
|
|
dAngBpDeg += ANG_FULL ;
|
|
// se l'angolo di DirA è compreso tra DirBn e DirBp (muovendosi in senso CCW) allora è IN, altrimenti OUT
|
|
if ( dAngADeg > 0 && dAngADeg < dAngBpDeg)
|
|
nType = ICCT_IN ;
|
|
else
|
|
nType = ICCT_OUT ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, const ICurveComposite& CCompoB)
|
|
{
|
|
// Le intersezioni sono calcolate nel piano XY locale.
|
|
|
|
// nessuna intersezione trovata
|
|
m_bOverlaps = false ;
|
|
m_nNumInters = 0 ;
|
|
m_Info.clear() ;
|
|
|
|
// doppio ciclo sulle entità delle curve composite
|
|
// !!! questa parte è O(N^2), vanno usate Grid Gerarchiche o BVH per renderla O(N*logN) !!!
|
|
int nCountA = 0 ;
|
|
for ( const ICurve* pCrvA = CCompoA.GetFirstCurve() ;
|
|
pCrvA != nullptr ;
|
|
pCrvA = CCompoA.GetNextCurve(), ++ nCountA) {
|
|
int nCountB = 0 ;
|
|
for ( const ICurve* pCrvB = CCompoB.GetFirstCurve() ;
|
|
pCrvB != nullptr ;
|
|
pCrvB = CCompoB.GetNextCurve(), ++ nCountB) {
|
|
// eseguo l'intersezione di queste curve elementari
|
|
IntersCurveCurve intCC( *pCrvA, *pCrvB) ;
|
|
// ne recupero i risultati
|
|
int nCurrInters = intCC.GetNumInters() ;
|
|
if ( nCurrInters > 0) {
|
|
m_nNumInters += nCurrInters ;
|
|
m_bOverlaps = ( intCC.GetOverlaps() ? true : m_bOverlaps) ;
|
|
for ( int i = 0 ; i < nCurrInters ; ++ i) {
|
|
IntCrvCrvInfo aInfo ;
|
|
intCC.GetIntCrvCrvInfo( i, aInfo) ;
|
|
aInfo.IciA[0].dU += nCountA ;
|
|
aInfo.IciB[0].dU += nCountB ;
|
|
if ( aInfo.bOverlap) {
|
|
aInfo.IciA[1].dU += nCountA ;
|
|
aInfo.IciB[1].dU += nCountB ;
|
|
}
|
|
m_Info.push_back( aInfo) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ordino le intersezioni secondo l'ordine crescente del parametro della prima curva
|
|
stable_sort( m_Info.begin(), m_Info.end(), SortGreater) ;
|
|
|
|
// sistemazione di intersezioni coincidenti
|
|
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
|
// calcolo indice precedente
|
|
int j = i - 1 ;
|
|
if ( i == 0) {
|
|
// se prima curva aperta, salto alla prossima
|
|
if ( ! CCompoA.IsClosed())
|
|
continue ;
|
|
// è chiusa quindi prendo l'ultima
|
|
j = m_nNumInters - 1 ;
|
|
}
|
|
// se i due indici coincidono, c'è una sola intersezione e posso uscire
|
|
if ( i == j)
|
|
break ;
|
|
// calcolo sottoindici
|
|
int ki = 0 ; // del successivo si prende sempre il primo
|
|
int kj = ( m_Info[j].bOverlap ? 1 : 0) ; // del precedente si prende il secondo se overlap
|
|
// verifico se precedente e corrente si riferiscono alla stessa intersezione (10 * EPS_SMALL)
|
|
if ( SqDist( m_Info[i].IciA[ki].ptI, m_Info[j].IciA[kj].ptI) < ( 100 * EPS_SMALL * EPS_SMALL) &&
|
|
SqDist( m_Info[i].IciB[ki].ptI, m_Info[j].IciB[kj].ptI) < ( 100 * EPS_SMALL * EPS_SMALL)) {
|
|
// caso DET-NULL -> NULL-DET per prima curva
|
|
if ( m_Info[j].IciA[kj].nPrevTy != ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL &&
|
|
m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy != ICCT_NULL) {
|
|
// per la prima curva tengo i determinati
|
|
m_Info[i].IciA[ki].nPrevTy = m_Info[j].IciA[kj].nPrevTy ;
|
|
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
|
|
// se overlap equiverso
|
|
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
|
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
|
m_Info[i].IciB[ki].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
|
m_Info[i].IciB[ki].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
|
|
}
|
|
// se altrimenti overlap controverso
|
|
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
|
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione invertita
|
|
m_Info[i].IciB[ki].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
|
m_Info[i].IciB[ki].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
|
}
|
|
// se overlap equiverso
|
|
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
|
m_Info[j].IciB[kj].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
|
m_Info[j].IciB[kj].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
|
|
}
|
|
// se altrimenti overlap controverso
|
|
else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
|
|
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
|
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
|
}
|
|
// medio parametri e punti separatamente per le due curve
|
|
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ;
|
|
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ;
|
|
// se entrambi overlap non cancello
|
|
if ( m_Info[j].bOverlap && m_Info[i].bOverlap)
|
|
continue ;
|
|
// cancello un singolo
|
|
int k = ( ! m_Info[i].bOverlap ? i : j) ;
|
|
m_Info.erase( m_Info.begin() + k) ;
|
|
-- i ;
|
|
-- m_nNumInters ;
|
|
}
|
|
// caso NULL-DET -> DET-NULL per prima curva (possibile su inizio/fine di curva chiusa)
|
|
else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy != ICCT_NULL &&
|
|
m_Info[i].IciA[ki].nPrevTy != ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
|
// per la prima curva tengo i determinati
|
|
m_Info[i].IciA[ki].nNextTy = m_Info[j].IciA[kj].nNextTy ;
|
|
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[ki].nPrevTy ;
|
|
// se overlap equiverso
|
|
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
|
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
|
m_Info[i].IciB[ki].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
|
m_Info[i].IciB[ki].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
|
|
}
|
|
// se altrimenti overlap controverso
|
|
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
|
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione scambiata
|
|
m_Info[i].IciB[ki].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
|
m_Info[i].IciB[ki].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
|
}
|
|
// se overlap equiverso
|
|
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
|
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
|
m_Info[j].IciB[kj].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
|
m_Info[j].IciB[kj].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
|
|
}
|
|
// se altrimenti overlap controverso
|
|
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
|
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione scambiata
|
|
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
|
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
|
}
|
|
// medio parametri e punti separatamente per le due curve
|
|
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ;
|
|
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ;
|
|
// se entrambi overlap non cancello
|
|
if ( m_Info[j].bOverlap && m_Info[i].bOverlap)
|
|
continue ;
|
|
// cancello un singolo
|
|
int k = ( ! m_Info[i].bOverlap ? i : j) ;
|
|
m_Info.erase( m_Info.begin() + k) ;
|
|
-- i ;
|
|
-- m_nNumInters ;
|
|
}
|
|
// caso DET-NULL -> NULL-DET per seconda curva
|
|
else if ( m_Info[j].IciB[kj].nPrevTy != ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL &&
|
|
m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy != ICCT_NULL) {
|
|
// per la seconda curva tengo i determinati
|
|
m_Info[i].IciB[ki].nPrevTy = m_Info[j].IciB[kj].nPrevTy ;
|
|
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
|
|
// se overlap equiverso
|
|
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
|
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
|
m_Info[i].IciA[ki].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
|
m_Info[i].IciA[ki].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
|
}
|
|
// se altrimenti overlap controverso
|
|
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
|
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
|
m_Info[i].IciA[ki].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
|
m_Info[i].IciA[ki].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
|
}
|
|
// se overlap equiverso
|
|
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
|
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
|
m_Info[j].IciA[kj].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
|
m_Info[j].IciA[kj].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
|
}
|
|
// se altrimenti overlap controverso
|
|
else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
|
|
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
|
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
|
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
|
}
|
|
// medio parametri e punti separatamente per le due curve
|
|
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ;
|
|
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ;
|
|
// se entrambi overlap non cancello
|
|
if ( m_Info[j].bOverlap && m_Info[i].bOverlap)
|
|
continue ;
|
|
// cancello un singolo
|
|
int k = ( ! m_Info[i].bOverlap ? i : j) ;
|
|
m_Info.erase( m_Info.begin() + k) ;
|
|
-- i ;
|
|
-- m_nNumInters ;
|
|
}
|
|
// caso NULL-DET -> DET-NULL per seconda curva (possibile su inizio/fine di curva chiusa)
|
|
else if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy != ICCT_NULL &&
|
|
m_Info[i].IciB[ki].nPrevTy != ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
|
// per la seconda curva tengo i determinati
|
|
m_Info[i].IciB[ki].nNextTy = m_Info[j].IciB[kj].nNextTy ;
|
|
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[ki].nPrevTy ;
|
|
// se overlap equiverso
|
|
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
|
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
|
m_Info[i].IciA[ki].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
|
m_Info[i].IciA[ki].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
|
}
|
|
// se altrimenti overlap controverso
|
|
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
|
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
|
m_Info[i].IciA[ki].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
|
m_Info[i].IciA[ki].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
|
}
|
|
// se overlap equiverso
|
|
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
|
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
|
m_Info[j].IciA[kj].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
|
m_Info[j].IciA[kj].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
|
}
|
|
// se altrimenti overlap controverso
|
|
else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
|
|
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
|
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
|
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
|
}
|
|
// medio parametri e punti separatamente per le due curve
|
|
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ;
|
|
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ;
|
|
// se entrambi overlap non cancello
|
|
if ( m_Info[j].bOverlap && m_Info[i].bOverlap)
|
|
continue ;
|
|
// cancello un singolo
|
|
int k = ( ! m_Info[i].bOverlap ? i : j) ;
|
|
m_Info.erase( m_Info.begin() + k) ;
|
|
-- i ;
|
|
-- m_nNumInters ;
|
|
}
|
|
// caso NULL-NULL per corrente di prima curva
|
|
else if ( m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
|
// cancello l'intersezione corrente (non aggiunge nulla rispetto alla precedente)
|
|
m_Info.erase( m_Info.begin() + i) ;
|
|
-- i ;
|
|
-- m_nNumInters ;
|
|
}
|
|
// caso NULL-NULL per precedente di prima curva
|
|
else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL) {
|
|
// cancello l'intersezione precedente (non aggiunge nulla rispetto alla corrente)
|
|
m_Info.erase( m_Info.begin() + j) ;
|
|
if ( j < i)
|
|
i -= 2 ;
|
|
else
|
|
-- i ;
|
|
-- m_nNumInters ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// verifico se sono rimaste delle intersezioni di tipo non definito e cerco di risolverle
|
|
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
|
// in assenza di overlap
|
|
if ( ! m_Info[i].bOverlap) {
|
|
// se il tipo di accostamento per la curva A non è definito
|
|
if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) {
|
|
// devo studiare un intorno dell'intersezione
|
|
int nType ;
|
|
if ( ! CalcATypeFromDisk( CCompoA, m_Info[i].IciA[0].dU, ICurve::FROM_MINUS,
|
|
CCompoB, m_Info[i].IciB[0].dU, nType))
|
|
continue ;
|
|
// aggiorno il tipo di accostamento della curva A alla curva B
|
|
m_Info[i].IciA[0].nPrevTy = nType ;
|
|
}
|
|
// se il tipo di accostamento per la curva B non è definito
|
|
if ( m_Info[i].IciB[0].nPrevTy == ICCT_NULL) {
|
|
// devo studiare un intorno dell'intersezione
|
|
int nType ;
|
|
if ( ! CalcATypeFromDisk( CCompoB, m_Info[i].IciB[0].dU, ICurve::FROM_MINUS,
|
|
CCompoA, m_Info[i].IciA[0].dU, nType))
|
|
continue ;
|
|
// aggiorno il tipo di accostamento della curva B alla curva A
|
|
m_Info[i].IciB[0].nPrevTy = nType ;
|
|
}
|
|
// se il tipo di allontanamento per la curva A non è definito
|
|
if ( m_Info[i].IciA[0].nNextTy == ICCT_NULL) {
|
|
// devo studiare un intorno dell'intersezione
|
|
int nType ;
|
|
if ( ! CalcATypeFromDisk( CCompoA, m_Info[i].IciA[0].dU, ICurve::FROM_PLUS,
|
|
CCompoB, m_Info[i].IciB[0].dU, nType))
|
|
continue ;
|
|
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
|
m_Info[i].IciA[0].nNextTy = nType ;
|
|
}
|
|
// se il tipo di allontanamento per la curva B non è definito
|
|
if ( m_Info[i].IciB[0].nNextTy == ICCT_NULL) {
|
|
// devo studiare un intorno dell'intersezione
|
|
int nType ;
|
|
if ( ! CalcATypeFromDisk( CCompoB, m_Info[i].IciB[0].dU, ICurve::FROM_PLUS,
|
|
CCompoA, m_Info[i].IciA[0].dU, nType))
|
|
continue ;
|
|
// aggiorno il tipo di allontanamento della curva B dalla curva A
|
|
m_Info[i].IciB[0].nNextTy = nType ;
|
|
}
|
|
}
|
|
// in presenza di overlap
|
|
else {
|
|
// se il tipo di accostamento è non definito per la curva A
|
|
if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) {
|
|
// devo studiare un intorno dell'intersezione
|
|
int nType ;
|
|
if ( ! CalcATypeFromDisk( CCompoA, m_Info[i].IciA[0].dU, ICurve::FROM_MINUS,
|
|
CCompoB, m_Info[i].IciB[0].dU, nType))
|
|
continue ;
|
|
// aggiorno il tipo di accostamento della curva A alla curva B
|
|
m_Info[i].IciA[0].nPrevTy = nType ;
|
|
// aggiorno anche il corrispondente tipo sulla curva B
|
|
if ( m_Info[i].bCBOverEq)
|
|
m_Info[i].IciB[0].nPrevTy = GetDualIcct( nType) ;
|
|
else
|
|
m_Info[i].IciB[0].nNextTy = nType ;
|
|
}
|
|
// se il tipo di allontanamento è non definito per la curva A
|
|
if ( m_Info[i].IciA[1].nNextTy == ICCT_NULL) {
|
|
// devo studiare un intorno dell'intersezione
|
|
int nType ;
|
|
if ( ! CalcATypeFromDisk( CCompoA, m_Info[i].IciA[1].dU, ICurve::FROM_PLUS,
|
|
CCompoB, m_Info[i].IciB[1].dU, nType))
|
|
continue ;
|
|
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
|
m_Info[i].IciA[1].nNextTy = nType ;
|
|
// aggiorno anche il corrispondente tipo sulla curva B
|
|
if ( m_Info[i].bCBOverEq)
|
|
m_Info[i].IciB[1].nNextTy = GetDualIcct( nType) ;
|
|
else
|
|
m_Info[i].IciB[1].nPrevTy = nType ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// verifico se due intersezioni consecutive di tipo overlap si possono ridurre a una sola
|
|
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
|
// calcolo indice precedente
|
|
int j = i - 1 ;
|
|
if ( i == 0) {
|
|
// se prima curva aperta, salto alla prossima
|
|
if ( ! CCompoA.IsClosed())
|
|
continue ;
|
|
// è chiusa quindi prendo l'ultima
|
|
j = m_nNumInters - 1 ;
|
|
}
|
|
// se i due indici coincidono, c'è una sola intersezione e posso uscire
|
|
if ( i == j)
|
|
break ;
|
|
// assegno sottoindici (considero solo intersezioni overlap)
|
|
int ki = 0 ;
|
|
int kj = 1 ;
|
|
// verifico se entrambe overlap, la precedente termina con ON e la successiva inizia con ON
|
|
// sia sulla curva A sia sulla curva B (tenendo conto del senso equiverso/controverso)
|
|
if ( m_Info[j].bOverlap && m_Info[i].bOverlap &&
|
|
m_Info[j].IciA[kj].nNextTy == ICCT_ON && m_Info[i].IciA[ki].nPrevTy == ICCT_ON &&
|
|
GetCrvBDirANext( m_Info[j]) == ICCT_ON && GetCrvBDirAPrev( m_Info[i]) == ICCT_ON) {
|
|
// CurvaA : riporto il secondo punto del successivo sul secondo punto del precedente
|
|
m_Info[j].IciA[kj].dU = m_Info[i].IciA[kj].dU ;
|
|
m_Info[j].IciA[kj].ptI = m_Info[i].IciA[kj].ptI ;
|
|
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[kj].nPrevTy ;
|
|
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[kj].nNextTy ;
|
|
// CurvaB : riporto il secondo punto del successivo sul secondo punto del precedente
|
|
m_Info[j].IciB[kj].dU = m_Info[i].IciB[kj].dU ;
|
|
m_Info[j].IciB[kj].ptI = m_Info[i].IciB[kj].ptI ;
|
|
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[kj].nPrevTy ;
|
|
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[kj].nNextTy ;
|
|
// cancello il successivo
|
|
m_Info.erase( m_Info.begin() + i) ;
|
|
-- i ;
|
|
-- m_nNumInters ;
|
|
}
|
|
}
|
|
|
|
// se è rimasta una sola intersezione con overlap anche ad entrambi gli estremi e le curve sono chiuse
|
|
if ( m_nNumInters == 1 && CCompoA.IsClosed() && CCompoB.IsClosed() &&
|
|
m_Info[0].IciA[0].nPrevTy == ICCT_ON && m_Info[0].IciA[1].nNextTy == ICCT_ON &&
|
|
GetCrvBDirANext( m_Info[0]) == ICCT_ON && GetCrvBDirAPrev( m_Info[0]) == ICCT_ON) {
|
|
// questa intersezione con overlap deve interessare completamente le due curve
|
|
double dStart, dEnd ;
|
|
CCompoA.GetDomain( dStart, dEnd) ;
|
|
m_Info[0].IciA[0].dU = dStart ;
|
|
m_Info[0].IciA[1].dU = dEnd ;
|
|
CCompoB.GetDomain( dStart, dEnd) ;
|
|
m_Info[0].IciB[0].dU = ( m_Info[0].bCBOverEq ? dStart : dEnd) ;
|
|
m_Info[0].IciB[1].dU = ( m_Info[0].bCBOverEq ? dEnd : dStart) ;
|
|
}
|
|
|
|
}
|