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:
Dario Sassi
2014-07-16 09:08:32 +00:00
parent 19fda49699
commit 56d6307a1c
19 changed files with 1357 additions and 99 deletions
+143 -26
View File
@@ -13,12 +13,16 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "GeoConst.h"
#include "IntersLineLine.h"
#include "IntersLineArc.h"
#include "IntersArcArc.h"
#include "IntersCrvCompoCrvCompo.h"
#include "CurveLine.h"
#include "CurveComposite.h"
#include "/EgtDev/Include/EGkIntersCurveCurve.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkPlane3d.h"
#include "/EgtDev/Include/EGtPointerOwner.h"
#include <algorithm>
@@ -30,11 +34,11 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
// Le intersezioni sono calcolate nel piano XY locale.
// Il flag bAreSegments vale solo per intersezione tra due linee e riguarda entrambe.
// reset
// inizializzazioni
m_bOverlaps = false ;
m_nNumInters = 0 ;
m_pCurve[0] = nullptr ;
m_pCurve[1] = nullptr ;
m_pCurve[0] = &CurveA ;
m_pCurve[1] = &CurveB ;
// chiamo calcolatore opportuno
switch ( CurveA.GetType()) {
@@ -44,6 +48,7 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
LineLineCalculate( CurveA, CurveB, bAreSegments) ;
break ;
case CRV_ARC :
LineArcCalculate( CurveA, CurveB) ;
break ;
case CRV_BEZ :
break ;
@@ -53,6 +58,19 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
}
break ;
case CRV_ARC :
switch ( CurveB.GetType()) {
case CRV_LINE :
ArcLineCalculate( CurveA, CurveB) ;
break ;
case CRV_ARC :
ArcArcCalculate( CurveA, CurveB) ;
break ;
case CRV_BEZ :
break ;
case CRV_COMPO :
ArcCrvCompoCalculate( CurveA, CurveB) ;
break ;
}
break ;
case CRV_BEZ :
break ;
@@ -62,6 +80,7 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
CrvCompoLineCalculate( CurveA, CurveB) ;
break ;
case CRV_ARC :
CrvCompoArcCalculate( CurveA, CurveB) ;
break ;
case CRV_BEZ :
break ;
@@ -71,10 +90,6 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
}
break ;
}
// salvo i puntatori alle curve
m_pCurve[0] = &CurveA ;
m_pCurve[1] = &CurveB ;
}
//----------------------------------------------------------------------------
@@ -86,11 +101,25 @@ IntersCurveCurve::LineLineCalculate( const ICurve& CurveA, const ICurve& CurveB,
if ( intLnLn.m_nNumInters > 0) {
m_bOverlaps = intLnLn.m_bOverlaps ;
m_nNumInters = intLnLn.m_nNumInters ;
for ( int i = 0 ; i < m_nNumInters ; ++ i)
if ( m_nNumInters == 1)
m_Info.push_back( intLnLn.m_Info) ;
}
}
//----------------------------------------------------------------------------
void
IntersCurveCurve::LineArcCalculate( const ICurve& CurveA, const ICurve& CurveB)
{
IntersLineArc intLnAr( *GetCurveLine( &CurveA), *GetCurveArc( &CurveB)) ;
if ( intLnAr.m_nNumInters > 0) {
m_bOverlaps = false ;
m_nNumInters = intLnAr.m_nNumInters ;
for ( int i = 0 ; i < m_nNumInters ; ++ i)
m_Info.push_back( intLnAr.m_Info[i]) ;
}
}
//----------------------------------------------------------------------------
void
IntersCurveCurve::LineCrvCompoCalculate( const ICurve& CurveA, const ICurve& CurveB)
@@ -102,6 +131,47 @@ IntersCurveCurve::LineCrvCompoCalculate( const ICurve& CurveA, const ICurve& Cur
CrvCompoCrvCompoCalculate( crvCompo, CurveB) ;
}
//----------------------------------------------------------------------------
void
IntersCurveCurve::ArcLineCalculate( const ICurve& CurveA, const ICurve& CurveB)
{
IntersLineArc intLnAr( *GetCurveLine( &CurveB), *GetCurveArc( &CurveA)) ;
if ( intLnAr.m_nNumInters > 0) {
m_bOverlaps = false ;
m_nNumInters = intLnAr.m_nNumInters ;
for ( int i = 0 ; i < m_nNumInters ; ++ i)
m_Info.push_back( intLnAr.m_Info[i]) ;
// devo scambiare opportunamente le info di intersezione tra A e B
SwapInfoAB( m_Info, 0) ;
}
}
//----------------------------------------------------------------------------
void
IntersCurveCurve::ArcArcCalculate( const ICurve& CurveA, const ICurve& CurveB)
{
IntersArcArc intArAr( *GetCurveArc( &CurveA), *GetCurveArc( &CurveB)) ;
if ( intArAr.m_nNumInters > 0) {
m_bOverlaps = intArAr.m_bOverlaps ;
m_nNumInters = intArAr.m_nNumInters ;
for ( int i = 0 ; i < m_nNumInters ; ++ i)
m_Info.push_back( intArAr.m_Info[i]) ;
}
}
//----------------------------------------------------------------------------
void
IntersCurveCurve::ArcCrvCompoCalculate( const ICurve& CurveA, const ICurve& CurveB)
{
// trasformo l'arco in curva composita
CurveComposite crvCompo ;
crvCompo.CopyFrom( &CurveA) ;
// eseguo l'intersezione tra curve composite
CrvCompoCrvCompoCalculate( crvCompo, CurveB) ;
}
//----------------------------------------------------------------------------
void
IntersCurveCurve::CrvCompoLineCalculate( const ICurve& CurveA, const ICurve& CurveB)
@@ -113,6 +183,17 @@ IntersCurveCurve::CrvCompoLineCalculate( const ICurve& CurveA, const ICurve& Cur
CrvCompoCrvCompoCalculate( CurveA, crvCompo) ;
}
//----------------------------------------------------------------------------
void
IntersCurveCurve::CrvCompoArcCalculate( const ICurve& CurveA, const ICurve& CurveB)
{
// trasformo l'arco in curva composita
CurveComposite crvCompo ;
crvCompo.CopyFrom( &CurveB) ;
// eseguo l'intersezione tra curve composite
CrvCompoCrvCompoCalculate( CurveA, crvCompo) ;
}
//----------------------------------------------------------------------------
void
IntersCurveCurve::CrvCompoCrvCompoCalculate( const ICurve& CurveA, const ICurve& CurveB)
@@ -239,21 +320,8 @@ IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass)
// devo scambiare opportunamente le info di intersezione tra A e B
// copia temporanea delle info di intersezione
ICCIVECTOR InfoTmp = m_Info ;
// eseguo lo scambio
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
// scambio le informazioni tra A e B
swap( InfoTmp[i].IciA[0], InfoTmp[i].IciB[0]) ;
swap( InfoTmp[i].IciA[1], InfoTmp[i].IciB[1]) ;
// riordino eventuali sovrapposizioni controverse
if ( InfoTmp[i].bOverlap && ! InfoTmp[i].bCBOverEq) {
swap( InfoTmp[i].IciA[0], InfoTmp[i].IciA[1]) ;
swap( InfoTmp[i].IciB[0], InfoTmp[i].IciB[1]) ;
}
}
// ordino le intersezioni secondo l'ordine crescente del parametro della prima curva
stable_sort( InfoTmp.begin(), InfoTmp.end(), SortGreater) ;
// verifiche su intersezioni in zone non-manifold
OrderNonManifoldInters( InfoTmp, *(m_pCurve[1]), *(m_pCurve[0])) ;
// esecuzione scambio e controlli
SwapInfoAB( InfoTmp, 1) ;
// se esiste almeno una intersezione
if ( m_nNumInters >= 1)
return CalcCurveClassification( m_pCurve[1], InfoTmp, ccClass) ;
@@ -266,6 +334,31 @@ IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass)
return false ;
}
//----------------------------------------------------------------------------
bool
IntersCurveCurve::SwapInfoAB( ICCIVECTOR& Info, int IndCrvOrd)
{
if ( IndCrvOrd < 0 || IndCrvOrd > 1)
return false ;
// eseguo lo scambio
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
// scambio le informazioni tra A e B
swap( Info[i].IciA[0], Info[i].IciB[0]) ;
swap( Info[i].IciA[1], Info[i].IciB[1]) ;
// riordino eventuali sovrapposizioni controverse
if ( Info[i].bOverlap && ! Info[i].bCBOverEq) {
swap( Info[i].IciA[0], Info[i].IciA[1]) ;
swap( Info[i].IciB[0], Info[i].IciB[1]) ;
}
}
// ordino le intersezioni secondo l'ordine crescente del parametro della prima curva
stable_sort( Info.begin(), Info.end(), SortGreater) ;
// verifiche su intersezioni in zone non-manifold
OrderNonManifoldInters( Info, *(m_pCurve[IndCrvOrd]), *(m_pCurve[1-IndCrvOrd])) ;
return true ;
}
//----------------------------------------------------------------------------
bool
IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTOR& Info, CRVCVECTOR& ccClass)
@@ -352,17 +445,21 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
double dStartPar, dEndPar ;
if ( ! pCurveA->GetDomain( dStartPar, dEndPar))
return false ;
// se i box delle due curve non interferiscono è sicuramente esterna
// se i box delle due curve non interferiscono è sicuramente default
BBox3d boxCrvA, boxCrvB ;
if ( ! pCurveA->GetLocalBBox( boxCrvA) ||
! pCurveB->GetLocalBBox( boxCrvB))
return false ;
if ( ! boxCrvA.OverlapsXY( boxCrvB)) {
// determino il tipo di esterno
int nClass ;
if ( ! GetCurveOutClass( pCurveB, nClass))
return false ;
// assegno i dati
CrvClass segClass ;
segClass.dParS = dStartPar ;
segClass.dParE = dEndPar ;
segClass.nClass = CRVC_OUT ;
segClass.nClass = nClass ;
ccClass.push_back( segClass) ;
return true ;
}
@@ -377,7 +474,7 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
return false ;
// calcolo l'intersezione
IntersCurveCurve iCC( clLine, *pCurveB) ;
// dichiaro la curva esterna per default
// dichiaro la classe della curva per default
int nClass = CRVC_OUT ;
// se c'è almeno una intersezione
if ( iCC.GetNumInters() > 0) {
@@ -387,6 +484,12 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
if ( aInfo.IciA[0].nPrevTy == ICCT_IN)
nClass = CRVC_IN ;
}
// altrimenti sono esterni tra loro
else {
// determino il tipo di esterno
if ( ! GetCurveOutClass( pCurveB, nClass))
return false ;
}
// assegno i dati
CrvClass segClass ;
segClass.dParS = dStartPar ;
@@ -395,3 +498,17 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
ccClass.push_back( segClass) ;
return true ;
}
//----------------------------------------------------------------------------
bool
IntersCurveCurve::GetCurveOutClass( const ICurve* pCurve, int& nClass)
{
PolyLine PL ;
if ( ! pCurve->ApproxWithLines( LIN_TOL_APPROX, ANG_TOL_APPROX_DEG, PL))
return false ;
double dArea ;
if ( ! PL.GetAreaXY( dArea))
return false ;
nClass = (( dArea > 0) ? CRVC_OUT : CRVC_IN) ;
return true ;
}