EgtGeomKernel 1.6o4 :
- aggiunta OffsetCurveOnX.
This commit is contained in:
Binary file not shown.
@@ -321,6 +321,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="FontNfe.cpp" />
|
||||
<ClCompile Include="NgeReader.cpp" />
|
||||
<ClCompile Include="FontOs.cpp" />
|
||||
<ClCompile Include="OffsetCurveOnX.cpp" />
|
||||
<ClCompile Include="RemoveCurveOverlaps.cpp" />
|
||||
<ClCompile Include="SelfIntersCurve.cpp" />
|
||||
<ClCompile Include="SfrCreate.cpp" />
|
||||
@@ -401,6 +402,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="..\Include\EGkLuaAux.h" />
|
||||
<ClInclude Include="..\Include\EGkMaterial.h" />
|
||||
<ClInclude Include="..\Include\EgkObjGraphics.h" />
|
||||
<ClInclude Include="..\Include\EGkOffsetCurveOnX.h" />
|
||||
<ClInclude Include="..\Include\EGkPlane3d.h" />
|
||||
<ClInclude Include="..\Include\EGkPoint3d.h" />
|
||||
<ClInclude Include="..\Include\EGkPointGrid3d.h" />
|
||||
|
||||
@@ -330,6 +330,9 @@
|
||||
<ClCompile Include="Simple CDSurfFrMove.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="OffsetCurveOnX.cpp">
|
||||
<Filter>File di origine\GeoOffset</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
@@ -737,6 +740,9 @@
|
||||
<ClInclude Include="..\Include\EGkSimpleCDSurfFrMove.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkOffsetCurveOnX.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2015-2015
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CurveOffsetAdv.cpp Data : 23.09.15 Versione : 1.6i8
|
||||
// File : OffsetCurve.cpp Data : 23.09.15 Versione : 1.6i8
|
||||
// Contenuto : Classe per offset avanzato di Curve.
|
||||
//
|
||||
//
|
||||
|
||||
@@ -0,0 +1,466 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2016-2016
|
||||
//----------------------------------------------------------------------------
|
||||
// File : OffsetCurveOnX.cpp Data : 02.04.16 Versione : 1.6o4
|
||||
// Contenuto : Classe per offset di Curve lungo la sola X.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 02.04.16 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "CurveLine.h"
|
||||
#include "CurveArc.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EgkOffsetCurveOnX.h"
|
||||
#include "/EgtDev/Include/EgkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool SplitLeftRightArcs( CurveComposite& cCompo) ;
|
||||
static bool SimpleOffsetOnX( ICurve* pCrv, double dDist) ;
|
||||
static bool VerifyAndAdjustSamePoint( ICurve* pCrv1, ICurve* pCrv2) ;
|
||||
static bool VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2) ;
|
||||
static bool SafeDist( double dDist, double dCoeff, ICurve* pCrv1, ICurve* pCrv2) ;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
OffsetCurveOnX::~OffsetCurveOnX( void)
|
||||
{
|
||||
for ( auto& pCrv : m_CrvLst) {
|
||||
if ( pCrv != nullptr) {
|
||||
delete pCrv ;
|
||||
pCrv = nullptr ;
|
||||
}
|
||||
}
|
||||
m_CrvLst.clear() ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
OffsetCurveOnX::Make( const ICurve* pCrv, double dDist)
|
||||
{
|
||||
// verifico che la curva esista e sia piana
|
||||
Plane3d plPlane ;
|
||||
if ( pCrv == nullptr || ! pCrv->IsFlat( plPlane))
|
||||
return false ;
|
||||
// se esiste estrusione, verifico sia perpendicolare al piano della curva
|
||||
Vector3d vtExtr ;
|
||||
if ( pCrv->GetExtrusion( vtExtr) && ! vtExtr.IsSmall()) {
|
||||
if ( ! AreSameOrOppositeVectorApprox( plPlane.vtN, vtExtr))
|
||||
return false ;
|
||||
}
|
||||
else
|
||||
vtExtr = plPlane.vtN ;
|
||||
|
||||
// determino se necessario cambiare riferimento ( dal vettore estrusione)
|
||||
bool bNeedRef = ( ! vtExtr.IsZplus()) ;
|
||||
|
||||
// creo una copia della curva
|
||||
CurveComposite ccCopy ;
|
||||
if ( ! ccCopy.CopyFrom( pCrv))
|
||||
return false ;
|
||||
ccCopy.SetExtrusion( vtExtr) ;
|
||||
|
||||
// se necessario cambio il riferimento
|
||||
Frame3d frExtr ;
|
||||
if ( bNeedRef) {
|
||||
// calcolo il riferimento OCS con VtExtr come asse Z
|
||||
if ( ! frExtr.Set( ORIG, vtExtr))
|
||||
return false ;
|
||||
// esprimo la curva in questo riferimento
|
||||
ccCopy.ToLoc( frExtr) ;
|
||||
}
|
||||
|
||||
// verifico che la curva sia fatta solo da rette e archi che giacciono nel piano XY (VtExtr è ora Z+)
|
||||
if ( ! ccCopy.ArcsBezierCurvesToArcsPerpExtr( 10 * EPS_SMALL, ANG_TOL_STD_DEG))
|
||||
return false ;
|
||||
|
||||
// spezzo eventuali archi che cambiano pendenza
|
||||
if ( ! SplitLeftRightArcs( ccCopy))
|
||||
return false ;
|
||||
|
||||
// verifico se curva chiusa
|
||||
bool bClosed = ccCopy.IsClosed() ;
|
||||
|
||||
// Primo passo : estraggo entità dalla copia ed eseguo opportuno offset orizzontale
|
||||
CurveComposite ccCopy2 ;
|
||||
if ( ! ccCopy2.CopyFrom( &ccCopy))
|
||||
return false ;
|
||||
// indice della prima curva (1-based, per poter assegnare un significato al segno)
|
||||
int nInd1 = 1 ;
|
||||
// recupero la prima curva e la processo
|
||||
PtrOwner<ICurve> pCrv1( ccCopy2.RemoveFirstOrLastCurve( false)) ;
|
||||
if ( IsNull( pCrv1))
|
||||
return false ;
|
||||
// eseguo semplice offset orizzontale
|
||||
pCrv1->SetTempProp( nInd1) ;
|
||||
SimpleOffsetOnX( Get( pCrv1), dDist) ;
|
||||
// curve successive
|
||||
PtrOwner<ICurve> pCrv2( ccCopy2.RemoveFirstOrLastCurve( false)) ;
|
||||
while ( ! IsNull( pCrv2)) {
|
||||
// eseguo semplice offset
|
||||
pCrv2->SetTempProp( nInd1 + 1) ;
|
||||
SimpleOffsetOnX( Get( pCrv2), dDist) ;
|
||||
// metto in lista curva precedente
|
||||
m_CrvLst.push_back( Release( pCrv1)) ;
|
||||
// aggiorno curva precedente
|
||||
++ nInd1 ;
|
||||
pCrv1.Set( Release( pCrv2)) ;
|
||||
// passo alla curva successiva
|
||||
pCrv2.Set( ccCopy2.RemoveFirstOrLastCurve( false)) ;
|
||||
}
|
||||
// Metto in lista l'ultima curva rimasta
|
||||
if ( ! IsNull( pCrv1))
|
||||
m_CrvLst.push_back( Release( pCrv1)) ;
|
||||
|
||||
// Secondo passo : taglio angoli tipo interni
|
||||
ICurve* pPrev = nullptr ;
|
||||
if ( bClosed && ! m_CrvLst.empty())
|
||||
pPrev = m_CrvLst.back() ;
|
||||
for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ;) {
|
||||
ICurve* pCrv = *iIter ;
|
||||
// gestione e verifica di estremi quasi coincidenti ed angoli interni
|
||||
if ( pPrev != nullptr) {
|
||||
if ( ! VerifyAndAdjustSamePoint( pPrev, pCrv))
|
||||
VerifyAndAdjustInternalAngle( pPrev, pCrv) ;
|
||||
}
|
||||
// passo al successivo
|
||||
pPrev = pCrv ;
|
||||
++ iIter ;
|
||||
}
|
||||
|
||||
// Terzo passo : conversione in curva composita chiudendo gli eventuali buchi con rette
|
||||
PtrOwner<CurveComposite> pCrvCompo( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pCrvCompo))
|
||||
return false ;
|
||||
Point3d ptPrec ;
|
||||
if ( ! m_CrvLst.empty())
|
||||
m_CrvLst.front()->GetStartPoint( ptPrec) ;
|
||||
for ( auto& pCrv : m_CrvLst) {
|
||||
// se punto iniziale diverso da precedente, inserisco segmento di collegamento
|
||||
Point3d ptStart ;
|
||||
pCrv->GetStartPoint( ptStart) ;
|
||||
if ( ! AreSamePointApprox( ptPrec, ptStart)) {
|
||||
CurveLine crvLine ;
|
||||
crvLine.Set( ptPrec, ptStart) ;
|
||||
pCrvCompo->AddCurve( crvLine) ;
|
||||
}
|
||||
// salvo punto finale come nuovo precedente
|
||||
pCrv->GetEndPoint( ptPrec) ;
|
||||
// aggiungo la curva alla composita
|
||||
pCrvCompo->AddCurve( pCrv) ;
|
||||
pCrv = nullptr ;
|
||||
}
|
||||
m_CrvLst.clear() ;
|
||||
// se curva chiusa, verifico anche gap tra inizio e fine
|
||||
if ( bClosed)
|
||||
pCrvCompo->Close() ;
|
||||
// unisco tutte le curve possibili
|
||||
pCrvCompo->MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG) ;
|
||||
|
||||
// se non rimasto nulla, esco
|
||||
double dLen ;
|
||||
if ( ! pCrvCompo->IsValid() || ! pCrvCompo->GetLength( dLen) || dLen < 10 * EPS_SMALL)
|
||||
return true ;
|
||||
// inserisco la curva nella lista
|
||||
m_CrvLst.push_back( Release( pCrvCompo)) ;
|
||||
CurveComposite* pCompo1 = GetBasicCurveComposite( m_CrvLst.front()) ;
|
||||
|
||||
// Quarto passo : spezzatura della curva composita negli eventuali punti di auto-intersezione
|
||||
// calcolo le auto-intersezioni
|
||||
SelfIntersCurve sintC( *pCompo1) ;
|
||||
DBLVECTOR vU ;
|
||||
IntCrvCrvInfo iccInfo ;
|
||||
for ( int i = 0 ; sintC.GetIntCrvCrvInfo( i, iccInfo) ; ++ i) {
|
||||
if ( ! iccInfo.bOverlap) {
|
||||
vU.push_back( iccInfo.IciA[0].dU) ;
|
||||
vU.push_back( iccInfo.IciB[0].dU) ;
|
||||
}
|
||||
else {
|
||||
vU.push_back( iccInfo.IciA[0].dU) ;
|
||||
vU.push_back( iccInfo.IciA[1].dU) ;
|
||||
vU.push_back( iccInfo.IciB[0].dU) ;
|
||||
vU.push_back( iccInfo.IciB[1].dU) ;
|
||||
}
|
||||
}
|
||||
// ordino il vettore in senso crescente
|
||||
sort( vU.begin(), vU.end(), less<double>()) ;
|
||||
// calcolo il vettore delle lunghezze di ogni parte di curva
|
||||
DBLVECTOR vLen ;
|
||||
for ( const auto& dU : vU) {
|
||||
double dULen ;
|
||||
pCompo1->GetLengthAtParam( dU, dULen) ;
|
||||
vLen.push_back( dULen) ;
|
||||
}
|
||||
// se ultima parte molto piccola, la elimino
|
||||
if ( ! vU.empty() && ( dLen - vLen.back()) < 2 * EPS_SMALL) {
|
||||
vU.pop_back() ;
|
||||
vLen.pop_back() ;
|
||||
}
|
||||
// eseguo la divisione
|
||||
int nCount = 1 ;
|
||||
double dUPrev = 0 ;
|
||||
double dLenPrev = 0 ;
|
||||
for ( int i = 0 ; i < int( vU.size()) ; ++ i) {
|
||||
// se lunghezza della curva risulta piccola, salto
|
||||
if ( ( vLen[i] - dLenPrev) < 2 * EPS_SMALL)
|
||||
continue ;
|
||||
// copio la curva
|
||||
PtrOwner<CurveComposite> pCopy( pCompo1->Clone()) ;
|
||||
if ( IsNull( pCopy))
|
||||
return false ;
|
||||
m_CrvLst.push_back( Release( pCopy)) ;
|
||||
++ nCount ;
|
||||
// trimmo l'originale
|
||||
pCompo1->TrimStartEndAtParam( dUPrev, vU[i]) ;
|
||||
// la copia diventa il nuovo corrente
|
||||
pCompo1 = GetBasicCurveComposite( m_CrvLst.back()) ;
|
||||
dUPrev = vU[i] ;
|
||||
dLenPrev = vLen[i] ;
|
||||
}
|
||||
// se fatta almeno una suddivisione, trimmo l'ultima parte
|
||||
if ( dUPrev > EPS_PARAM)
|
||||
pCompo1->TrimStartAtParam( dUPrev) ;
|
||||
|
||||
// Quinto passo : elimino le parti che sono troppo vicine al percorso originale
|
||||
for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ;) {
|
||||
ICurve* pCrv = *iIter ;
|
||||
// distanza minima di alcuni punti interni della curva dalla curva originale
|
||||
if ( ! SafeDist( dDist, 0.5, pCrv, &ccCopy) ||
|
||||
! SafeDist( dDist, 0.25, pCrv, &ccCopy) ||
|
||||
! SafeDist( dDist, 0.75, pCrv, &ccCopy)) {
|
||||
delete pCrv ;
|
||||
iIter = m_CrvLst.erase( iIter) ;
|
||||
continue ;
|
||||
}
|
||||
// passo alla successiva
|
||||
++ iIter ;
|
||||
}
|
||||
|
||||
// Sesto passo : concateno i percorsi risultanti (senza cambiare verso)
|
||||
for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ;) {
|
||||
CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ;
|
||||
// recupero punti iniziale e finale della curva
|
||||
Point3d ptStart, ptEnd ;
|
||||
pCrvCo->GetStartPoint( ptStart) ;
|
||||
pCrvCo->GetEndPoint( ptEnd) ;
|
||||
// ciclo sulle curve successive per verificare se possibile concatenamento
|
||||
for ( auto iIter2 = next( iIter) ; iIter2 != m_CrvLst.end() ;) {
|
||||
CurveComposite* pCrvCo2 = GetBasicCurveComposite( *iIter2) ;
|
||||
// recupero punti iniziale e finale della curva
|
||||
Point3d ptStart2, ptEnd2 ;
|
||||
pCrvCo2->GetStartPoint( ptStart2) ;
|
||||
pCrvCo2->GetEndPoint( ptEnd2) ;
|
||||
// verifiche di concatenamento
|
||||
if ( AreSamePointEpsilon( ptEnd, ptStart2, 10 * EPS_SMALL)) {
|
||||
pCrvCo->AddCurve( pCrvCo2, true, 10 * EPS_SMALL) ;
|
||||
m_CrvLst.erase( iIter2) ;
|
||||
ptEnd = ptEnd2 ;
|
||||
iIter2 = next( iIter) ;
|
||||
}
|
||||
else if ( AreSamePointEpsilon( ptEnd2, ptStart, 10 * EPS_SMALL)) {
|
||||
pCrvCo->AddCurve( pCrvCo2, false, 10 * EPS_SMALL) ;
|
||||
m_CrvLst.erase( iIter2) ;
|
||||
ptStart = ptStart2 ;
|
||||
iIter2 = next( iIter) ;
|
||||
}
|
||||
else
|
||||
++ iIter2 ;
|
||||
}
|
||||
++ iIter ;
|
||||
}
|
||||
|
||||
// riporto il risultato nel riferimento originale
|
||||
if ( bNeedRef) {
|
||||
for ( auto pCrv : m_CrvLst)
|
||||
pCrv->ToGlob( frExtr) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
OffsetCurveOnX::GetCurve( void)
|
||||
{
|
||||
if ( m_CrvLst.empty())
|
||||
return nullptr ;
|
||||
ICurve* pCrv = m_CrvLst.front() ;
|
||||
m_CrvLst.pop_front() ;
|
||||
return pCrv ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
OffsetCurveOnX::GetLongerCurve( void)
|
||||
{
|
||||
if ( m_CrvLst.empty())
|
||||
return nullptr ;
|
||||
// cerco la curva più lunga
|
||||
double dMaxLen = 0 ;
|
||||
auto iMaxIter = m_CrvLst.end() ;
|
||||
for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ; ++ iIter) {
|
||||
double dLen ;
|
||||
if ( (*iIter)->GetLength( dLen) && dLen > dMaxLen) {
|
||||
dMaxLen = dLen ;
|
||||
iMaxIter = iIter ;
|
||||
}
|
||||
}
|
||||
// se trovata
|
||||
if ( iMaxIter != m_CrvLst.end()) {
|
||||
ICurve* pCrv = (*iMaxIter) ;
|
||||
m_CrvLst.erase( iMaxIter) ;
|
||||
return pCrv ;
|
||||
}
|
||||
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SplitLeftRightArcs( CurveComposite& cCompo)
|
||||
{
|
||||
int i = 0 ;
|
||||
const ICurve* pCrv = cCompo.GetCurve( i) ;
|
||||
while ( pCrv != nullptr) {
|
||||
if ( pCrv->GetType() == CRV_ARC) {
|
||||
const CurveArc* pArc = GetBasicCurveArc( pCrv) ;
|
||||
// determino la rotazione angolare dall'inizio alle direzioni su e giù
|
||||
double dAng1, dAng2 ;
|
||||
bool bDet ;
|
||||
pArc->GetStartVersor().GetRotation( Y_AX, Z_AX, dAng1, bDet) ;
|
||||
pArc->GetStartVersor().GetRotation( - Y_AX, Z_AX, dAng2, bDet) ;
|
||||
// oriento queste rotazioni come l'angolo al centro dell'arco
|
||||
if ( pArc->GetAngCenter() > 0) {
|
||||
if ( dAng1 < 0)
|
||||
dAng1 += ANG_FULL ;
|
||||
if ( dAng2 < 0)
|
||||
dAng2 += ANG_FULL ;
|
||||
}
|
||||
else {
|
||||
if ( dAng1 > 0)
|
||||
dAng1 -= ANG_FULL ;
|
||||
if ( dAng2 > 0)
|
||||
dAng2 -= ANG_FULL ;
|
||||
}
|
||||
// le ordino in senso crescente di ampiezza assoluta
|
||||
if ( abs( dAng1) > abs( dAng2))
|
||||
swap( dAng1, dAng2) ;
|
||||
// verifico se la prima di queste rotazioni è compresa nell'arco
|
||||
if ( abs( dAng1) > EPS_ANG_SMALL && abs( dAng1) < abs( pArc->GetAngCenter()) - EPS_ANG_SMALL) {
|
||||
cCompo.AddJoint( i + dAng1 / pArc->GetAngCenter()) ;
|
||||
}
|
||||
// verifico la seconda
|
||||
else if ( abs( dAng2) > EPS_ANG_SMALL && abs( dAng2) < abs( pArc->GetAngCenter()) - EPS_ANG_SMALL) {
|
||||
cCompo.AddJoint( i + dAng2 / pArc->GetAngCenter()) ;
|
||||
}
|
||||
}
|
||||
// passo alla successiva
|
||||
pCrv = cCompo.GetCurve( ++i) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SimpleOffsetOnX( ICurve* pCrv, double dDist)
|
||||
{
|
||||
Point3d ptStart, ptEnd ;
|
||||
pCrv->GetStartPoint( ptStart) ;
|
||||
pCrv->GetEndPoint( ptEnd) ;
|
||||
if ( abs( ptStart.y - ptEnd.y) < EPS_SMALL)
|
||||
;
|
||||
else if ( ptStart.y < ptEnd.y)
|
||||
pCrv->Translate( Vector3d( dDist, 0, 0)) ;
|
||||
else
|
||||
pCrv->Translate( Vector3d( - dDist, 0, 0)) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VerifyAndAdjustSamePoint( ICurve* pCrv1, ICurve* pCrv2)
|
||||
{
|
||||
// verifica dei puntatori
|
||||
if ( pCrv1 == nullptr || pCrv2 == nullptr)
|
||||
return false ;
|
||||
|
||||
// calcolo dei punti estremi (finale per prima curva, iniziale per seconda)
|
||||
Point3d ptP1, ptP2 ;
|
||||
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
|
||||
return false ;
|
||||
// verifica distanza tra estremi
|
||||
if ( ! AreSamePointXYEpsilon( ptP1, ptP2, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
// se coincidono esattamente, va bene così
|
||||
if ( AreSamePointExact( ptP1, ptP2))
|
||||
return true ;
|
||||
// sono in tolleranza, ma devo ricongiungere gli estremi
|
||||
Point3d ptMid = 0.5 * ( ptP1 + ptP2) ;
|
||||
return ( pCrv1->ModifyEnd( ptMid) && pCrv2->ModifyStart( ptMid)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2)
|
||||
{
|
||||
// verifica dei puntatori
|
||||
if ( pCrv1 == nullptr || pCrv2 == nullptr)
|
||||
return false ;
|
||||
|
||||
// calcolo l'intersezione tra le due curve
|
||||
IntersCurveCurve intCC( *pCrv1, *pCrv2) ;
|
||||
if ( intCC.GetIntersCount() == 0)
|
||||
return false ;
|
||||
// prendo l'intersezione più vicina al punto medio tra gli estremi delle curve
|
||||
Point3d ptP1, ptP2 ;
|
||||
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
|
||||
return false ;
|
||||
Point3d ptMid = 0.5 * ( ptP1 + ptP2) ;
|
||||
Point3d ptNew1, ptNew2 ;
|
||||
if ( ! intCC.GetIntersPointNearTo( 0, ptMid, ptNew1) ||
|
||||
! intCC.GetIntersPointNearTo( 1, ptMid, ptNew2))
|
||||
return false ;
|
||||
// modifico le due curve sul punto medio di intersezione
|
||||
Point3d ptNew = 0.5 * ( ptNew1 + ptNew2) ;
|
||||
return ( pCrv1->ModifyEnd( ptNew) && pCrv2->ModifyStart( ptNew)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SafeDist( double dDist, double dCoeff, ICurve* pCrv1, ICurve* pCrv2)
|
||||
{
|
||||
// calcolo il punto e due vicini
|
||||
double dUStart, dUEnd ;
|
||||
pCrv1->GetDomain( dUStart, dUEnd) ;
|
||||
double dU = dCoeff * dUStart + ( 1 - dCoeff) * dUEnd ;
|
||||
Point3d ptP ;
|
||||
pCrv1->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP) ;
|
||||
Point3d ptPrev, ptNext ;
|
||||
Vector3d vtPrev, vtNext ;
|
||||
pCrv1->GetPointTang( dU - 100 * EPS_PARAM, ICurve::FROM_MINUS, ptPrev, vtPrev) ;
|
||||
pCrv1->GetPointTang( dU + 100 * EPS_PARAM, ICurve::FROM_PLUS, ptNext, vtNext) ;
|
||||
// non si considerano i tratti orizzontali
|
||||
if ( abs( vtPrev.y) < EPS_SMALL || abs( vtNext.y) < EPS_SMALL)
|
||||
return true ;
|
||||
// segmento orizzontale di prova centrato sul punto e lungo dDist + dDist
|
||||
Vector3d vtDelta( abs(dDist) - 5 * EPS_SMALL, 0, 0) ;
|
||||
CurveLine Line ;
|
||||
Line.Set( ptP - vtDelta, ptP + vtDelta) ;
|
||||
// interseco il segmento di test con la curva originale
|
||||
IntersCurveCurve IntCC( Line, *pCrv2) ;
|
||||
return ( IntCC.GetIntersCount() == 0) ;
|
||||
}
|
||||
Reference in New Issue
Block a user