4410a83631
- piccole modifiche per nuovo Set di PtrOwner.
171 lines
6.5 KiB
C++
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( pCrvLtmp) ;
|
|
}
|
|
}
|
|
|
|
return Release( pCrvLine) ;
|
|
}
|