Files
EgtGeomKernel/ArcCenTgCurvePnt.cpp
DarioS 4410a83631 EgtGeomKernel :
- piccole modifiche per nuovo Set di PtrOwner.
2023-03-27 18:41:16 +02:00

178 lines
8.0 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2015-2015
//----------------------------------------------------------------------------
// File : ArcCenTgCurvePnt.cpp Data : 15.03.15 Versione : 1.6c2
// Contenuto : Implementazione funzioni per calcolo arco dati centro,
// tangente a curva e punto vicino a finale.
//
//
// Modifiche : 15.03.15 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "CurveBezier.h"
#include "CurveComposite.h"
#include "CreateCurveAux.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EGkArcCenTgCurvePnt.h"
#include "/EgtDev/Include/EGkArcSpecial.h"
#include "/EgtDev/Include/EGkCircleCenTgCurve.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
//----------------------------------------------------------------------------
static CurveArc* GetArcCenTgCurvePnt( const Point3d& ptCen, const ICurve& cCrv, const Point3d& ptNearStart,
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg) ;
static CurveArc* GetArcCenTgLinePnt( const Point3d& ptCen, const CurveLine& crvLine, const Point3d& ptNearStart,
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg) ;
static CurveArc* GetArcCenTgArcPnt( const Point3d& ptCen, const CurveArc& crvArc, const Point3d& ptNearStart,
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg) ;
static CurveArc* GetArcCenTgBezierPnt( const Point3d& ptCen, const CurveBezier& crvBezier, const Point3d& ptNearStart,
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg) ;
static CurveArc* GetArcCenTgCompoPnt( const Point3d& ptCen, const CurveComposite& crvCompo, const Point3d& ptNearStart,
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg) ;
//----------------------------------------------------------------------------
ICurveArc*
GetArcCenTgCurvePnt( const Point3d& pCen, const ICurve& cCrv, const Point3d& ptNearStart,
const Point3d& ptNearEnd, const Vector3d& vtN)
{
return GetArcCenTgCurvePnt( pCen, cCrv, ptNearStart, ptNearEnd, vtN, nullptr) ;
}
//----------------------------------------------------------------------------
CurveArc*
GetArcCenTgCurvePnt( const Point3d& ptCen, const ICurve& cCrv, const Point3d& ptNearStart,
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg)
{
// verifica dei parametri
if ( &ptCen == nullptr || &cCrv == nullptr || &ptNearStart == nullptr ||
&ptNearEnd == nullptr || &vtN == nullptr)
return nullptr ;
// eseguo calcoli a seconda della curva tg
switch ( cCrv.GetType()) {
case CRV_LINE :
{ const CurveLine& crvLine = *GetBasicCurveLine( &cCrv) ;
return GetArcCenTgLinePnt( ptCen, crvLine, ptNearStart, ptNearEnd, vtN, pPtTg) ; }
case CRV_ARC :
{ const CurveArc& crvArc = *GetBasicCurveArc( &cCrv) ;
return GetArcCenTgArcPnt( ptCen, crvArc, ptNearStart, ptNearEnd, vtN, pPtTg) ; }
case CRV_BEZIER :
{ const CurveBezier& crvBezier = *GetBasicCurveBezier( &cCrv) ;
return GetArcCenTgBezierPnt( ptCen, crvBezier, ptNearStart, ptNearEnd, vtN, pPtTg) ; }
case CRV_COMPO :
{ const CurveComposite& crvCompo = *GetBasicCurveComposite( &cCrv) ;
return GetArcCenTgCompoPnt( ptCen, crvCompo, ptNearStart, ptNearEnd, vtN, pPtTg) ; }
default :
return nullptr ;
}
}
//----------------------------------------------------------------------------
CurveArc* GetArcCenTgLinePnt( const Point3d& ptCen, const CurveLine& crvLine, const Point3d& ptNearStart,
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg)
{
// ricavo circonferenza con medesimo centro e tangente alla stessa linea
Point3d ptTg ;
PtrOwner<ICurveArc> pCirc( GetCircleCenTgCurve( ptCen, vtN, crvLine, ptNearStart, &ptTg)) ;
if ( IsNull( pCirc))
return nullptr ;
// costruisco l'arco voluto con i dati di quuesta circonferenza
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
if ( pArc->SetC2PN( ptCen, ptTg, ptNearEnd, vtN)) {
if ( pPtTg != nullptr)
*pPtTg = ptTg ;
return Release( pArc) ;
}
else
return nullptr ;
}
//----------------------------------------------------------------------------
CurveArc* GetArcCenTgArcPnt( const Point3d& ptCen, const CurveArc& crvArc, const Point3d& ptNearStart,
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg)
{
// ricavo circonferenza con medesimo centro e tangente allo stesso arco
Point3d ptTg ;
PtrOwner<ICurveArc> pCirc( GetCircleCenTgCurve( ptCen, vtN, crvArc, ptNearStart, &ptTg)) ;
if ( IsNull( pCirc))
return nullptr ;
// costruisco l'arco voluto con i dati di quuesta circonferenza
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
if ( pArc->SetC2PN( ptCen, ptTg, ptNearEnd, vtN)) {
if ( pPtTg != nullptr)
*pPtTg = ptTg ;
return Release( pArc) ;
}
else
return nullptr ;
}
//----------------------------------------------------------------------------
CurveArc*
GetArcCenTgBezierPnt( const Point3d& ptCen, const CurveBezier& crvBezier, const Point3d& ptNearStart,
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg)
{
// 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 circonferenza tangente a questa approssimazione
Point3d ptTg ;
PtrOwner<CurveArc> pCrvArc( GetBasicCurveArc( GetArcCenTgCurvePnt( ptCen, *pCrvCompo, ptNearStart,
ptNearEnd, vtN, &ptTg))) ;
if ( IsNull( pCrvArc))
return nullptr ;
// porto il punto di tangenza della circonferenza esattamente sulla curva di Bezier
DistPointCurve dstPtCurve( ptTg, crvBezier) ;
Point3d ptTg2 ;
int nFlag ;
if ( ! dstPtCurve.GetMinDistPoint( 0, ptTg2, nFlag))
return nullptr ;
// calcolo il nuovo arco
if ( ! pCrvArc->SetC2PN( ptCen, ptTg2, ptNearEnd, vtN))
return nullptr ;
// se richiesto, assegno il punto di tg
if ( pPtTg != nullptr)
*pPtTg = ptTg2 ;
// restituisco la circonferenza
return Release( pCrvArc) ;
}
//----------------------------------------------------------------------------
CurveArc* GetArcCenTgCompoPnt( const Point3d& ptCen, const CurveComposite& crvCompo, const Point3d& ptNearStart,
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg)
{
// ciclo sulla curva composita
double dMinSqDist = SQ_INFINITO ;
PtrOwner<CurveArc> pCrvArc ;
for ( const ICurve* pCrv = crvCompo.GetFirstCurve() ;
pCrv != nullptr ;
pCrv = crvCompo.GetNextCurve()) {
// recupero la circonferenza tangente alla curva elementare
Point3d ptTg ;
PtrOwner<CurveArc> pCrvAtmp( GetBasicCurveArc( GetArcCenTgCurvePnt( ptCen, *pCrv, ptNearStart,
ptNearEnd, vtN, &ptTg))) ;
if ( IsNull( pCrvAtmp))
continue ;
// verifico se è la più vicina al punto desiderato
double dSqDist = SqDist( ptNearStart, ptTg) ;
if ( dSqDist < dMinSqDist) {
dMinSqDist = dSqDist ;
pCrvArc.Set( pCrvAtmp) ;
if ( pPtTg != nullptr)
*pPtTg = ptTg ;
}
}
return Release( pCrvArc) ;
}