Files
EgtGeomKernel/LinePntPerpCurve.cpp
T
DarioS de34cfb7e8 EgtGeomKernel :
- sistemate minuscole/maiuscole in #include.
2022-02-26 17:47:48 +01:00

171 lines
6.5 KiB
C++

//----------------------------------------------------------------------------
// 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_BEZIER :
{ 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.IsPlane())
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 = SQ_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) ;
}