f119a5a1be
- 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.
200 lines
6.1 KiB
C++
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 ;
|
|
}
|