EgtGeomKernel 1.5k5 :
- sviluppo linee tangenti e perpendicolari a curve.
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2014
|
||||
//----------------------------------------------------------------------------
|
||||
// File : LinePntPerpCurve.cpp Data : 25.11.14 Versione : 1.5k5
|
||||
// Contenuto : Implementazione funzioni per calcolo rette perpendicolari a curve.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 25.11.14 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveLine.h"
|
||||
#include "CurveArc.h"
|
||||
#include "CurveBezier.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EgkLinePntPerpCurve.h"
|
||||
#include "/EgtDev/Include/EgkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static CurveLine* GetLinePointPerpLine( const Point3d& ptP, const CurveLine& crvLine, const Point3d& ptNear) ;
|
||||
static CurveLine* GetLinePointPerpArc( const Point3d& ptP, const CurveArc& crvArc, const Point3d& ptNear) ;
|
||||
static CurveLine* GetLinePointPerpBezier( const Point3d& ptP, const CurveBezier& crvBezier, const Point3d& ptNear) ;
|
||||
static CurveLine* GetLinePointPerpCompo( const Point3d& ptP, const CurveComposite& crvCompo, const Point3d& ptNear) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurveLine*
|
||||
GetLinePointPerpCurve( const Point3d& ptP, const ICurve& cCrv, const Point3d& ptNear)
|
||||
{
|
||||
switch ( cCrv.GetType()) {
|
||||
case CRV_LINE :
|
||||
{ const CurveLine& crvLine = *GetBasicCurveLine( &cCrv) ;
|
||||
return GetLinePointPerpLine( ptP, crvLine, ptNear) ; }
|
||||
case CRV_ARC :
|
||||
{ const CurveArc& crvArc = *GetBasicCurveArc( &cCrv) ;
|
||||
return GetLinePointPerpArc( ptP, crvArc, ptNear) ; }
|
||||
case CRV_BEZ :
|
||||
{ const CurveBezier& crvBezier = *GetBasicCurveBezier( &cCrv) ;
|
||||
return GetLinePointPerpBezier( ptP, crvBezier, ptNear) ; }
|
||||
case CRV_COMPO :
|
||||
{ const CurveComposite& crvCompo = *GetBasicCurveComposite( &cCrv) ;
|
||||
return GetLinePointPerpCompo( ptP, crvCompo, ptNear) ; }
|
||||
default :
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveLine*
|
||||
GetLinePointPerpLine( const Point3d& ptP, const CurveLine& crvLine, const Point3d& ptNear)
|
||||
{
|
||||
// direzione della linea
|
||||
Vector3d vtDir ;
|
||||
if ( ! crvLine.GetStartDir( vtDir))
|
||||
return nullptr ;
|
||||
// lunghezza della linea
|
||||
double dLen ;
|
||||
if ( ! crvLine.GetLength( dLen))
|
||||
return nullptr ;
|
||||
// piede della perpendicolare dal punto alla linea
|
||||
double dPerpLen = ( ptP - crvLine.GetStart()) * vtDir ;
|
||||
if ( dPerpLen < - EPS_ZERO || dPerpLen > dLen + EPS_ZERO)
|
||||
return nullptr ;
|
||||
if ( dPerpLen < 0)
|
||||
dPerpLen = 0 ;
|
||||
else if ( dPerpLen > dLen)
|
||||
dPerpLen = dLen ;
|
||||
Point3d ptFoot = crvLine.GetStart() + dPerpLen * vtDir ;
|
||||
// creo la linea
|
||||
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
|
||||
if ( IsNull( pCrvLine))
|
||||
return nullptr ;
|
||||
// costruisco la linea
|
||||
if ( ! pCrvLine->Set( ptP, ptFoot))
|
||||
return nullptr ;
|
||||
// restituisco la linea
|
||||
return Release( pCrvLine) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveLine*
|
||||
GetLinePointPerpArc( const Point3d& ptP, const CurveArc& crvArc, const Point3d& ptNear)
|
||||
{
|
||||
// l'arco deve essere piatto (no elica)
|
||||
if ( ! crvArc.IsFlat())
|
||||
return nullptr ;
|
||||
// punti sull'arco su direzione della linea dal punto al centro dell'arco
|
||||
Point3d ptP2 ;
|
||||
Vector3d vtDirP = crvArc.GetCenter() - ptP ;
|
||||
vtDirP -= vtDirP * crvArc.GetNormVersor() * crvArc.GetNormVersor() ;
|
||||
if ( ! vtDirP.Normalize()) {
|
||||
// il punto è nel centro dell'arco, l'estremo sull'arco dipende solo da Near
|
||||
DistPointCurve dstPtCurve( ptNear, crvArc) ;
|
||||
int nFlag ;
|
||||
if ( ! dstPtCurve.GetMinDistPoint( 0, ptP2, nFlag))
|
||||
return nullptr ;
|
||||
}
|
||||
else {
|
||||
if ( ! FindPointOnArc( crvArc, vtDirP, ptNear, ptP2))
|
||||
return nullptr ;
|
||||
}
|
||||
// creo la linea
|
||||
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
|
||||
if ( IsNull( pCrvLine))
|
||||
return nullptr ;
|
||||
// costruisco la linea
|
||||
if ( ! pCrvLine->Set( ptP, ptP2))
|
||||
return nullptr ;
|
||||
// restituisco la linea
|
||||
return Release( pCrvLine) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveLine*
|
||||
GetLinePointPerpBezier( const Point3d& ptP, const CurveBezier& crvBezier, const Point3d& ptNear)
|
||||
{
|
||||
// calcolo approssimazione della curva di Bezier con archi e rette
|
||||
PolyArc PA ;
|
||||
if ( ! crvBezier.ApproxWithArcs( 10 * EPS_SMALL, ANG_TOL_STD_DEG, PA))
|
||||
return nullptr ;
|
||||
// la trasformo in curva composita
|
||||
PtrOwner<CurveComposite> pCrvCompo( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyArc( PA))
|
||||
return nullptr ;
|
||||
// calcolo la linea perpendicolare a questa approssimazione
|
||||
PtrOwner<CurveLine> pCrvLine( GetBasicCurveLine( GetLinePointPerpCurve( ptP, *pCrvCompo, ptNear))) ;
|
||||
if ( IsNull( pCrvLine))
|
||||
return nullptr ;
|
||||
// porto il punto finale della linea esattamente sulla curva di Bezier
|
||||
DistPointCurve dstPtCurve( pCrvLine->GetEnd(), crvBezier) ;
|
||||
Point3d ptP2 ;
|
||||
int nFlag ;
|
||||
if ( ! dstPtCurve.GetMinDistPoint( 0, ptP2, nFlag) || ! pCrvLine->ModifyEnd( ptP2))
|
||||
return nullptr ;
|
||||
// restituisco la linea
|
||||
return Release( pCrvLine) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveLine*
|
||||
GetLinePointPerpCompo( const Point3d& ptP, const CurveComposite& crvCompo, const Point3d& ptNear)
|
||||
{
|
||||
// ciclo sulla curva composita
|
||||
double dMinSqDist = INFINITO * INFINITO ;
|
||||
PtrOwner<CurveLine> pCrvLine ;
|
||||
for ( const ICurve* pCrv = crvCompo.GetFirstCurve() ;
|
||||
pCrv != nullptr ;
|
||||
pCrv = crvCompo.GetNextCurve()) {
|
||||
// recupero la linea perpendicolare alla curva elementare
|
||||
PtrOwner<CurveLine> pCrvLtmp( GetBasicCurveLine( GetLinePointPerpCurve( ptP, *pCrv, ptNear))) ;
|
||||
if ( IsNull( pCrvLtmp))
|
||||
continue ;
|
||||
// verifico se è la più vicina al punto desiderato
|
||||
double dSqDist = SqDist( ptNear, pCrvLtmp->GetEnd()) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
pCrvLine.Set( Release( pCrvLtmp)) ;
|
||||
}
|
||||
}
|
||||
|
||||
return Release( pCrvLine) ;
|
||||
}
|
||||
Reference in New Issue
Block a user