diff --git a/ArcSpecial.cpp b/ArcSpecial.cpp index 08ca4e9..908e39c 100644 --- a/ArcSpecial.cpp +++ b/ArcSpecial.cpp @@ -28,15 +28,13 @@ ICurve* GetArc2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStartDeg) { // creo l'oggetto arco - ICurveArc* pArc = CreateCurveArc() ; - if ( pArc == nullptr) + PtrOwner pArc( CreateCurveArc()) ; + if ( IsNull( pArc)) return nullptr ; - // inizializzo il puntatore a curva con l'arco - PtrOwner pCrv( pArc) ; // calcolo l'arco, se ok lo restituisco ed esco if ( pArc->Set2PD( ptStart, ptEnd, dDirStartDeg)) - return Release( pCrv) ; + return Release( pArc) ; // calcolo arco non riuscito, verifico se retta va bene Vector3d vtDiff = ptEnd - ptStart ; @@ -45,14 +43,12 @@ GetArc2PD( const Point3d& ptStart, const Point3d& ptEnd, double 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 - ICurveLine* pLine = CreateCurveLine() ; - if ( pLine == nullptr) + PtrOwner pLine( CreateCurveLine()) ; + if ( IsNull( pLine)) return nullptr ; - // inizializzo il puntatore a curva con la retta - pCrv.Set( pLine) ; // calcolo retta, se ok la restituisco ed esco if ( pLine->Set( ptStart, ptEnd)) - return Release( pCrv) ; + return Release( pLine) ; } return nullptr ; @@ -65,29 +61,25 @@ ICurve* GetArc2PVN( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDirS, const Vector3d& vtN) { // creo l'oggetto arco - ICurveArc* pArc = CreateCurveArc() ; - if ( pArc == nullptr) + PtrOwner pArc( CreateCurveArc()) ; + if ( IsNull( pArc)) return nullptr ; - // inizializzo il puntatore a curva con l'arco - PtrOwner pCrv( pArc) ; // calcolo l'arco, se ok lo restituisco ed esco if ( pArc->Set2PVN( ptStart, ptEnd, vtDirS, vtN)) - return Release( pCrv) ; + 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 - ICurveLine* pLine = CreateCurveLine() ; - if ( pLine == nullptr) + PtrOwner pLine( CreateCurveLine()) ; + if ( IsNull( pLine)) return nullptr ; - // inizializzo il puntatore a curva con la retta - pCrv.Set( pLine) ; // calcolo retta, se ok la restituisco ed esco if ( pLine->Set( ptStart, ptEnd)) - return Release( pCrv) ; + return Release( pLine) ; } return nullptr ; @@ -100,15 +92,13 @@ ICurve* GetArc3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d& ptEnd, bool bCirc) { // creo l'oggetto arco - ICurveArc* pArc = CreateCurveArc() ; - if ( pArc == nullptr) + PtrOwner pArc( CreateCurveArc()) ; + if ( IsNull( pArc)) return nullptr ; - // inizializzo il puntatore a curva con l'arco - PtrOwner pCrv( pArc) ; // calcolo l'arco, se ok lo restituisco ed esco if ( pArc->Set3P( ptStart, ptOther, ptEnd, bCirc)) - return Release( pCrv) ; + return Release( pArc) ; // se era richiesta una circonferenza, errore perchè punti allineati if ( bCirc) @@ -118,15 +108,47 @@ GetArc3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d& ptEnd, // verifico se i punti sono allineati nel giusto verso if ( ( ptOther - ptStart) * ( ptEnd - ptOther) > EPS_ZERO) { // creo l'oggetto retta - ICurveLine* pLine = CreateCurveLine() ; - if ( pLine == nullptr) + PtrOwner pLine( CreateCurveLine()) ; + if ( IsNull( pLine)) return nullptr ; - // inizializzo il puntatore a curva con la retta - pCrv.Set( pLine) ; // calcolo retta, se ok la restituisco ed esco if ( pLine->Set( ptStart, ptEnd)) - return Release( pCrv) ; + 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( CreateCurveArc()) ; + 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 ; +}