EgtGeomKernel 1.5g2 :
- aggiunte intersezioni tra linee ed archi - aggiunte intersezioni tra archi e archi - aggiunte funzioni di utilità per angoli.
This commit is contained in:
@@ -0,0 +1,534 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2014
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersArcArc.cpp Data : 10.07.14 Versione : 1.5g2
|
||||
// Contenuto : Implementazione della classe intersezione arco/arco.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 10.07.14 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "IntersArcArc.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
IntersArcArc::IntersArcArc( const ICurveArc& Arc1, const ICurveArc& Arc2)
|
||||
{
|
||||
// Le intersezioni sono calcolate nel piano XY locale.
|
||||
|
||||
// nessuna intersezione trovata
|
||||
m_bOverlaps = false ;
|
||||
m_nNumInters = 0 ;
|
||||
|
||||
// verifico validità archi
|
||||
if ( ! Arc1.IsValid() || ! Arc2.IsValid())
|
||||
return ;
|
||||
// verifico che l'angolo al centro non superi il giro
|
||||
if ( fabs( Arc1.GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO ||
|
||||
fabs( Arc2.GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO)
|
||||
return ;
|
||||
// ne faccio una copia
|
||||
m_Arc1.CopyFrom( &Arc1) ;
|
||||
m_Arc2.CopyFrom( &Arc2) ;
|
||||
// gli archi devono avere il piano coincidente con XY
|
||||
if ( ! m_Arc1.GetNormVersor().IsZplus() && ! m_Arc1.GetNormVersor().IsZminus())
|
||||
return ;
|
||||
if ( ! m_Arc2.GetNormVersor().IsZplus() && ! m_Arc2.GetNormVersor().IsZminus())
|
||||
return ;
|
||||
// !!! Gestire gli archi proiettati come ellissi
|
||||
|
||||
// verifico sovrapposizione box
|
||||
BBox3d boxArc1 ;
|
||||
if ( ! m_Arc1.GetLocalBBox( boxArc1))
|
||||
return ;
|
||||
BBox3d boxArc2 ;
|
||||
if ( ! m_Arc2.GetLocalBBox( boxArc2))
|
||||
return ;
|
||||
if ( ! boxArc1.OverlapsXY( boxArc2))
|
||||
return ;
|
||||
|
||||
// versore e distanza tra i centri
|
||||
Vector3d vtDir = ( m_Arc2.GetCenter() - m_Arc1.GetCenter()) ;
|
||||
vtDir.z = 0 ;
|
||||
double dDist = vtDir.LenXY() ;
|
||||
vtDir /= dDist ;
|
||||
|
||||
// cerchi esterni -> nessuna intersezione
|
||||
if ( dDist > m_Arc1.GetRadius() + m_Arc2.GetRadius() + EPS_SMALL)
|
||||
return ;
|
||||
|
||||
// cerchi interni -> nessuna intersezione
|
||||
if ( dDist < fabs( m_Arc1.GetRadius() - m_Arc2.GetRadius()) - EPS_SMALL)
|
||||
return ;
|
||||
|
||||
// cerchi coincidenti -> sovrapposizioni e/o intersezioni agli estremi
|
||||
if ( dDist < EPS_SMALL && fabs( m_Arc1.GetRadius() - m_Arc2.GetRadius()) < EPS_SMALL) {
|
||||
// coefficiente da parametro dell'arco 1 a lunghezza
|
||||
double dU2L = fabs( m_Arc1.GetAngCenter()) * DEGTORAD * m_Arc1.GetRadius() ;
|
||||
// determino se sono equiversi o controversi
|
||||
bool bEqVers = (( m_Arc1.GetAngCenter() * m_Arc1.GetNormVersor().z *
|
||||
m_Arc2.GetAngCenter() * m_Arc2.GetNormVersor().z) > 0) ;
|
||||
// calcolo degli estremi degli archi
|
||||
Point3d ptS1, ptE1 ;
|
||||
if ( ! m_Arc1.GetStartPoint( ptS1) || ! m_Arc1.GetEndPoint( ptE1))
|
||||
return ;
|
||||
Point3d ptS2, ptE2 ;
|
||||
if ( ! m_Arc2.GetStartPoint( ptS2) || ! m_Arc2.GetEndPoint( ptE2))
|
||||
return ;
|
||||
// calcolo del parametro di inizio dell'arco 2 nel riferimento dell'arco 1
|
||||
double dUS2 ;
|
||||
int nPosS2 ;
|
||||
if ( ! m_Arc1.CalcPointParamPosiz( ptS2, dUS2, nPosS2))
|
||||
return ;
|
||||
// calcolo dell'ampiezza parametrica dell'arco 2 nel riferimento dell'arco 1
|
||||
double dDeltaU2 = fabs( m_Arc2.GetAngCenter() / m_Arc1.GetAngCenter()) * ( bEqVers ? 1 : -1) ;
|
||||
// calcolo dell'ampiezza parametrica di un giro nel riferimento dell'arco 1
|
||||
double dTurnU = fabs( ANG_FULL / m_Arc1.GetAngCenter()) ;
|
||||
// determinazione del minimo e massimo parametro dell'arco 2 nel riferimento dell'arco 1
|
||||
double dU2min = dUS2 ;
|
||||
double dU2max = dUS2 + dDeltaU2 ;
|
||||
if ( dU2min > dU2max)
|
||||
swap( dU2min, dU2max) ;
|
||||
// se il minimo è negativo, aggiungo un giro
|
||||
if ( dU2min * dU2L < - EPS_SMALL) {
|
||||
dU2min += dTurnU ;
|
||||
dU2max += dTurnU ;
|
||||
}
|
||||
// se il minimo di 2 coincide con il massimo di 1 nel primo giro -> un punto estremo
|
||||
if ( fabs( 1 - dU2min) * dU2L < EPS_SMALL) {
|
||||
m_Info[0].IciA[0].dU = 1 ;
|
||||
m_Info[0].IciB[0].dU = ( bEqVers ? 0 : 1) ;
|
||||
m_Info[0].IciA[0].ptI = ptE1 ;
|
||||
m_Info[0].IciB[0].ptI = ( bEqVers ? ptS2 : ptE2) ;
|
||||
m_Info[0].IciA[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info[0].IciA[0].nNextTy = ICCT_NULL ;
|
||||
m_Info[0].IciB[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info[0].IciB[0].nNextTy = ICCT_NULL ;
|
||||
m_Info[0].bOverlap = false ;
|
||||
m_nNumInters = 1 ;
|
||||
}
|
||||
// se invece è minore -> una sovrapposizione
|
||||
else if ( dU2min < 1) {
|
||||
// inizio dell'intervallo
|
||||
m_Info[0].IciA[0].dU = dU2min ;
|
||||
m_Info[0].IciB[0].dU = ( bEqVers ? 0 : 1) ;
|
||||
m_Arc1.GetPointD1D2( m_Info[0].IciA[0].dU, ICurve::FROM_MINUS, m_Info[0].IciA[0].ptI) ;
|
||||
m_Info[0].IciB[0].ptI = ( bEqVers ? ptS2 : ptE2) ;
|
||||
m_Info[0].IciA[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info[0].IciA[0].nNextTy = ICCT_ON ;
|
||||
if ( bEqVers) {
|
||||
m_Info[0].IciB[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info[0].IciB[0].nNextTy = ICCT_ON ;
|
||||
}
|
||||
else {
|
||||
m_Info[0].IciB[0].nPrevTy = ICCT_ON ;
|
||||
m_Info[0].IciB[0].nNextTy = ICCT_NULL ;
|
||||
}
|
||||
// fine dell'intervallo
|
||||
if ( dU2max < 1) {
|
||||
m_Info[0].IciA[1].dU = dU2max ;
|
||||
m_Info[0].IciB[1].dU = ( bEqVers ? 1 : 0) ;
|
||||
}
|
||||
else {
|
||||
m_Info[0].IciA[1].dU = 1 ;
|
||||
int nPos ;
|
||||
m_Arc2.CalcPointParamPosiz( ptE1, m_Info[0].IciB[1].dU, nPos) ;
|
||||
}
|
||||
m_Arc1.GetPointD1D2( m_Info[0].IciA[1].dU, ICurve::FROM_MINUS, m_Info[0].IciA[1].ptI) ;
|
||||
m_Arc2.GetPointD1D2( m_Info[0].IciB[1].dU, ICurve::FROM_MINUS, m_Info[0].IciB[1].ptI) ;
|
||||
m_Info[0].IciA[1].nPrevTy = ICCT_ON ;
|
||||
m_Info[0].IciA[1].nNextTy = ICCT_NULL ;
|
||||
if ( bEqVers) {
|
||||
m_Info[0].IciB[1].nPrevTy = ICCT_ON ;
|
||||
m_Info[0].IciB[1].nNextTy = ICCT_NULL ;
|
||||
}
|
||||
else {
|
||||
m_Info[0].IciB[1].nPrevTy = ICCT_NULL ;
|
||||
m_Info[0].IciB[1].nNextTy = ICCT_ON ;
|
||||
}
|
||||
// dati generali
|
||||
m_Info[0].bOverlap = true ;
|
||||
m_Info[0].bCBOverEq = bEqVers ;
|
||||
m_bOverlaps = true ;
|
||||
m_nNumInters = 1 ;
|
||||
}
|
||||
// se il massimo di 2 coincide con il minimo di 1 nel secondo giro e 1 non completo -> un punto estremo
|
||||
if ( fabs( dTurnU - dU2max) * dU2L < EPS_SMALL && dTurnU < 1 - EPS_PARAM) {
|
||||
m_Info[m_nNumInters].IciA[0].dU = 0 ;
|
||||
m_Info[m_nNumInters].IciB[0].dU = ( bEqVers ? 1 : 0) ;
|
||||
m_Info[m_nNumInters].IciA[0].ptI = ptS1 ;
|
||||
m_Info[m_nNumInters].IciB[0].ptI = ( bEqVers ? ptE2 : ptS2) ;
|
||||
m_Info[m_nNumInters].IciA[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info[m_nNumInters].IciA[0].nNextTy = ICCT_NULL ;
|
||||
m_Info[m_nNumInters].IciB[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info[m_nNumInters].IciB[0].nNextTy = ICCT_NULL ;
|
||||
m_Info[m_nNumInters].bOverlap = false ;
|
||||
++ m_nNumInters ;
|
||||
}
|
||||
// se invece è maggiore -> una sovrapposizione
|
||||
else if ( dU2max > dTurnU) {
|
||||
// inizio dell'intervallo
|
||||
m_Info[m_nNumInters].IciA[0].dU = 0 ;
|
||||
int nPos ;
|
||||
m_Arc2.CalcPointParamPosiz( ptS1, m_Info[m_nNumInters].IciB[0].dU, nPos) ;
|
||||
m_Info[m_nNumInters].IciA[0].ptI = ptS1 ;
|
||||
m_Arc2.GetPointD1D2( m_Info[m_nNumInters].IciB[0].dU, ICurve::FROM_MINUS, m_Info[m_nNumInters].IciB[0].ptI) ;
|
||||
m_Info[m_nNumInters].IciA[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info[m_nNumInters].IciA[0].nNextTy = ICCT_ON ;
|
||||
if ( bEqVers) {
|
||||
m_Info[m_nNumInters].IciB[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info[m_nNumInters].IciB[0].nNextTy = ICCT_ON ;
|
||||
}
|
||||
else {
|
||||
m_Info[m_nNumInters].IciB[0].nPrevTy = ICCT_ON ;
|
||||
m_Info[m_nNumInters].IciB[0].nNextTy = ICCT_NULL ;
|
||||
}
|
||||
// fine dell'intervallo
|
||||
if ( dU2max - dTurnU < 1) {
|
||||
m_Info[m_nNumInters].IciA[1].dU = dU2max - dTurnU ;
|
||||
m_Info[m_nNumInters].IciB[1].dU = ( bEqVers ? 1 : 0) ;
|
||||
}
|
||||
else {
|
||||
m_Info[m_nNumInters].IciA[1].dU = 1 ;
|
||||
int nPos ;
|
||||
m_Arc2.CalcPointParamPosiz( ptE1, m_Info[m_nNumInters].IciB[1].dU, nPos) ;
|
||||
}
|
||||
m_Arc1.GetPointD1D2( m_Info[m_nNumInters].IciA[1].dU, ICurve::FROM_MINUS, m_Info[m_nNumInters].IciA[1].ptI) ;
|
||||
m_Arc2.GetPointD1D2( m_Info[m_nNumInters].IciB[1].dU, ICurve::FROM_MINUS, m_Info[m_nNumInters].IciB[1].ptI) ;
|
||||
m_Info[m_nNumInters].IciA[1].nPrevTy = ICCT_ON ;
|
||||
m_Info[m_nNumInters].IciA[1].nNextTy = ICCT_NULL ;
|
||||
if ( bEqVers) {
|
||||
m_Info[m_nNumInters].IciB[1].nPrevTy = ICCT_ON ;
|
||||
m_Info[m_nNumInters].IciB[1].nNextTy = ICCT_NULL ;
|
||||
}
|
||||
else {
|
||||
m_Info[m_nNumInters].IciB[1].nPrevTy = ICCT_NULL ;
|
||||
m_Info[m_nNumInters].IciB[1].nNextTy = ICCT_ON ;
|
||||
}
|
||||
// dati generali
|
||||
m_Info[m_nNumInters].bOverlap = true ;
|
||||
m_Info[m_nNumInters].bCBOverEq = bEqVers ;
|
||||
m_bOverlaps = true ;
|
||||
++ m_nNumInters ;
|
||||
}
|
||||
// se due intersezioni, le ordino in senso crescente del parametro U della prima curva
|
||||
if ( m_nNumInters == 2) {
|
||||
if ( m_Info[0].IciA[0].dU > m_Info[1].IciA[0].dU)
|
||||
swap( m_Info[0], m_Info[1]) ;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
// cerchi tangenti esterni -> una intersezione
|
||||
if ( fabs( dDist - ( m_Arc1.GetRadius() + m_Arc2.GetRadius())) < EPS_SMALL) {
|
||||
// calcolo il punto di intersezione
|
||||
Point3d ptInt = m_Arc1.GetCenter() + vtDir * m_Arc1.GetRadius() ;
|
||||
// posizione parametrica dell'intersezione sul primo arco
|
||||
int nPos1 ;
|
||||
if ( ! m_Arc1.CalcPointParamPosiz( ptInt, m_Info[0].IciA[0].dU, nPos1))
|
||||
return ;
|
||||
// posizione parametrica dell'intersezione sul secondo arco
|
||||
int nPos2 ;
|
||||
if ( ! m_Arc2.CalcPointParamPosiz( ptInt, m_Info[0].IciB[0].dU, nPos2))
|
||||
return ;
|
||||
// se soluzione non accettata, esco
|
||||
if ( nPos1 == ICurve::PP_NULL || nPos2 == ICurve::PP_NULL)
|
||||
return ;
|
||||
// calcolo i punti sui due archi (possono differire in Z)
|
||||
m_Arc1.GetPointD1D2( m_Info[0].IciA[0].dU, ICurve::FROM_MINUS, m_Info[0].IciA[0].ptI) ;
|
||||
m_Arc2.GetPointD1D2( m_Info[0].IciB[0].dU, ICurve::FROM_MINUS, m_Info[0].IciB[0].ptI) ;
|
||||
// calcolo dati ausiliari
|
||||
bool bCCW1 = (( m_Arc1.GetAngCenter() > 0 && m_Arc1.GetNormVersor().IsZplus()) ||
|
||||
( m_Arc1.GetAngCenter() < 0 && m_Arc1.GetNormVersor().IsZminus())) ;
|
||||
bool bCCW2 = (( m_Arc2.GetAngCenter() > 0 && m_Arc2.GetNormVersor().IsZplus()) ||
|
||||
( m_Arc2.GetAngCenter() < 0 && m_Arc2.GetNormVersor().IsZminus())) ;
|
||||
// calcolo tipo di intersezione
|
||||
m_Info[0].IciA[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info[0].IciA[0].nNextTy = ICCT_NULL ;
|
||||
m_Info[0].IciB[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info[0].IciB[0].nNextTy = ICCT_NULL ;
|
||||
// si incontrano alle estremità, non si può dire alcunché
|
||||
if ( ( nPos1 == ICurve::PP_START || nPos1 == ICurve::PP_END) &&
|
||||
( nPos2 == ICurve::PP_START || nPos2 == ICurve::PP_END)) {
|
||||
; // rimangono tutti NULL
|
||||
}
|
||||
// l'inizio di 1 interseca il mezzo di 2
|
||||
else if ( nPos1 == ICurve::PP_START) {
|
||||
if ( bCCW2)
|
||||
m_Info[0].IciA[0].nNextTy = ICCT_OUT ; // NULL + OUT
|
||||
else
|
||||
m_Info[0].IciA[0].nNextTy = ICCT_IN ; // NULL + IN
|
||||
// curva 2 NULL + NULL
|
||||
}
|
||||
// la fine di 1 interseca il mezzo di 2
|
||||
else if ( nPos1 == ICurve::PP_END) {
|
||||
if ( bCCW2)
|
||||
m_Info[0].IciA[0].nPrevTy = ICCT_OUT ; // OUT + NULL
|
||||
else
|
||||
m_Info[0].IciA[0].nPrevTy = ICCT_IN ; // IN + NULL
|
||||
// curva 2 NULL + NULL
|
||||
}
|
||||
// l'inizio di 2 interseca il mezzo di 1
|
||||
else if ( nPos2 == ICurve::PP_START) {
|
||||
// curva 1 NULL + NULL
|
||||
if ( bCCW1)
|
||||
m_Info[0].IciB[0].nNextTy = ICCT_OUT ; // NULL + OUT
|
||||
else
|
||||
m_Info[0].IciB[0].nNextTy = ICCT_IN ; // NULL + IN
|
||||
}
|
||||
// la fine di 2 interseca il mezzo di 1
|
||||
else if ( nPos2 == ICurve::PP_END) {
|
||||
// curva 1 NULL + NULL
|
||||
if ( bCCW1)
|
||||
m_Info[0].IciB[0].nPrevTy = ICCT_OUT ; // OUT + NULL
|
||||
else
|
||||
m_Info[0].IciB[0].nPrevTy = ICCT_IN ; // IN + NULL
|
||||
}
|
||||
// si intersecano nel mezzo
|
||||
else {
|
||||
if ( bCCW2) {
|
||||
m_Info[0].IciA[0].nPrevTy = ICCT_OUT ; // OUT + OUT
|
||||
m_Info[0].IciA[0].nNextTy = ICCT_OUT ;
|
||||
}
|
||||
else {
|
||||
m_Info[0].IciA[0].nPrevTy = ICCT_IN ; // IN + IN
|
||||
m_Info[0].IciA[0].nNextTy = ICCT_IN ;
|
||||
}
|
||||
if ( bCCW1) {
|
||||
m_Info[0].IciB[0].nPrevTy = ICCT_OUT ; // OUT + OUT
|
||||
m_Info[0].IciB[0].nNextTy = ICCT_OUT ;
|
||||
}
|
||||
else {
|
||||
m_Info[0].IciB[0].nPrevTy = ICCT_IN ; // IN + IN
|
||||
m_Info[0].IciB[0].nNextTy = ICCT_IN ;
|
||||
}
|
||||
}
|
||||
// aggiorno dati generali di intersezione
|
||||
m_Info[0].bOverlap = false ;
|
||||
m_nNumInters = 1 ;
|
||||
return ;
|
||||
}
|
||||
|
||||
// cerchi tangenti interni -> una intersezione
|
||||
if ( fabs( dDist - fabs( m_Arc1.GetRadius() - m_Arc2.GetRadius())) < EPS_SMALL) {
|
||||
// determino quale dei due contiene l'altro
|
||||
bool bBiggest1 = ( m_Arc1.GetRadius() > m_Arc2.GetRadius()) ;
|
||||
// calcolo il punto di intersezione
|
||||
Point3d ptInt = m_Arc1.GetCenter() + ( bBiggest1 ? vtDir : - vtDir) * m_Arc1.GetRadius() ;
|
||||
// posizione parametrica dell'intersezione sul primo arco
|
||||
int nPos1 ;
|
||||
if ( ! m_Arc1.CalcPointParamPosiz( ptInt, m_Info[0].IciA[0].dU, nPos1))
|
||||
return ;
|
||||
// posizione parametrica dell'intersezione sul secondo arco
|
||||
int nPos2 ;
|
||||
if ( ! m_Arc2.CalcPointParamPosiz( ptInt, m_Info[0].IciB[0].dU, nPos2))
|
||||
return ;
|
||||
// se soluzione non accettata, esco
|
||||
if ( nPos1 == ICurve::PP_NULL || nPos2 == ICurve::PP_NULL)
|
||||
return ;
|
||||
// calcolo i punti sui due archi (possono differire in Z)
|
||||
m_Arc1.GetPointD1D2( m_Info[0].IciA[0].dU, ICurve::FROM_MINUS, m_Info[0].IciA[0].ptI) ;
|
||||
m_Arc2.GetPointD1D2( m_Info[0].IciB[0].dU, ICurve::FROM_MINUS, m_Info[0].IciB[0].ptI) ;
|
||||
// calcolo dati ausiliari
|
||||
bool bCCW1 = (( m_Arc1.GetAngCenter() > 0 && m_Arc1.GetNormVersor().IsZplus()) ||
|
||||
( m_Arc1.GetAngCenter() < 0 && m_Arc1.GetNormVersor().IsZminus())) ;
|
||||
bool bCCW2 = (( m_Arc2.GetAngCenter() > 0 && m_Arc2.GetNormVersor().IsZplus()) ||
|
||||
( m_Arc2.GetAngCenter() < 0 && m_Arc2.GetNormVersor().IsZminus())) ;
|
||||
// calcolo tipo di intersezione
|
||||
m_Info[0].IciA[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info[0].IciA[0].nNextTy = ICCT_NULL ;
|
||||
m_Info[0].IciB[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info[0].IciB[0].nNextTy = ICCT_NULL ;
|
||||
// si incontrano alle estremità, non si può dire alcunché
|
||||
if ( ( nPos1 == ICurve::PP_START || nPos1 == ICurve::PP_END) &&
|
||||
( nPos2 == ICurve::PP_START || nPos2 == ICurve::PP_END)) {
|
||||
; // rimangono tutti NULL
|
||||
}
|
||||
// l'inizio di 1 interseca il mezzo di 2
|
||||
else if ( nPos1 == ICurve::PP_START) {
|
||||
if ( ( bBiggest1 && bCCW2) || ( ! bBiggest1 && ! bCCW2))
|
||||
m_Info[0].IciA[0].nNextTy = ICCT_OUT ; // NULL + OUT
|
||||
else
|
||||
m_Info[0].IciA[0].nNextTy = ICCT_IN ; // NULL + IN
|
||||
// curva 2 NULL + NULL
|
||||
}
|
||||
// la fine di 1 interseca il mezzo di 2
|
||||
else if ( nPos1 == ICurve::PP_END) {
|
||||
if ( ( bBiggest1 && bCCW2) || ( ! bBiggest1 && ! bCCW2))
|
||||
m_Info[0].IciA[0].nPrevTy = ICCT_OUT ; // OUT + NULL
|
||||
else
|
||||
m_Info[0].IciA[0].nPrevTy = ICCT_IN ; // IN + NULL
|
||||
// curva 2 NULL + NULL
|
||||
}
|
||||
// l'inizio di 2 interseca il mezzo di 1
|
||||
else if ( nPos2 == ICurve::PP_START) {
|
||||
// curva 1 NULL + NULL
|
||||
if ( ( bBiggest1 && ! bCCW1) || ( ! bBiggest1 && bCCW1))
|
||||
m_Info[0].IciB[0].nNextTy = ICCT_OUT ; // NULL + OUT
|
||||
else
|
||||
m_Info[0].IciB[0].nNextTy = ICCT_IN ; // NULL + IN
|
||||
}
|
||||
// la fine di 2 interseca il mezzo di 1
|
||||
else if ( nPos2 == ICurve::PP_END) {
|
||||
// curva 1 NULL + NULL
|
||||
if ( ( bBiggest1 && ! bCCW1) || ( ! bBiggest1 && bCCW1))
|
||||
m_Info[0].IciB[0].nPrevTy = ICCT_OUT ; // OUT + NULL
|
||||
else
|
||||
m_Info[0].IciB[0].nPrevTy = ICCT_IN ; // IN + NULL
|
||||
}
|
||||
// si intersecano nel mezzo
|
||||
else {
|
||||
if ( ( bBiggest1 && bCCW2) || ( ! bBiggest1 && ! bCCW2)) {
|
||||
m_Info[0].IciA[0].nPrevTy = ICCT_OUT ; // OUT + OUT
|
||||
m_Info[0].IciA[0].nNextTy = ICCT_OUT ;
|
||||
}
|
||||
else {
|
||||
m_Info[0].IciA[0].nPrevTy = ICCT_IN ; // IN + IN
|
||||
m_Info[0].IciA[0].nNextTy = ICCT_IN ;
|
||||
}
|
||||
if ( ( bBiggest1 && ! bCCW1) || ( ! bBiggest1 && bCCW1)) {
|
||||
m_Info[0].IciB[0].nPrevTy = ICCT_OUT ; // OUT + OUT
|
||||
m_Info[0].IciB[0].nNextTy = ICCT_OUT ;
|
||||
}
|
||||
else {
|
||||
m_Info[0].IciB[0].nPrevTy = ICCT_IN ; // IN + IN
|
||||
m_Info[0].IciB[0].nNextTy = ICCT_IN ;
|
||||
}
|
||||
}
|
||||
// aggiorno dati generali di intersezione
|
||||
m_Info[0].bOverlap = false ;
|
||||
m_nNumInters = 1 ;
|
||||
return ;
|
||||
}
|
||||
|
||||
// due intersezioni
|
||||
double dA = ( m_Arc1.GetRadius() * m_Arc1.GetRadius() - m_Arc2.GetRadius() * m_Arc2.GetRadius() +
|
||||
dDist * dDist) / ( 2 * dDist) ;
|
||||
double dH = sqrt( m_Arc1.GetRadius() * m_Arc1.GetRadius() - dA * dA) ;
|
||||
Point3d ptRef = m_Arc1.GetCenter() + dA * vtDir ;
|
||||
Vector3d vtDelta = dH * vtDir ;
|
||||
vtDelta.Rotate( Z_AX, 0, 1) ;
|
||||
int nPos1, nPos2 ;
|
||||
// ---> prima intersezione
|
||||
// determinazione geometrica e topologica dell'intersezione tra le due curve
|
||||
if ( CalcSecIntersGeomData( 0, ptRef + vtDelta, nPos1, nPos2) &&
|
||||
CalcSecIntersTopolData( 0, nPos1, nPos2)) {
|
||||
// aggiorno dati generali di intersezione
|
||||
m_Info[0].bOverlap = false ;
|
||||
++ m_nNumInters ;
|
||||
}
|
||||
// ---> seconda intersezione
|
||||
// determinazione geometrica e topologica dell'intersezione tra le due curve
|
||||
if ( CalcSecIntersGeomData( m_nNumInters, ptRef - vtDelta, nPos1, nPos2) &&
|
||||
CalcSecIntersTopolData( m_nNumInters, nPos1, nPos2)) {
|
||||
// aggiorno dati generali di intersezione
|
||||
m_Info[m_nNumInters].bOverlap = false ;
|
||||
++ m_nNumInters ;
|
||||
}
|
||||
// se due intersezioni, le ordino in senso crescente del parametro U della prima curva
|
||||
if ( m_nNumInters == 2) {
|
||||
if ( m_Info[0].IciA[0].dU > m_Info[1].IciA[0].dU)
|
||||
swap( m_Info[0], m_Info[1]) ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersArcArc::CalcSecIntersGeomData( int nInt, const Point3d& ptInt, int& nPos1, int& nPos2)
|
||||
{
|
||||
// posizione parametrica dell'intersezione sul primo arco
|
||||
if ( ! m_Arc1.CalcPointParamPosiz( ptInt, m_Info[nInt].IciA[0].dU, nPos1))
|
||||
return false ;
|
||||
// posizione parametrica dell'intersezione sul secondo arco
|
||||
if ( ! m_Arc2.CalcPointParamPosiz( ptInt, m_Info[nInt].IciB[0].dU, nPos2))
|
||||
return false ;
|
||||
// se soluzione non accettata, esco
|
||||
if ( nPos1 == ICurve::PP_NULL || nPos2 == ICurve::PP_NULL)
|
||||
return false ;
|
||||
// calcolo i punti sulle due curve (possono differire in Z)
|
||||
m_Arc1.GetPointD1D2( m_Info[nInt].IciA[0].dU, ICurve::FROM_MINUS, m_Info[nInt].IciA[0].ptI) ;
|
||||
m_Arc2.GetPointD1D2( m_Info[nInt].IciB[0].dU, ICurve::FROM_MINUS, m_Info[nInt].IciB[0].ptI) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersArcArc::CalcSecIntersTopolData( int nInt, int nPos1, int nPos2)
|
||||
{
|
||||
// calcolo dati ausiliari
|
||||
Point3d ptInt1, ptInt2 ;
|
||||
Vector3d vtDir1, vtDir2 ;
|
||||
m_Arc1.GetPointD1D2( m_Info[nInt].IciA[0].dU, ICurve::FROM_MINUS, ptInt1, &vtDir1) ;
|
||||
m_Arc2.GetPointD1D2( m_Info[nInt].IciB[0].dU, ICurve::FROM_MINUS, ptInt2, &vtDir2) ;
|
||||
double dCrossXY = CrossXY( vtDir1, vtDir2) ;
|
||||
// calcolo tipo di intersezione
|
||||
m_Info[nInt].IciA[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info[nInt].IciA[0].nNextTy = ICCT_NULL ;
|
||||
m_Info[nInt].IciB[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info[nInt].IciB[0].nNextTy = ICCT_NULL ;
|
||||
// si incontrano alle estremità, non si può dire alcunché
|
||||
if ( ( nPos1 == ICurve::PP_START || nPos1 == ICurve::PP_END) &&
|
||||
( nPos2 == ICurve::PP_START || nPos2 == ICurve::PP_END)) {
|
||||
; // rimangono tutti NULL
|
||||
}
|
||||
// l'inizio di 1 interseca il mezzo di 2
|
||||
else if ( nPos1 == ICurve::PP_START) {
|
||||
if ( dCrossXY > 0)
|
||||
m_Info[nInt].IciA[0].nNextTy = ICCT_OUT ; // NULL + OUT
|
||||
else
|
||||
m_Info[nInt].IciA[0].nNextTy = ICCT_IN ; // NULL + IN
|
||||
// curva 2 NULL + NULL
|
||||
}
|
||||
// la fine di 1 interseca il mezzo di 2
|
||||
else if ( nPos1 == ICurve::PP_END) {
|
||||
if ( dCrossXY < 0)
|
||||
m_Info[nInt].IciA[0].nPrevTy = ICCT_OUT ; // OUT + NULL
|
||||
else
|
||||
m_Info[nInt].IciA[0].nPrevTy = ICCT_IN ; // IN + NULL
|
||||
// curva 2 NULL + NULL
|
||||
}
|
||||
// l'inizio di 2 interseca il mezzo di 1
|
||||
else if ( nPos2 == ICurve::PP_START) {
|
||||
// curva 1 NULL + NULL
|
||||
if ( - dCrossXY > 0)
|
||||
m_Info[nInt].IciB[0].nNextTy = ICCT_OUT ; // NULL + OUT
|
||||
else
|
||||
m_Info[nInt].IciB[0].nNextTy = ICCT_IN ; // NULL + IN
|
||||
}
|
||||
// la fine di 2 interseca il mezzo di 1
|
||||
else if ( nPos2 == ICurve::PP_END) {
|
||||
// curva 1 NULL + NULL
|
||||
if ( - dCrossXY < 0)
|
||||
m_Info[nInt].IciB[0].nPrevTy = ICCT_OUT ; // OUT + NULL
|
||||
else
|
||||
m_Info[nInt].IciB[0].nPrevTy = ICCT_IN ; // IN + NULL
|
||||
}
|
||||
// si intersecano nel mezzo
|
||||
else {
|
||||
if ( CrossXY( ( ( ptInt1 - vtDir1) - ( ptInt2 - vtDir2)), vtDir2) > 0) {
|
||||
m_Info[nInt].IciA[0].nPrevTy = ICCT_OUT ;
|
||||
m_Info[nInt].IciA[0].nNextTy = ICCT_IN ;
|
||||
}
|
||||
else {
|
||||
m_Info[nInt].IciA[0].nPrevTy = ICCT_IN ;
|
||||
m_Info[nInt].IciA[0].nNextTy = ICCT_OUT ;
|
||||
}
|
||||
if ( CrossXY( ( ( ptInt2 - vtDir2) - ( ptInt1 - vtDir1)), vtDir1) > 0) {
|
||||
m_Info[nInt].IciB[0].nPrevTy = ICCT_OUT ;
|
||||
m_Info[nInt].IciB[0].nNextTy = ICCT_IN ;
|
||||
}
|
||||
else {
|
||||
m_Info[nInt].IciB[0].nPrevTy = ICCT_IN ;
|
||||
m_Info[nInt].IciB[0].nNextTy = ICCT_OUT ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
Reference in New Issue
Block a user