15f819fe31
- 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.
186 lines
5.6 KiB
C++
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 ;
|
|
}
|