Files
EgtGeomKernel/IntersCurveCurve.cpp
T
Dario Sassi 15f819fe31 EgtGeomKernel 1.5f7 :
- 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.
2014-07-01 12:30:16 +00:00

186 lines
5.6 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2014-2014
//----------------------------------------------------------------------------
// File : IntersCurveCurve.cpp Data : 20.06.14 Versione : 1.5f6
// Contenuto : Implementazione della classe intersezione linea/linea.
//
//
//
// Modifiche : 15.06.14 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "IntersLineLine.h"
#include "IntersCrvCompoCrvCompo.h"
#include "/EgtDev/Include/EGkIntersCurveCurve.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGtPointerOwner.h"
using namespace std ;
//----------------------------------------------------------------------------
IntersCurveCurve::IntersCurveCurve( const ICurve& Curve1, const ICurve& Curve2, bool bIsSegment)
{
// Le intersezioni sono calcolate nel piano XY locale.
// Il flag bIsSegment vale solo per linee.
// reset
m_bOverlaps = false ;
m_nNumInters = 0 ;
m_pCurve[0] = nullptr ;
m_pCurve[1] = nullptr ;
// chiamo calcolatore opportuno
switch ( Curve1.GetType()) {
case CRV_LINE :
switch ( Curve2.GetType()) {
case CRV_LINE :
LineLineCalculate( Curve1, Curve2, bIsSegment) ;
break ;
case CRV_ARC :
break ;
case CRV_BEZ :
break ;
case CRV_COMPO :
break ;
}
break ;
case CRV_ARC :
break ;
case CRV_BEZ :
break ;
case CRV_COMPO :
switch ( Curve2.GetType()) {
case CRV_LINE :
break ;
case CRV_ARC :
break ;
case CRV_BEZ :
break ;
case CRV_COMPO :
CrvCompoCrvCompoCalculate( Curve1, Curve2) ;
break ;
}
break ;
}
// salvo i puntatori alle curve
m_pCurve[0] = &Curve1 ;
m_pCurve[1] = &Curve2 ;
}
//----------------------------------------------------------------------------
void
IntersCurveCurve::LineLineCalculate( const ICurve& Curve1, const ICurve& Curve2, bool bIsSegment)
{
IntersLineLine intLnLn( *GetCurveLine( &Curve1), *GetCurveLine( &Curve2), bIsSegment) ;
if ( intLnLn.m_nNumInters > 0) {
m_bOverlaps = intLnLn.m_bOverlaps ;
m_nNumInters = intLnLn.m_nNumInters ;
for ( int i = 0 ; i < m_nNumInters ; ++ i)
m_Info.push_back( intLnLn.m_Info) ;
}
}
//----------------------------------------------------------------------------
void
IntersCurveCurve::CrvCompoCrvCompoCalculate( const ICurve& Curve1, const ICurve& Curve2)
{
IntersCrvCompoCrvCompo intCcCc( *GetCurveComposite( &Curve1), *GetCurveComposite( &Curve2)) ;
if ( intCcCc.m_nNumInters > 0) {
m_bOverlaps = intCcCc.m_bOverlaps ;
m_nNumInters = intCcCc.m_nNumInters ;
for ( int i = 0 ; i < m_nNumInters ; ++ i)
m_Info.push_back( intCcCc.m_Info[i]) ;
}
}
//----------------------------------------------------------------------------
bool
IntersCurveCurve::GetOverlaps( void)
{
return m_bOverlaps ;
}
//----------------------------------------------------------------------------
int
IntersCurveCurve::GetNumInters( void)
{
return m_nNumInters ;
}
//----------------------------------------------------------------------------
bool
IntersCurveCurve::GetIntCrvCrvInfo( int nInd, IntCrvCrvInfo& aInfo)
{
if ( nInd < 0 || nInd >= m_nNumInters)
return false ;
aInfo = m_Info[nInd] ;
return true ;
}
//----------------------------------------------------------------------------
bool
IntersCurveCurve::GetIntersPointNearTo( int nCrv, const Point3d& ptNear, Point3d& ptI)
{
if ( m_nNumInters == 0 || nCrv < 0 || nCrv > 1)
return false ;
// ricerca del punto più vicino tra le intersezioni singole
bool bFound = false ;
double dMinSqDist = INFINITO * INFINITO ;
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
// se è un'intersezione singola
if ( ! m_Info[i].bOverlap) {
// faccio la verifica sul punto
Point3d ptP = ( nCrv == 0 ? m_Info[i].IciA[0].ptI : m_Info[i].IciB[0].ptI) ;
double dSqDist = SqDist( ptNear, ptP) ;
if ( dSqDist < dMinSqDist) {
dMinSqDist = dSqDist ;
ptI = ptP ;
bFound = true ;
}
}
// altrimenti
else {
// recupero il tratto di sovrapposizione
double dUStartTrim, dUEndTrim ;
if ( nCrv == 0) {
dUStartTrim = m_Info[i].IciA[0].dU ;
dUEndTrim = m_Info[i].IciA[1].dU ;
}
else {
dUStartTrim = m_Info[i].IciB[0].dU ;
dUEndTrim = m_Info[i].IciB[1].dU ;
if ( ! m_Info[i].bCBOverEq)
swap( dUStartTrim, dUEndTrim) ;
}
// !!! sistemare per curva chiusa con tratto che attraversa fine/inizio !!!
PtrOwner<ICurve> pCrv( m_pCurve[nCrv]->Clone()) ;
if ( ! ::IsValid( pCrv))
continue ;
if ( ! pCrv->TrimStartEndAtParam( dUStartTrim, dUEndTrim))
continue ;
// cerco il punto
int nFlag ;
Point3d ptP ;
if ( DistPointCurve( ptNear, *pCrv).GetMinDistPoint( 0.5, ptP, nFlag)) {
// faccio la verifica
double dSqDist = SqDist( ptNear, ptP) ;
if ( dSqDist < dMinSqDist) {
dMinSqDist = dSqDist ;
ptI = ptP ;
bFound = true ;
}
}
}
}
return bFound ;
}