EgtGeomKernel 1.6h3 :
- migliorata approssimazione curve per riconoscimento di tratti rettilinei - aggiunta CopyMaterial a GeomDB - correzioni a IntersCurveCurve per le curve approssimate - aggiunte a Intervals Union, Intersection e Difference - correzioni a SelfIntersCurve per curve approssimate - aggiunte funzioni di creazione Regioni (Rectangle, Stadium, Disk e da zuppa di curve) - migliorie varie a Regioni e introduzione dei componenti connessi (chunk).
This commit is contained in:
+91
-37
@@ -19,6 +19,7 @@
|
||||
#include "IntersCrvCompoCrvCompo.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -29,34 +30,48 @@ SelfIntersCurve::SelfIntersCurve( const ICurve& Curve)
|
||||
|
||||
// inizializzazioni
|
||||
m_bOverlaps = false ;
|
||||
m_nNumInters = 0 ;
|
||||
m_pOriCrv = &Curve ;
|
||||
m_pCurve = nullptr ;
|
||||
m_nIntersCount = 0 ;
|
||||
m_pCurve = &Curve ;
|
||||
|
||||
// verifico che la curva sia definita
|
||||
if ( &Curve == nullptr || ! Curve.IsValid())
|
||||
return ;
|
||||
|
||||
// puntatore alla curva usata nei calcoli (originale o temporanea)
|
||||
const ICurve* pCalcCrv ;
|
||||
// eventuale approssimazione temporanea della curva
|
||||
PtrOwner<ICurve> pTmpCrv ;
|
||||
// eventuale parametrizzazione della approssimazione temporanea
|
||||
DBLVECTOR vTmpPar ;
|
||||
|
||||
// se curva è arco da approssimare oppure è curva di Bezier
|
||||
if ( ( m_pOriCrv->GetType() == CRV_ARC && IsArcToApprox( *m_pOriCrv)) ||
|
||||
m_pOriCrv->GetType() == CRV_BEZ) {
|
||||
if ( ( m_pCurve->GetType() == CRV_ARC && IsArcToApprox( *m_pCurve)) ||
|
||||
m_pCurve->GetType() == CRV_BEZ) {
|
||||
// approssimo con rette
|
||||
PolyLine PL ;
|
||||
if ( ! m_pOriCrv->ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
if ( ! m_pCurve->ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
return ;
|
||||
m_pTmpCrv.Set( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( m_pTmpCrv))
|
||||
pTmpCrv.Set( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pTmpCrv))
|
||||
return ;
|
||||
if ( ! GetBasicCurveComposite( Get( m_pTmpCrv))->FromPolyLine( PL))
|
||||
if ( ! GetBasicCurveComposite( Get( pTmpCrv))->FromPolyLine( PL))
|
||||
return ;
|
||||
m_pCurve = Get( m_pTmpCrv) ;
|
||||
pCalcCrv = Get( pTmpCrv) ;
|
||||
// salvo la parametrizzazione della approssimazione temporanea
|
||||
vTmpPar.reserve( PL.GetPointNbr()) ;
|
||||
double dPar ;
|
||||
bool bFound = PL.GetFirstU( dPar) ;
|
||||
while ( bFound) {
|
||||
vTmpPar.push_back( dPar) ;
|
||||
bFound = PL.GetNextU( dPar) ;
|
||||
}
|
||||
}
|
||||
// altrimenti uso la curva originale
|
||||
else
|
||||
m_pCurve = m_pOriCrv ;
|
||||
pCalcCrv = m_pCurve ;
|
||||
|
||||
// chiamo calcolatore opportuno
|
||||
switch ( m_pCurve->GetType()) {
|
||||
switch ( pCalcCrv->GetType()) {
|
||||
case CRV_LINE :
|
||||
// un segmento non può autointersecarsi (non considero auto-intersezione un segmento perpendicolare a XY)
|
||||
break ;
|
||||
@@ -64,16 +79,18 @@ SelfIntersCurve::SelfIntersCurve( const ICurve& Curve)
|
||||
// un arco nel piano XY con angolo al centro non superiore al giro non può autointersecarsi
|
||||
break ;
|
||||
case CRV_COMPO : {
|
||||
IntersCrvCompoCrvCompo intCcCc( *GetCurveComposite( &Curve), *GetCurveComposite( &Curve)) ;
|
||||
IntersCrvCompoCrvCompo intCcCc( *GetCurveComposite( pCalcCrv), *GetCurveComposite( pCalcCrv)) ;
|
||||
if ( intCcCc.m_nNumInters > 0) {
|
||||
m_bOverlaps = intCcCc.m_bOverlaps ;
|
||||
m_nNumInters = intCcCc.m_nNumInters ;
|
||||
for ( int i = 0 ; i < m_nNumInters ; ++ i)
|
||||
m_nIntersCount = intCcCc.m_nNumInters ;
|
||||
for ( int i = 0 ; i < m_nIntersCount ; ++ i)
|
||||
m_Info.push_back( intCcCc.m_Info[i]) ;
|
||||
}
|
||||
}
|
||||
break ;
|
||||
}
|
||||
// per curva approssimata, sistemo...
|
||||
AdjustIntersParams( ( pCalcCrv != m_pCurve), pCalcCrv, vTmpPar) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -89,6 +106,54 @@ SelfIntersCurve::IsArcToApprox( const ICurve& Curve)
|
||||
fabs( pArc->GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SelfIntersCurve::GetCurveParamFromApproxParam( double& dU, const ICurve* pCalcCrv, const DBLVECTOR& vCalcPar)
|
||||
{
|
||||
int nInd = int( dU) ;
|
||||
double dFraz = dU - nInd ;
|
||||
if ( nInd >= 0 && nInd < int( vCalcPar.size()) - 1) {
|
||||
// parametrizzazione da vettore dei parametri, uniforme in ogni intervallino
|
||||
dU = vCalcPar[nInd] + dFraz * ( vCalcPar[nInd+1] - vCalcPar[nInd]) ;
|
||||
}
|
||||
else {
|
||||
// domini parametrici delle due curve
|
||||
double dCalcS, dCalcE ;
|
||||
pCalcCrv->GetDomain( dCalcS, dCalcE) ;
|
||||
double dCrvS, dCrvE ;
|
||||
m_pCurve->GetDomain( dCrvS, dCrvE) ;
|
||||
// considero una parametrizzazione uniforme sull'intero dominio
|
||||
dU = dCrvS + ( dU - dCalcS) * ( dCrvE - dCrvS) / ( dCalcE - dCalcS) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SelfIntersCurve::AdjustIntersParams( bool bAdjCrv, const ICurve* pCalcCrv, const DBLVECTOR& vCalcPar)
|
||||
{
|
||||
// se la curva originale non è stata approssimata o non ci sono auto-intersezioni, non va fatto alcunché
|
||||
if ( ! bAdjCrv || m_Info.size() == 0)
|
||||
return true ;
|
||||
// procedo ad aggiustare
|
||||
for ( auto& aInfo : m_Info) {
|
||||
// devo ricalcolare i parametri dei punti di intersezione
|
||||
GetCurveParamFromApproxParam( aInfo.IciA[0].dU, pCalcCrv, vCalcPar) ;
|
||||
ImproveCurveParamAtPoint( aInfo.IciA[0].dU, aInfo.IciA[0].ptI, m_pCurve) ;
|
||||
if ( aInfo.bOverlap) {
|
||||
GetCurveParamFromApproxParam( aInfo.IciA[1].dU, pCalcCrv, vCalcPar) ;
|
||||
ImproveCurveParamAtPoint( aInfo.IciA[1].dU, aInfo.IciA[1].ptI, m_pCurve) ;
|
||||
}
|
||||
GetCurveParamFromApproxParam( aInfo.IciB[0].dU, pCalcCrv, vCalcPar) ;
|
||||
ImproveCurveParamAtPoint( aInfo.IciB[0].dU, aInfo.IciB[0].ptI, m_pCurve) ;
|
||||
if ( aInfo.bOverlap) {
|
||||
GetCurveParamFromApproxParam( aInfo.IciB[1].dU, pCalcCrv, vCalcPar) ;
|
||||
ImproveCurveParamAtPoint( aInfo.IciB[1].dU, aInfo.IciB[1].ptI, m_pCurve) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SelfIntersCurve::GetOverlaps( void)
|
||||
@@ -98,49 +163,38 @@ SelfIntersCurve::GetOverlaps( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SelfIntersCurve::GetNumInters( void)
|
||||
SelfIntersCurve::GetIntersCount( void)
|
||||
{
|
||||
return m_nNumInters ;
|
||||
return m_nIntersCount ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SelfIntersCurve::GetNumCrossInters( void)
|
||||
SelfIntersCurve::GetCrossIntersCount( void)
|
||||
{
|
||||
int nNumCrossInters = 0 ;
|
||||
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
||||
int nCrossIntersCount = 0 ;
|
||||
for ( int i = 0 ; i < m_nIntersCount ; ++ i) {
|
||||
// se con sovrapposizione
|
||||
if ( m_Info[i].bOverlap) {
|
||||
if ( m_Info[i].IciA[0].nPrevTy != m_Info[i].IciA[1].nNextTy)
|
||||
++ nNumCrossInters ;
|
||||
++ nCrossIntersCount ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( m_Info[i].IciA[0].nPrevTy != m_Info[i].IciA[0].nNextTy)
|
||||
++ nNumCrossInters ;
|
||||
++ nCrossIntersCount ;
|
||||
}
|
||||
}
|
||||
return nNumCrossInters ;
|
||||
return nCrossIntersCount ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SelfIntersCurve::GetIntCrvCrvInfo( int nInd, IntCrvCrvInfo& aInfo)
|
||||
{
|
||||
if ( nInd < 0 || nInd >= m_nNumInters)
|
||||
if ( nInd < 0 || nInd >= m_nIntersCount)
|
||||
return false ;
|
||||
aInfo = m_Info[nInd] ;
|
||||
// se curva originale approssimata, devo ricalcolare i parametri dei punti di intersezione
|
||||
if ( m_pCurve != m_pOriCrv) {
|
||||
if ( ! m_pOriCrv->GetParamAtPoint( aInfo.IciA[0].ptI, aInfo.IciA[0].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
if ( aInfo.bOverlap && ! m_pOriCrv->GetParamAtPoint( aInfo.IciA[1].ptI, aInfo.IciA[1].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
if ( ! m_pOriCrv->GetParamAtPoint( aInfo.IciB[0].ptI, aInfo.IciB[0].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
if ( aInfo.bOverlap && ! m_pOriCrv->GetParamAtPoint( aInfo.IciB[1].ptI, aInfo.IciB[1].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -148,13 +202,13 @@ SelfIntersCurve::GetIntCrvCrvInfo( int nInd, IntCrvCrvInfo& aInfo)
|
||||
bool
|
||||
SelfIntersCurve::GetIntersPointNearTo( const Point3d& ptNear, Point3d& ptI)
|
||||
{
|
||||
if ( m_nNumInters == 0)
|
||||
if ( m_nIntersCount == 0)
|
||||
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) {
|
||||
for ( int i = 0 ; i < m_nIntersCount ; ++ i) {
|
||||
// se è un'intersezione singola
|
||||
if ( ! m_Info[i].bOverlap) {
|
||||
// faccio la verifica sul punto
|
||||
|
||||
Reference in New Issue
Block a user