diff --git a/CurveArc.cpp b/CurveArc.cpp index abd126a..f78f842 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -25,6 +25,7 @@ #include "/EgtDev/Include/EGkAngle.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkUiUnits.h" +#include "/EgtDev/Include/ENkPolynomialRoots.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include @@ -701,7 +702,6 @@ CurveArc::GetLocalBBox( BBox3d& b3Loc, int nFlag) const { // richiamo della funzione generale return GetBBox( GLOB_FRM, b3Loc, nFlag) ; - } //---------------------------------------------------------------------------- @@ -717,115 +717,87 @@ CurveArc::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const // 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) ; + // ricavo il riferimento intrinseco dell'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 ; + // pendenza intrinseca + double dPitch = m_dDeltaN * ( m_dAngCenDeg > 0 ? 1 : -1) / abs( m_dAngCenDeg * DEGTORAD) ; - 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 ; + // cordinate nel frRef dei versori del sistema di riferimento dell'arco + Vector3d vtXRef = frArc.VersX() ; + vtXRef.ToGlob( frRef) ; + Vector3d vtYRef = frArc.VersY() ; + vtYRef.ToGlob( frRef) ; + Vector3d vtZRef = frArc.VersZ() ; + vtZRef.ToGlob( frRef) ; // 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) ; } + GetStartPoint( ptS) ; + ptS.ToGlob( frRef) ; + b3Ref.Add( ptS) ; + GetEndPoint( ptE) ; + ptE.ToGlob( frRef) ; + b3Ref.Add( 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 ; + // vettore degli angoli dei punti candidati estremi + DBLVECTOR vdTheta ; - 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) ; + // arco piatto + if ( abs( dPitch) < EPS_SMALL) { + double dAngXDeg = atan2( vtYRef.x, vtXRef.x) * RADTODEG ; + bool bAngXSmall = (abs( dAngXDeg) <= EPS_ANG_ZERO) ; + if ( ! bAngXSmall) { + vdTheta.push_back( dAngXDeg) ; + vdTheta.push_back( dAngXDeg + ANG_STRAIGHT) ; } - if ( abs( ay) > EPS_SMALL) { - vdTheta.push_back( atan( by / ay)) ; - vdTheta.push_back( vdTheta.back() > 0 ? vdTheta.back() + PIGRECO : vdTheta.back() - PIGRECO) ; + double dAngYDeg = atan2( vtYRef.y, vtXRef.y) * RADTODEG ; + bool bAngYSmall = (abs( dAngYDeg) <= EPS_ANG_ZERO) ; + if ( ! bAngYSmall) { + vdTheta.push_back( dAngYDeg) ; + vdTheta.push_back( dAngYDeg + ANG_STRAIGHT) ; } - if ( abs( az) > EPS_SMALL) { - vdTheta.push_back( atan( bz / az)) ; - vdTheta.push_back( vdTheta.back() > 0 ? vdTheta.back() + PIGRECO : vdTheta.back() - PIGRECO) ; + double dAngZDeg = atan2( vtYRef.z, vtXRef.z) * RADTODEG ; + bool bAngZSmall = (abs( dAngZDeg) <= EPS_ANG_ZERO) ; + if ( ! bAngZSmall) { + vdTheta.push_back( dAngZDeg) ; + vdTheta.push_back( dAngZDeg + ANG_STRAIGHT) ; } + if ( bAngXSmall || bAngYSmall || bAngZSmall) + vdTheta.push_back( ANG_STRAIGHT) ; } + // altrimenti arco di elica 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) ; + for ( int i = 0 ; i < 3 ; ++ i) { + DBLVECTOR vdPoly{ m_dRad * vtYRef.v[i] + dPitch * vtZRef.v[i], + - 2 * m_dRad * vtXRef.v[i], + - m_dRad * vtYRef.v[i] + dPitch * vtZRef.v[i]} ; + DBLVECTOR vdRoot ; + int nRoot = PolynomialRoots( 2, vdPoly, vdRoot) ; + for ( int i = 0 ; i < nRoot ; ++ i) { + double dAngDeg = atan2( 2 * vdRoot[i], (1 - vdRoot[i] * vdRoot[i])) * RADTODEG ; + if ( abs( dAngDeg) > EPS_ANG_ZERO) { + vdTheta.push_back( dAngDeg) ; + vdTheta.push_back( dAngDeg + ANG_STRAIGHT) ; } + else + vdTheta.push_back( ANG_STRAIGHT) ; } } } - 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) ; + // verifica degli angoli sull'arco ed eventuale considerazione dei punti + for ( int i = 0 ; i < int( vdTheta.size()) ; ++ i) { + double dTheta = ( vdTheta[i] > 0 ? vdTheta[i] : vdTheta[i] + ANG_FULL) ; + if ( dTheta < abs( m_dAngCenDeg)) { + Point3d ptP ; + GetPointD1D2( dTheta / ( abs( m_dAngCenDeg)), FROM_MINUS, ptP) ; + ptP.ToGlob( frRef) ; + b3Ref.Add( ptP) ; } } - - 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) - dLinTol = LIN_TOL_MIN ; - ArcApproxer aAppr( dLinTol, dAngTolDeg, false, *this) ; - double dU ; - Point3d ptPos ; - while ( aAppr.GetPoint( dU, ptPos)) { - 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 ; diff --git a/CurveAux.cpp b/CurveAux.cpp index 0c401aa..239b8df 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -30,9 +30,8 @@ using namespace std ; bool IsClosed( const ICurve& crvC) { - Point3d ptStart ; - Point3d ptEnd ; - return ( crvC.GetStartPoint( ptStart) && crvC.GetEndPoint( ptEnd) && AreSamePointApprox( ptStart, ptEnd)) ; + Point3d ptStart, ptEnd ; + return ( crvC.GetStartPoint( ptStart) && crvC.GetEndPoint( ptEnd) && AreSamePointApprox( ptStart, ptEnd)) ; } //---------------------------------------------------------------------------- diff --git a/SurfTriMeshBooleans.cpp b/SurfTriMeshBooleans.cpp index 6a4f967..b8a27ad 100644 --- a/SurfTriMeshBooleans.cpp +++ b/SurfTriMeshBooleans.cpp @@ -694,7 +694,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT // Elimino loop interni non validi bool bDouble = true ; for ( int nInnLoop = 0 ; nInnLoop < int( vInnerLoop.size()) ; ++ nInnLoop) { - if ( int( cvClosedChain[vInnerLoop[nInnLoop]].size()) > 2) { + if ( cvClosedChain[vInnerLoop[nInnLoop]].size() > 2) { bDouble = false ; break ; } @@ -820,6 +820,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT } } } + // Divido i loop che si autointercettano int nInitialLoopNum = int( vPolygons.size()) ; for ( int nL = 1 ; nL < nInitialLoopNum ; ++ nL) { @@ -868,8 +869,8 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT itSt2 = LoopPointList.emplace( itEn2, vAddingPointWithOrder[nPi]) ; } } + // Spezzo i loop autointersecantesi - POLYLINEVECTOR vAuxPolygons ; vAuxPolygons.emplace_back( vPolygons[nL]) ; @@ -917,7 +918,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT } bool bReplaced = false ; for ( int nl = 0 ; nl < int( vAuxPolygons.size()) ; ++ nl) { - if ( true/*vAuxPolygons.GetAreaXY(double& dArea)*/) { + if ( true) { if ( ! bReplaced) { vPolygons[nL].Clear() ; Point3d ptP ;