//---------------------------------------------------------------------------- // EgalTech 2014-2023 //---------------------------------------------------------------------------- // File : ArcSpecial.cpp Data : 04.08.23 Versione : 2.5h1 // Contenuto : Implementazione funzioni per calcoli speciali archi. // // // // Modifiche : 12.06.14 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "CreateCurveAux.h" #include "/EgtDev/Include/EGkCurveLine.h" #include "/EgtDev/Include/EGkArcSpecial.h" #include "/EgtDev/Include/EgtPointerOwner.h" using namespace std ; //---------------------------------------------------------------------------- // Come la CurveArc::Set2PD, ma se raggio infinito restituisce una retta //---------------------------------------------------------------------------- ICurve* GetArc2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStartDeg) { // creo l'oggetto arco PtrOwner pArc( CreateBasicCurveArc()) ; if ( IsNull( pArc)) return nullptr ; // calcolo l'arco, se ok lo restituisco ed esco if ( pArc->Set2PD( ptStart, ptEnd, dDirStartDeg)) return Release( pArc) ; // calcolo arco non riuscito, verifico se retta va bene Vector3d vtDiff = ptEnd - ptStart ; vtDiff.z = 0 ; Vector3d vtDir = FromPolar( 1, dDirStartDeg) ; // verifico se i punti sono allineati con la direzione e nel giusto verso if ( abs( CrossXY( vtDiff, vtDir)) < EPS_SMALL && ScalarXY( vtDiff, vtDir) > EPS_SMALL) { // creo l'oggetto retta PtrOwner pLine( CreateBasicCurveLine()) ; if ( IsNull( pLine)) return nullptr ; // calcolo retta, se ok la restituisco ed esco if ( pLine->Set( ptStart, ptEnd)) return Release( pLine) ; } return nullptr ; } //---------------------------------------------------------------------------- // Come la CurveArc::Set2PVN, ma se raggio infinito restituisce una retta //---------------------------------------------------------------------------- ICurve* GetArc2PVN( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDirS, const Vector3d& vtN) { // creo l'oggetto arco PtrOwner pArc( CreateBasicCurveArc()) ; if ( IsNull( pArc)) return nullptr ; // calcolo l'arco, se ok lo restituisco ed esco if ( pArc->Set2PVN( ptStart, ptEnd, vtDirS, vtN)) return Release( pArc) ; // calcolo arco non riuscito, verifico se retta va bene Vector3d vtDiff = ptEnd - ptStart ; // verifico se i punti sono allineati con la direzione e nel giusto verso nel piano perpendicolare a vtN if ( abs( ( vtDiff ^ vtDirS) * vtN) < EPS_SMALL && vtDiff * vtDirS > EPS_SMALL) { // creo l'oggetto retta PtrOwner pLine( CreateBasicCurveLine()) ; if ( IsNull( pLine)) return nullptr ; // calcolo retta, se ok la restituisco ed esco if ( pLine->Set( ptStart, ptEnd)) return Release( pLine) ; } return nullptr ; } //---------------------------------------------------------------------------- // Come la CurveArc::Set2PNB, ma se bulge nullo restituisce una retta //---------------------------------------------------------------------------- ICurve* GetArc2PNB( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtN, double dBulge) { // creo l'oggetto arco PtrOwner pArc( CreateBasicCurveArc()) ; if ( IsNull( pArc)) return nullptr ; // calcolo l'arco, se ok lo restituisco ed esco if ( pArc->Set2PNB( ptStart, ptEnd, vtN, dBulge)) return Release( pArc) ; // calcolo arco non riuscito, verifico se retta va bene if ( abs( dBulge) > EPS_SMALL) return nullptr ; // creo l'oggetto retta PtrOwner pLine( CreateBasicCurveLine()) ; if ( IsNull( pLine)) return nullptr ; // calcolo retta, se ok la restituisco ed esco if ( pLine->Set( ptStart, ptEnd)) return Release( pLine) ; return nullptr ; } //---------------------------------------------------------------------------- // Come la CurveArc::Set3P, ma se raggio infinito restituisce una retta //---------------------------------------------------------------------------- ICurve* GetArc3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d& ptEnd, bool bCirc) { // creo l'oggetto arco PtrOwner pArc( CreateBasicCurveArc()) ; if ( IsNull( pArc)) return nullptr ; // calcolo l'arco, se ok lo restituisco ed esco if ( pArc->Set3P( ptStart, ptOther, ptEnd, bCirc)) return Release( pArc) ; // se era richiesta una circonferenza, errore perchè punti allineati if ( bCirc) return nullptr ; // calcolo arco non riuscito, se i punti sono allineati nel giusto verso per essere una retta // verifico se i punti sono allineati nel giusto verso if ( ( ptOther - ptStart) * ( ptEnd - ptOther) > EPS_ZERO) { // creo l'oggetto retta PtrOwner pLine( CreateBasicCurveLine()) ; if ( IsNull( pLine)) return nullptr ; // calcolo retta, se ok la restituisco ed esco if ( pLine->Set( ptStart, ptEnd)) return Release( pLine) ; } return nullptr ; } //---------------------------------------------------------------------------- // Come la CurveArc::SetC2PN, ma garantisce il passaggio per gli estremi e minimizza errore sul centro //---------------------------------------------------------------------------- ICurveArc* GetArc2PCN( const Point3d& ptStart, const Point3d& ptEnd, const Point3d& ptNearCen, const Vector3d& vtN) { // creo l'oggetto arco PtrOwner pArc( CreateBasicCurveArc()) ; if ( IsNull( pArc)) return nullptr ; // vettori dal centro a inizio e fine Vector3d vtStart = ptStart - ptNearCen ; Vector3d vtEnd = ptEnd - ptNearCen ; // determino il raggio medio double dStartRad = OrthoCompo( vtStart, vtN).Len() ; double dEndRad = OrthoCompo( vtEnd, vtN).Len() ; double dRad = ( dStartRad + dEndRad) / 2 ; if ( dRad < EPS_SMALL) return nullptr ; // determino un valore approssimato dell'angolo al centro double dAngDeg ; bool bDet ; if ( ! vtStart.GetRotation( vtEnd, vtN, dAngDeg, bDet) || ! bDet || abs( dAngDeg) < EPS_ANG_ZERO) return nullptr ; // calcolo l'arco antiorario per i due punti con il raggio medio if ( pArc->Set2PNRS( ptStart, ptEnd, vtN, dRad, ( dAngDeg > 0))) return Release( pArc) ; return nullptr ; }