Files
EgtGeomKernel/IntersCurveCurve.cpp
T
Dario Sassi f119a5a1be EgtGeomKernel 1.5f6 :
- agg. intersezione linee-linee
- agg. alle curve metodi per passare da lunghezza a parametro e viceversa
- agg. metodi per creare curve composite come poligoni regolari
- corr. errore in triangulate con contorni CW
- agg. opportune funzioni a TSC.
2014-06-24 07:05:43 +00:00

200 lines
6.1 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 "/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 :
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[i]) ;
}
}
//----------------------------------------------------------------------------
bool
IntersCurveCurve::GetOverlaps( void)
{
return m_bOverlaps ;
}
//----------------------------------------------------------------------------
int
IntersCurveCurve::GetNumInters( void)
{
return m_nNumInters ;
}
//----------------------------------------------------------------------------
bool
IntersCurveCurve::GetIntersParam( int nInd, int nCrv, double& dPar)
{
if ( nInd < 0 || nInd >= m_nNumInters || nCrv < 0 || nCrv > 1)
return false ;
dPar = m_Info[nInd].Ici[nCrv].dU ;
return true ;
}
//----------------------------------------------------------------------------
bool
IntersCurveCurve::GetIntersPoint( int nInd, int nCrv, Point3d& ptI)
{
if ( nInd < 0 || nInd >= m_nNumInters || nCrv < 0 || nCrv > 1)
return false ;
ptI = m_Info[nInd].Ici[nCrv].ptI ;
return true ;
}
//----------------------------------------------------------------------------
bool
IntersCurveCurve::GetIntersType( int nInd, int nCrv, int& nType)
{
if ( nInd < 0 || nInd >= m_nNumInters || nCrv < 0 || nCrv > 1)
return false ;
nType = m_Info[nInd].Ici[nCrv].nTy ;
return true ;
}
//----------------------------------------------------------------------------
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 ;
// inizializzo risultato della ricerca
bool bFound = false ;
// ricerca del punto più vicino tra le intersezioni singole
double dMinSqDist = INFINITO * INFINITO ;
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
// se è estremo di un tratto in sovrapposizione, salto al successivo
if ( IsIcctPrevOn( m_Info[i].Ici[nCrv].nTy) ||
IsIcctNextOn( m_Info[i].Ici[nCrv].nTy))
continue ;
// faccio la verifica
double dSqDist = SqDist( ptNear, m_Info[i].Ici[nCrv].ptI) ;
if ( dSqDist < dMinSqDist) {
dMinSqDist = dSqDist ;
ptI = m_Info[i].Ici[nCrv].ptI ;
bFound = true ;
}
}
// se non ci sono sovrapposizioni, posso uscire
if ( ! m_bOverlaps)
return bFound ;
// ricerca del punto più vicino tra le sovrapposizioni (sono sempre a coppie)
bool bPrevOverlap = false ;
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
// se non è estremo di un tratto in sovrapposizione, vado al prossimo
if ( ! IsIcctPrevOn( m_Info[i].Ici[nCrv].nTy) &&
! IsIcctNextOn( m_Info[i].Ici[nCrv].nTy)) {
bPrevOverlap = false ;
continue ;
}
// se il precedente non era una sovrapposizione, ne marco l'inizio
if ( ! bPrevOverlap) {
bPrevOverlap = true ;
continue ;
}
// recupero il tratto di sovrapposizione
bPrevOverlap = false ;
double dUStartTrim = m_Info[i-1].Ici[nCrv].dU ;
double dUEndTrim = m_Info[i].Ici[nCrv].dU ;
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 ;
}