//---------------------------------------------------------------------------- // 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_BEZ : { 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 pCirc( GetCircleCenTgCurve( ptCen, vtN, crvLine, ptNearStart, &ptTg)) ; if ( IsNull( pCirc)) return nullptr ; // costruisco l'arco voluto con i dati di quuesta circonferenza PtrOwner 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 pCirc( GetCircleCenTgCurve( ptCen, vtN, crvArc, ptNearStart, &ptTg)) ; if ( IsNull( pCirc)) return nullptr ; // costruisco l'arco voluto con i dati di quuesta circonferenza PtrOwner 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 pCrvCompo( CreateBasicCurveComposite()) ; if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyArc( PA)) return nullptr ; // calcolo la circonferenza tangente a questa approssimazione Point3d ptTg ; PtrOwner 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 = INFINITO * INFINITO ; PtrOwner pCrvArc ; for ( const ICurve* pCrv = crvCompo.GetFirstCurve() ; pCrv != nullptr ; pCrv = crvCompo.GetNextCurve()) { // recupero la circonferenza tangente alla curva elementare Point3d ptTg ; PtrOwner 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( Release( pCrvAtmp)) ; if ( pPtTg != nullptr) *pPtTg = ptTg ; } } return Release( pCrvArc) ; }