diff --git a/CurveArc.cpp b/CurveArc.cpp index b411c0d..abd126a 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -699,29 +699,9 @@ CurveArc::Load( NgeReader& ngeIn) bool CurveArc::GetLocalBBox( BBox3d& b3Loc, int nFlag) const { - // verifico lo stato - if ( m_nStatus != OK) - return false ; - // assegno il box in locale - b3Loc.Reset() ; - double dLinTol = LIN_TOL_APPROX ; - double dAngTolDeg = ANG_TOL_APPROX_DEG ; - if ( ( nFlag & BBF_EXACT) != 0) - dLinTol = LIN_TOL_MIN ; - ArcApproxer aAppr( dLinTol, dAngTolDeg, false, *this) ; - double dU ; - Point3d ptPos ; - while ( aAppr.GetPoint( dU, ptPos)) - b3Loc.Add( ptPos) ; - // se c'è estrusione, devo tenerne conto - if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) { - Point3d ptMinExtr = b3Loc.GetMin() + m_VtExtr * m_dThick ; - Point3d ptMaxExtr = b3Loc.GetMax() + m_VtExtr * m_dThick ; - b3Loc.Add( ptMinExtr) ; - b3Loc.Add( ptMaxExtr) ; - } + // richiamo della funzione generale + return GetBBox( GLOB_FRM, b3Loc, nFlag) ; - return true ; } //---------------------------------------------------------------------------- @@ -736,6 +716,102 @@ CurveArc::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const return false ; // assegno il box nel riferimento b3Ref.Reset() ; + + // ricavo il Frame3D solidale all'arco + Frame3d frArc; frArc.Set( m_PtCen, m_dAngCenDeg > 0 ? m_VtN : - m_VtN, m_VtS) ; + + // cordinate nel FrRef dei versori del sistema di riferimento dell'arco + Vector3d a = frArc.VersX() ; + a.ToGlob( frRef) ; + double ax = a.x ; + double ay = a.y ; + double az = a.z ; + + Vector3d b = frArc.VersY() ; + b.ToGlob( frRef) ; + double bx = b.x ; + double by = b.y ; + double bz = b.z ; + + Vector3d c = frArc.VersZ() ; + c.ToGlob( frRef) ; + double nx = c.x ; + double ny = c.y ; + double nz = c.z ; + + // vettore degli angoli e dei punti di estremi + PNTVECTOR vPoints ; + DBLVECTOR vdTheta ; + + // il punto iniziale e finale sono punti candidati per estremanti + Point3d ptS, ptE ; + GetPointD1D2( 0, FROM_PLUS, ptS) ; if ( ! abs( m_dAngCenDeg - 360) < EPS_SMALL) { GetPointD1D2( 1, FROM_MINUS, ptE) ; } + vPoints.push_back( ptS) ; if ( ! abs( m_dAngCenDeg - 360) < EPS_SMALL) { vPoints.push_back( ptE) ; } + + // angolo al centro, raggio e parametro Q + double dAngCenRad = m_dAngCenDeg * DEGTORAD ; + ptE.ToLoc( frArc) ; ptS.ToLoc( frArc) ; + double Q = ( ptE.z - ptS.z) / abs( dAngCenRad) ; + double dRad = m_dRad ; + + if ( abs( Q) < EPS_SMALL) { + if ( abs( ax) > EPS_SMALL) { + vdTheta.push_back( atan( bx / ax)) ; + vdTheta.push_back( vdTheta.back() > 0 ? vdTheta.back() + PIGRECO : vdTheta.back() - PIGRECO) ; + } + if ( abs( ay) > EPS_SMALL) { + vdTheta.push_back( atan( by / ay)) ; + vdTheta.push_back( vdTheta.back() > 0 ? vdTheta.back() + PIGRECO : vdTheta.back() - PIGRECO) ; + } + if ( abs( az) > EPS_SMALL) { + vdTheta.push_back( atan( bz / az)) ; + vdTheta.push_back( vdTheta.back() > 0 ? vdTheta.back() + PIGRECO : vdTheta.back() - PIGRECO) ; + } + } + else { + + vector Va ; Va.push_back( ax) ; Va.push_back( ay) ; Va.push_back( az) ; + vector Vb ; Vb.push_back( bx) ; Vb.push_back( by) ; Vb.push_back( bz) ; + vector Vn ; Vn.push_back( nx) ; Vn.push_back( ny) ; Vn.push_back( nz) ; + + for ( int i = 0 ; i < 3 ; i++) { + double delta = dRad * dRad * Va[i] * Va[i] - Q * Q * Vn[i] * Vn[i] + Vb[i] * Vb[i] * dRad * dRad ; + if ( delta > 0) { + double t1 = ( dRad * Va[i] + sqrt( delta)) / ( Q * Vn[i] - dRad * Vb[i]) ; + if ( abs( 1 - t1 * t1) > EPS_SMALL) { + vdTheta.push_back( atan( 2 * t1 / (1 - t1 * t1))) ; + vdTheta.push_back(vdTheta.back() > 0 ? vdTheta.back() + PIGRECO : vdTheta.back() - PIGRECO); + } + double t2 = ( dRad * Va[i] - sqrt( delta)) / ( Q * Vn[i] - dRad * Vb[i]) ; + if ( abs( 1 - t2 * t2) > EPS_SMALL){ + vdTheta.push_back( atan( 2 * t2 / ( 1 - t2 * t2))) ; + vdTheta.push_back( vdTheta.back() > 0 ? vdTheta.back() + PIGRECO : vdTheta.back() - PIGRECO) ; + } + } + } + } + + vdTheta.push_back( PIGRECO) ; + vdTheta.push_back( PIGRECO / 2) ; + vdTheta.push_back( 3 * PIGRECO / 2) ; + + for ( int i = 0 ; i < vdTheta.size() ; i++) { + double dTheta = vdTheta[i] > 0 ? vdTheta[i] : 2 * PIGRECO + vdTheta[i] ; + if ( dTheta < abs( dAngCenRad)) { + Point3d pt ; + GetPointD1D2( dTheta / ( abs( dAngCenRad)), FROM_MINUS, pt) ; + vPoints.push_back( pt) ; + } + } + + for (int i = 0; i < vPoints.size(); i++) { + vPoints[i].ToGlob( frRef) ; + b3Ref.Add( vPoints[i]) ; + } + + return true ; + + /* double dLinTol = LIN_TOL_APPROX ; double dAngTolDeg = ANG_TOL_APPROX_DEG ; if ( ( nFlag & BBF_EXACT) != 0) @@ -747,6 +823,9 @@ CurveArc::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const ptPos.ToGlob( frRef) ; b3Ref.Add( ptPos) ; } + + */ + // se c'è estrusione, devo tenerne conto if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) { Vector3d vtFrExtr = m_VtExtr ;