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,273 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2014
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineArc.cpp Data : 07.07.14 Versione : 1.5g2
|
||||
// Contenuto : Implementazione della classe intersezione linea/arco.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 07.07.14 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "IntersLineArc.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
IntersLineArc::IntersLineArc( const ICurveLine& Line, const ICurveArc& Arc)
|
||||
{
|
||||
// Le intersezioni sono calcolate nel piano XY locale.
|
||||
|
||||
// nessuna intersezione trovata
|
||||
m_nNumInters = 0 ;
|
||||
|
||||
// verifico validità linea e arco
|
||||
if ( ! Line.IsValid() || ! Arc.IsValid())
|
||||
return ;
|
||||
// l'arco deve avere il piano coincidente con XY
|
||||
if ( ! Arc.GetNormVersor().IsZplus() && ! Arc.GetNormVersor().IsZminus())
|
||||
return ;
|
||||
// verifico che l'angolo al centro non superi il giro
|
||||
if ( fabs( Arc.GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO)
|
||||
return ;
|
||||
// !!! Gestire l'arco proiettato come ellisse
|
||||
|
||||
// verifico sovrapposizione box
|
||||
BBox3d boxLine ;
|
||||
if ( ! Line.GetLocalBBox( boxLine))
|
||||
return ;
|
||||
BBox3d boxArc ;
|
||||
if ( ! Arc.GetLocalBBox( boxArc))
|
||||
return ;
|
||||
if ( ! boxLine.OverlapsXY( boxArc))
|
||||
return ;
|
||||
|
||||
// linea : copia e Direzione
|
||||
m_Line.CopyFrom( &Line) ;
|
||||
m_vtDirL = m_Line.GetEnd() - m_Line.GetStart() ;
|
||||
if ( m_vtDirL.SqLenXY() < EPS_SMALL * EPS_SMALL)
|
||||
return ;
|
||||
|
||||
// arco : copia
|
||||
m_Arc.CopyFrom( &Arc) ;
|
||||
|
||||
// punto proiezione del centro arco sulla linea
|
||||
double dU = (( m_Arc.GetCenter() - m_Line.GetStart()) * m_vtDirL) / m_vtDirL.SqLenXY() ;
|
||||
Point3d ptPrjCen = m_Line.GetStart() + m_vtDirL * dU ;
|
||||
// quadrato della distanza tra centro e punto proiezione
|
||||
double dSqDist = ( ptPrjCen - m_Arc.GetCenter()).SqLenXY() ;
|
||||
// differenza tra quadrato del raggio e quadrato della distanza
|
||||
double dSqDelta = m_Arc.GetRadius() * m_Arc.GetRadius() - dSqDist ;
|
||||
|
||||
// se distanza maggiore del raggio -> nessuna intersezione
|
||||
if ( dSqDelta < - 2 * m_Arc.GetRadius() * EPS_SMALL)
|
||||
return ;
|
||||
|
||||
// se distanza uguale al raggio -> una intersezione tangente (è la proiezione)
|
||||
if ( dSqDelta < 2 * m_Arc.GetRadius() * EPS_SMALL) {
|
||||
// determinazione geometrica dell'intersezione tra le due curve
|
||||
int nPosL, nPosA ;
|
||||
if ( ! CalcIntersGeomData( 0, ptPrjCen, nPosL, nPosA))
|
||||
return ;
|
||||
// determinazione topologica dell'intersezione tra le due curve
|
||||
if ( ! CalcTgIntersTopolData( 0, nPosL, nPosA))
|
||||
return ;
|
||||
// aggiorno dati generali di intersezione
|
||||
m_Info[0].bOverlap = false ;
|
||||
m_nNumInters = 1 ;
|
||||
return ;
|
||||
}
|
||||
|
||||
// distanza minore del raggio -> due intersezioni
|
||||
double dDelta = sqrt( dSqDelta) ;
|
||||
Vector3d vtDelta = m_vtDirL * dDelta / m_vtDirL.LenXY() ;
|
||||
int nPosL, nPosA ;
|
||||
// ---> prima intersezione
|
||||
// determinazione geometrica e topologica dell'intersezione tra le due curve
|
||||
if ( CalcIntersGeomData( 0, ptPrjCen - vtDelta, nPosL, nPosA) &&
|
||||
CalcSecIntersTopolData( 0, nPosL, nPosA)) {
|
||||
// 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 ( CalcIntersGeomData( m_nNumInters, ptPrjCen + vtDelta, nPosL, nPosA) &&
|
||||
CalcSecIntersTopolData( m_nNumInters, nPosL, nPosA)) {
|
||||
// aggiorno dati generali di intersezione
|
||||
m_Info[m_nNumInters].bOverlap = false ;
|
||||
++ m_nNumInters ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineArc::CalcIntersGeomData( int nInt, const Point3d& ptInt, int& nPosL, int& nPosA)
|
||||
{
|
||||
// posizione parametrica dell'intersezione sulla linea
|
||||
if ( ! m_Line.CalcPointParamPosiz( ptInt, true, m_Info[nInt].IciA[0].dU, nPosL))
|
||||
return false ;
|
||||
// posizione parametrica dell'intersezione sull'arco
|
||||
if ( ! m_Arc.CalcPointParamPosiz( ptInt, m_Info[nInt].IciB[0].dU, nPosA))
|
||||
return false ;
|
||||
// se soluzione non accettata, esco
|
||||
if ( nPosL == ICurve::PP_NULL || nPosA == ICurve::PP_NULL)
|
||||
return false ;
|
||||
// calcolo i punti sulle due curve (possono differire in Z)
|
||||
m_Info[nInt].IciA[0].ptI = m_Line.GetStart() + m_Info[nInt].IciA[0].dU * m_vtDirL ;
|
||||
m_Arc.GetPointD1D2( m_Info[nInt].IciB[0].dU, ICurve::FROM_MINUS, m_Info[nInt].IciB[0].ptI) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineArc::CalcTgIntersTopolData( int nInt, int nPosL, int nPosA)
|
||||
{
|
||||
// calcolo dati ausiliari
|
||||
bool bCCW = (( m_Arc.GetAngCenter() > 0 && m_Arc.GetNormVersor().IsZplus()) ||
|
||||
( m_Arc.GetAngCenter() < 0 && m_Arc.GetNormVersor().IsZminus())) ;
|
||||
double dCrossXY = CrossXY( m_vtDirL, ( m_Arc.GetCenter() - m_Info[nInt].IciB[0].ptI)) ;
|
||||
|
||||
// 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 ( ( nPosL == ICurve::PP_START || nPosL == ICurve::PP_END) &&
|
||||
( nPosA == ICurve::PP_START || nPosA == ICurve::PP_END)) {
|
||||
; // rimangono tutti NULL
|
||||
}
|
||||
// l'inizio di L interseca il mezzo di A
|
||||
else if ( nPosL == ICurve::PP_START) {
|
||||
if ( bCCW)
|
||||
m_Info[nInt].IciA[0].nNextTy = ICCT_OUT ; // NULL + OUT
|
||||
else
|
||||
m_Info[nInt].IciA[0].nNextTy = ICCT_IN ; // NULL + IN
|
||||
// curva B NULL + NULL
|
||||
}
|
||||
// la fine di L interseca il mezzo di A
|
||||
else if ( nPosL == ICurve::PP_END) {
|
||||
if ( bCCW)
|
||||
m_Info[nInt].IciA[0].nPrevTy = ICCT_OUT ; // OUT + NULL
|
||||
else
|
||||
m_Info[nInt].IciA[0].nPrevTy = ICCT_IN ; // IN + NULL
|
||||
// curva B NULL + NULL
|
||||
}
|
||||
// l'inizio di A interseca il mezzo di L
|
||||
else if ( nPosA == ICurve::PP_START) {
|
||||
// curva A 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 A interseca il mezzo di L
|
||||
else if ( nPosA == ICurve::PP_END) {
|
||||
// curva A 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 ( bCCW) { // OUT + OUT
|
||||
m_Info[nInt].IciA[0].nPrevTy = ICCT_OUT ;
|
||||
m_Info[nInt].IciA[0].nNextTy = ICCT_OUT ;
|
||||
}
|
||||
else { // IN + IN
|
||||
m_Info[nInt].IciA[0].nPrevTy = ICCT_IN ;
|
||||
m_Info[nInt].IciA[0].nNextTy = ICCT_IN ;
|
||||
}
|
||||
if ( - dCrossXY > 0) { // OUT + OUT
|
||||
m_Info[nInt].IciB[0].nPrevTy = ICCT_OUT ;
|
||||
m_Info[nInt].IciB[0].nNextTy = ICCT_OUT ;
|
||||
}
|
||||
else { // IN + IN
|
||||
m_Info[nInt].IciB[0].nPrevTy = ICCT_IN ;
|
||||
m_Info[nInt].IciB[0].nNextTy = ICCT_IN ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineArc::CalcSecIntersTopolData( int nInt, int nPosL, int nPosA)
|
||||
{
|
||||
// calcolo dati ausiliari
|
||||
Point3d ptIntA ;
|
||||
Vector3d vtDirA ;
|
||||
m_Arc.GetPointD1D2( m_Info[nInt].IciB[0].dU, ICurve::FROM_MINUS, ptIntA, &vtDirA) ;
|
||||
double dCrossXY = CrossXY( m_vtDirL, vtDirA) ;
|
||||
// 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 ( ( nPosL == ICurve::PP_START || nPosL == ICurve::PP_END) &&
|
||||
( nPosA == ICurve::PP_START || nPosA == ICurve::PP_END)) {
|
||||
; // rimangono tutti NULL
|
||||
}
|
||||
// l'inizio di 1 interseca il mezzo di 2
|
||||
else if ( nPosL == 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 B NULL + NULL
|
||||
}
|
||||
// la fine di 1 interseca il mezzo di 2
|
||||
else if ( nPosL == 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 B NULL + NULL
|
||||
}
|
||||
// l'inizio di 2 interseca il mezzo di 1
|
||||
else if ( nPosA == ICurve::PP_START) {
|
||||
// curva A 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 ( nPosA == ICurve::PP_END) {
|
||||
// curva A 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( ( m_Line.GetStart() - ( ptIntA - vtDirA)), vtDirA) > 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( ( ( ptIntA - vtDirA) - m_Line.GetStart()), m_vtDirL) > 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