diff --git a/ArcSpecial.cpp b/ArcSpecial.cpp index bc489e1..7c147c9 100644 --- a/ArcSpecial.cpp +++ b/ArcSpecial.cpp @@ -77,8 +77,8 @@ GetArc2PVN( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDirS // 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 - if ( ( vtDiff ^ vtDirS).IsSmall() && vtDiff * vtDirS > EPS_SMALL) { + // 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) diff --git a/CurveComposite.cpp b/CurveComposite.cpp index 73bdbb1..a956de0 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -2817,3 +2817,44 @@ CurveComposite::RemoveUndercutOnY( double dLinTol, double dAngTolDeg) Clear() ; return AddCurve( Release( pOutLoop)) ; } + +//---------------------------------------------------------------------------- +bool +CurveComposite::IsOneCircle( Point3d& ptCen, Vector3d& vtN, double& dRad, bool& bCCW) const +{ + // deve essere una sola entità + if ( GetCurveCount() != 1) + return false ; + // deve essere un arco di circonferenza completo + const CurveArc* pArc = GetBasicCurveArc( GetFirstCurve()) ; + if ( pArc == nullptr || ! pArc->IsACircle()) + return false ; + // assegno i parametri + ptCen = pArc->GetCenter() ; + vtN = pArc->GetNormVersor() ; + dRad = pArc->GetRadius() ; + bCCW = ( pArc->GetAngCenter() > 0) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveComposite::IsACircle( double dLinTol, Point3d& ptCen, Vector3d& vtN, double& dRad, bool& bCCW) const +{ + // deve essere chiusa + if ( ! IsClosed()) + return false ; + + // se è formata da una sola entità arco che è una circonferenza + if ( IsOneCircle( ptCen, vtN, dRad, bCCW)) + return true ; + + // provo ad approssimarla con archi e verifico se si riduce ad una circonferenza + PolyArc PA ; + if ( ! ApproxWithArcs( dLinTol, ANG_TOL_STD_DEG, PA)) + return false ; + CurveComposite CrvTemp ; + if ( ! CrvTemp.FromPolyArc( PA) || ! CrvTemp.MergeCurves( dLinTol, ANG_TOL_STD_DEG)) + return false ; + return CrvTemp.IsOneCircle( ptCen, vtN, dRad, bCCW) ; +} diff --git a/CurveComposite.h b/CurveComposite.h index 52c4606..3966b84 100644 --- a/CurveComposite.h +++ b/CurveComposite.h @@ -151,6 +151,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW bool ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDeg) override ; bool MergeCurves( double dLinTol, double dAngTolDeg, bool bStartEnd = true) override ; bool RemoveUndercutOnY( double dLinTol, double dAngTolDeg) override ; + bool IsACircle( double dLinTol, Point3d& ptCen, Vector3d& vtN, double& dRad, bool& bCCW) const override ; public : // IGeoObjRW virtual int GetNgeId( void) const ; @@ -176,6 +177,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW bool GetIndSCurveAndLocPar( double dU, Side nS, int& nSCrv, double& dLocU) const ; bool SimpleOffsetXY( double dDist, int nType = OFF_FILLET) ; bool MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dAngTolDeg) ; + bool IsOneCircle( Point3d& ptCen, Vector3d& vtN, double& dRad, bool& bCCW) const ; private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;