//---------------------------------------------------------------------------- // EgalTech 2014-2014 //---------------------------------------------------------------------------- // File : CurveLine.cpp Data : 06.05.14 Versione : 1.5e3 // Contenuto : Implementazione della classe Segmento di Linea. // // // // Modifiche : 16.04.13 DS Creazione modulo. // 06.05.14 DS Aggiunta Set per Pini, vtDir, Len e per Pini, AngDir, Len. // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "CurveLine.h" #include "GeoObjFactory.h" #include "NgeWriter.h" #include "NgeReader.h" #include "Voronoi.h" #include "/EgtDev/Include/EGkDistPointLine.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EgtNumUtils.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include using namespace std ; //---------------------------------------------------------------------------- GEOOBJ_REGISTER( CRV_LINE, NGE_C_LIN, CurveLine) ; //---------------------------------------------------------------------------- CurveLine::CurveLine( void) : m_nStatus( TO_VERIFY), m_PtStart(), m_PtEnd(), m_VtExtr(), m_dThick(), m_nTempProp{0,0}, m_dTempParam{0.0,0.0}, m_pVoronoiObj( nullptr) { } //---------------------------------------------------------------------------- CurveLine::~CurveLine( void) { ResetVoronoiObject() ; } //---------------------------------------------------------------------------- bool CurveLine::Set( const Point3d& ptStart, const Point3d& ptEnd) { // assegno i dati m_PtStart = ptStart ; m_PtEnd = ptEnd ; m_nStatus = TO_VERIFY ; // imposto ricalcolo di Voronoi ResetVoronoiObject() ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; return Validate() ; } //---------------------------------------------------------------------------- bool CurveLine::SetPVL( const Point3d& ptStart, const Vector3d& vtDir, double dLen) { // assegno i dati m_PtStart = ptStart ; Vector3d vtDelta = vtDir ; if ( ! vtDelta.Normalize()) return false ; vtDelta *= dLen ; m_PtEnd = ptStart + vtDelta ; m_nStatus = TO_VERIFY ; // imposto ricalcolo di Voronoi ResetVoronoiObject() ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; return Validate() ; } //---------------------------------------------------------------------------- bool CurveLine::SetPDL( const Point3d& ptStart, double dDirAngDeg, double dLen) { // assegno i dati m_PtStart = ptStart ; Vector3d vtDelta ; vtDelta = FromPolar( dLen, dDirAngDeg) ; m_PtEnd = ptStart + vtDelta ; m_nStatus = TO_VERIFY ; // imposto ricalcolo di Voronoi ResetVoronoiObject() ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; return Validate() ; } //---------------------------------------------------------------------------- CurveLine* CurveLine::Clone( void) const { // alloco oggetto CurveLine* pCrv = new( nothrow) CurveLine ; if ( pCrv != nullptr) { if ( ! pCrv->CopyFrom( *this)) { delete pCrv ; return nullptr ; } } return pCrv ; } //---------------------------------------------------------------------------- bool CurveLine::CopyFrom( const IGeoObj* pGObjSrc) { const CurveLine* pCL = GetBasicCurveLine( pGObjSrc) ; if ( pCL == nullptr) return false ; return CopyFrom( *pCL) ; } //---------------------------------------------------------------------------- bool CurveLine::CopyFrom( const CurveLine& clSrc) { if ( &clSrc == this) return true ; m_VtExtr = clSrc.m_VtExtr ; m_dThick = clSrc.m_dThick ; m_nTempProp[0] = clSrc.m_nTempProp[0] ; m_nTempProp[1] = clSrc.m_nTempProp[1] ; m_dTempParam[0] = clSrc.m_dTempParam[0] ; m_dTempParam[1] = clSrc.m_dTempParam[1] ; return Set( clSrc.m_PtStart, clSrc.m_PtEnd) ; } //---------------------------------------------------------------------------- GeoObjType CurveLine::GetType( void) const { return static_cast( GEOOBJ_GETTYPE( CurveLine)) ; } //---------------------------------------------------------------------------- const string& CurveLine::GetTitle( void) const { static const string sTitle = "Line" ; return sTitle ; } //---------------------------------------------------------------------------- bool CurveLine::Dump( string& sOut, bool bMM, const char* szNewLine) const { // dati generali di una curva if ( ! CurveDump( *this, sOut, bMM, szNewLine)) return false ; // parametri : sono già compresi nei dati generali (PS e PE) return true ; } //---------------------------------------------------------------------------- int CurveLine::GetNgeId( void) const { return GEOOBJ_GETNGEID( CurveLine) ; } //---------------------------------------------------------------------------- bool CurveLine::Save( NgeWriter& ngeOut) const { // parametri : punti iniziale e finale if ( ! ngeOut.WritePoint( m_PtStart, ";")) return false ; if ( ! ngeOut.WritePoint( m_PtEnd, ";", true)) return false ; // da versione 1008 : linea con VtEstrusione e Spessore if ( ! ngeOut.WriteVector( m_VtExtr, ";")) return false ; if ( ! ngeOut.WriteDouble( m_dThick, ";", true)) return false ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::Load( NgeReader& ngeIn) { // imposto ricalcolo della grafica m_OGrMgr.Reset() ; // leggo la prossima linea if ( ! ngeIn.ReadPoint( m_PtStart, ";")) return false ; if ( ! ngeIn.ReadPoint( m_PtEnd, ";", true)) return false ; // da versione 1008 : linea con VtEstrusione e Spessore if ( ngeIn.GetFileVersion() >= NGE_VER_1008) { if ( ! ngeIn.ReadVector( m_VtExtr, ";")) return false ; if ( ! ngeIn.ReadDouble( m_dThick, ";", true)) return false ; } // eseguo validazione return Validate() ; } //---------------------------------------------------------------------------- bool CurveLine::GetLocalBBox( BBox3d& b3Loc, int nFlag) const { // verifico lo stato if ( m_nStatus != OK) return false ; // assegno il box in locale b3Loc.Set( m_PtStart, m_PtEnd) ; // 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) ; } return true ; } //---------------------------------------------------------------------------- bool CurveLine::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const { // verifico lo stato if ( m_nStatus != OK) return false ; // verifico validità del frame if ( frRef.GetType() == Frame3d::ERR) return false ; // porto gli estremi nel riferimento passato Point3d ptFrStart = m_PtStart ; ptFrStart.ToGlob( frRef) ; Point3d ptFrEnd = m_PtEnd ; ptFrEnd.ToGlob( frRef) ; // assegno il box nel riferimento b3Ref.Set( ptFrStart, ptFrEnd) ; // se c'è estrusione, devo tenerne conto if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) { Vector3d vtFrExtr = m_VtExtr ; vtFrExtr.ToGlob( frRef) ; Point3d ptMinExtr = b3Ref.GetMin() + vtFrExtr * m_dThick ; Point3d ptMaxExtr = b3Ref.GetMax() + vtFrExtr * m_dThick ; b3Ref.Add( ptMinExtr) ; b3Ref.Add( ptMaxExtr) ; } return true ; } //---------------------------------------------------------------------------- bool CurveLine::Validate( void) { if ( m_nStatus == TO_VERIFY) m_nStatus = ( m_PtStart.IsValid() && m_PtEnd.IsValid() && ! AreSamePointApprox( m_PtStart, m_PtEnd) ? OK : ERR) ; return ( m_nStatus == OK) ; } //---------------------------------------------------------------------------- bool CurveLine::IsFlat( Plane3d& plPlane, bool bUseExtrusion, double dToler) const { // verifico lo stato if ( m_nStatus != OK) return false ; // assegno dati piano bool bFlat ; Vector3d vtN ; if ( ! bUseExtrusion || m_VtExtr.IsSmall()) { vtN = FromUprightOrtho( m_PtEnd - m_PtStart) ; bFlat = true ; } else { Vector3d vtDir ; GetStartDir( vtDir) ; vtN = m_VtExtr - ( m_VtExtr * vtDir) * vtDir ; if ( ! vtN.Normalize()) vtN = FromUprightOrtho( vtDir) ; bFlat = ( AreSameOrOppositeVectorApprox( m_VtExtr, vtN)) ; } plPlane.Set( 0.5 * ( m_PtStart + m_PtEnd), vtN) ; // ritorno conferma return bFlat ; } //---------------------------------------------------------------------------- bool CurveLine::GetStartPoint( Point3d& ptStart) const { // verifico lo stato if ( m_nStatus != OK) return false ; // assegno il punto ptStart = m_PtStart ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::GetEndPoint( Point3d& ptEnd) const { // verifico lo stato if ( m_nStatus != OK) return false ; // assegno il punto ptEnd = m_PtEnd ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::GetMidPoint( Point3d& ptMid) const { // verifico lo stato if ( m_nStatus != OK) return false ; // assegno il punto ptMid = Media( m_PtStart, m_PtEnd, 0.5) ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::GetStartDir( Vector3d& vtDir) const { // verifico lo stato if ( m_nStatus != OK) return false ; // calcolo la direzione vtDir = m_PtEnd - m_PtStart ; return vtDir.Normalize() ; } //---------------------------------------------------------------------------- bool CurveLine::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1, Vector3d* pvtDer2) const { // verifico lo stato if ( m_nStatus != OK) return false ; // il parametro U deve essere compreso tra 0 e 1 dU = Clamp( dU, 0., 1.) ; // calcolo del punto ptPos = Media( m_PtStart, m_PtEnd, dU) ; // calcolo della derivata prima if ( pvtDer1 != nullptr) *pvtDer1 = m_PtEnd - m_PtStart ; // derivata seconda nulla if ( pvtDer2 != nullptr && pvtDer1 != nullptr) pvtDer2->Set( 0, 0, 0) ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::GetLength( double& dLen) const { // verifico lo stato if ( m_nStatus != OK) return false ; // la lunghezza è la distanza tra gli estremi dLen = Dist( m_PtStart, m_PtEnd) ; return ( dLen > EPS_SMALL) ; } //---------------------------------------------------------------------------- bool CurveLine::GetLengthAtParam( double dU, double& dLen) const { // verifico lo stato if ( m_nStatus != OK) return false ; // fuori dominio del parametro -> errore if ( dU < 0 - EPS_PARAM) return false ; if ( dU > ( 1 + EPS_PARAM)) return false ; // inizio if ( dU < 0 + EPS_PARAM) { dLen = 0 ; return true ; } // la lunghezza totale è la distanza tra gli estremi double dTotLen = Dist( m_PtStart, m_PtEnd) ; // fine if ( dU > 1 - EPS_PARAM) { dLen = dTotLen ; return true ; } // posizione intermedia dLen = dU * dTotLen ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::GetParamAtLength( double dLen, double& dU) const { // verifico lo stato if ( m_nStatus != OK) return false ; // se prima di inizio, errore if ( dLen < - EPS_SMALL) return false ; // inizio if ( dLen < EPS_SMALL) { dU = 0 ; return true ; } // la lunghezza totale è la distanza tra gli estremi double dTotLen = Dist( m_PtStart, m_PtEnd) ; // se dopo fine, errore if ( dLen > dTotLen + EPS_SMALL) return false ; // fine if ( dLen > dTotLen - EPS_SMALL) { dU = 1 ; return true ; } // posizione intermedia dU = dLen / dTotLen ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::IsPointOn( const Point3d& ptP, double dTol) const { double dSqDist ; dTol = max( dTol, EPS_ZERO) ; return ( DistPointLine( ptP, *this).GetSqDist( dSqDist) && dSqDist < dTol * dTol) ; } //---------------------------------------------------------------------------- bool CurveLine::GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol) const { double dSqDist ; dTol = max( dTol, EPS_ZERO) ; DistPointLine DPL( ptP, *this) ; if ( ! DPL.GetSqDist( dSqDist) || dSqDist > dTol * dTol) return false ; return DPL.GetParamAtMinDistPoint( dPar) ; } //---------------------------------------------------------------------------- bool CurveLine::GetLengthAtPoint( const Point3d& ptP, double& dLen, double dTol) const { double dU ; if ( ! GetParamAtPoint( ptP, dU, dTol)) return false ; return GetLengthAtParam( dU, dLen) ; } //---------------------------------------------------------------------------- bool CurveLine::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const { // pulisco la polilinea PL.Clear() ; // la curva deve essere validata if ( m_nStatus != OK) return false ; // inserisco gli estremi PL.AddUPoint( 0, m_PtStart) ; PL.AddUPoint( 1, m_PtEnd) ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const { // pulisco la polilinea PA.Clear() ; // la curva deve essere validata if ( m_nStatus != OK) return false ; // determinazione versore normale al piano di riferimento Vector3d vtNref = ( m_VtExtr.IsSmall() ? Z_AX : m_VtExtr) ; // assegno estrusione al poliarco PA.SetExtrusion( vtNref) ; // inserisco gli estremi return ( PA.AddUPoint( 0, m_PtStart, 0) && PA.AddUPoint( 1, m_PtEnd, 0)) ; } //---------------------------------------------------------------------------- ICurve* CurveLine::CopyParamRange( double dUStart, double dUEnd) const { // i parametri start ed end devono essere compresi nel dominio parametrico della curva if ( dUStart < - EPS_PARAM || dUStart > 1 + EPS_PARAM || dUEnd < - EPS_PARAM || dUEnd > 1 + EPS_PARAM) return nullptr ; // se il parametro start supera quello di end, essendo la linea una curva aperta, errore if ( dUStart > dUEnd - EPS_PARAM) return nullptr ; // creo la linea copia PtrOwner pCopy( Clone()) ; if ( IsNull( pCopy)) return nullptr ; // eseguo il trim if ( ! pCopy->TrimStartEndAtParam( dUStart, dUEnd)) return nullptr ; return ( ::Release( pCopy)) ; } //---------------------------------------------------------------------------- bool CurveLine::Invert( void) { // verifico lo stato if ( m_nStatus != OK) return false ; // inverto i punti estremi swap( m_PtStart, m_PtEnd) ; // imposto ricalcolo di Voronoi ResetVoronoiObject() ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::SimpleOffset( double dDist, int nType, double dMaxAngExt) { // verifico lo stato if ( m_nStatus != OK) return false ; // determinazione versore normale al piano di offset Vector3d vtNorm = Z_AX ; if ( ! m_VtExtr.IsSmall()) vtNorm = m_VtExtr ; // calcolo il versore direzione linea nel piano perpendicolare alla normale Vector3d vtDir = m_PtEnd - m_PtStart ; vtDir -= vtDir * vtNorm * vtNorm ; if ( ! vtDir.Normalize()) return false ; // calcolo il versore ortogonale dal lato destro (offset positivo) vtDir.Rotate( vtNorm, 0, -1) ; // rotazione CW di 90 deg // sposto i punti m_PtStart += vtDir * dDist ; m_PtEnd += vtDir * dDist ; // imposto ricalcolo di Voronoi ResetVoronoiObject() ; // con i controlli sopra fatti rimane validata, ma la grafica va ricalcolata m_OGrMgr.Reset() ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::ModifyStart( const Point3d& ptNewStart) { // verifico lo stato if ( m_nStatus != OK) return false ; // la linea modificata deve essere ancora valida if ( AreSamePointApprox( ptNewStart, m_PtEnd)) return false ; // assegno il nuovo inizio m_PtStart = ptNewStart ; // imposto ricalcolo di Voronoi ResetVoronoiObject() ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::ModifyEnd( const Point3d& ptNewEnd) { // verifico lo stato if ( m_nStatus != OK) return false ; // la linea modificata deve essere ancora valida if ( AreSamePointApprox( m_PtStart, ptNewEnd)) return false ; // assegno la nuova fine m_PtEnd = ptNewEnd ; // imposto ricalcolo di Voronoi ResetVoronoiObject() ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::TrimStartAtParam( double dUTrim) { // riporto i parametri nel loro range dUTrim = Clamp( dUTrim, 0., 1.) ; // recupero lunghezza double dLen ; if ( ! GetLength( dLen)) return false ; // utilizzo il trim sulle lunghezze return TrimStartAtLen( dUTrim * dLen) ; } //---------------------------------------------------------------------------- bool CurveLine::TrimEndAtParam( double dUTrim) { // riporto i parametri nel loro range dUTrim = Clamp( dUTrim, 0., 1.) ; // recupero lunghezza double dLen ; if ( ! GetLength( dLen)) return false ; // utilizzo il trim sulle lunghezze return TrimEndAtLen( dUTrim * dLen) ; } //---------------------------------------------------------------------------- bool CurveLine::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim) { // i parametri start ed end devono essere compresi nel dominio parametrico della curva if ( dUStartTrim < - EPS_PARAM || dUStartTrim > 1 + EPS_PARAM || dUEndTrim < - EPS_PARAM || dUEndTrim > 1 + EPS_PARAM) return false ; // verifico che i trim non cancellino interamente la curva if ( dUStartTrim > dUEndTrim - EPS_PARAM) return false ; // trim finale if ( ! TrimEndAtParam( dUEndTrim)) return false ; // trim iniziale con il parametro opportunamente ricalcolato double dNewUStartTrim = dUStartTrim / dUEndTrim ; return TrimStartAtParam( dNewUStartTrim) ; } //---------------------------------------------------------------------------- bool CurveLine::TrimStartAtLen( double dLenTrim) { // lunghezze negative vengono considerate nulle dLenTrim = max( dLenTrim, 0.) ; // verifico che sia abbastanza lunga double dLen ; if ( ! GetLength( dLen)) return false ; if ( ( dLen - dLenTrim) < EPS_SMALL) return false ; // eseguo il trim if ( dLenTrim > EPS_ZERO) m_PtStart = Media( m_PtStart, m_PtEnd, ( dLenTrim / dLen)) ; // imposto ricalcolo di Voronoi ResetVoronoiObject() ; // con i controlli sopra fatti rimane validata, ma la grafica va ricalcolata m_OGrMgr.Reset() ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::TrimEndAtLen( double dLenTrim) { // lunghezze negative vengono considerate nulle dLenTrim = max( dLenTrim, 0.) ; // verifico che sia abbastanza lunga double dLen ; if ( ! GetLength( dLen)) return false ; if ( dLenTrim < EPS_SMALL) return false ; // eseguo il trim if ( ( dLen - dLenTrim) > EPS_ZERO) m_PtEnd = Media( m_PtStart, m_PtEnd, ( dLenTrim / dLen)) ; // imposto ricalcolo di Voronoi ResetVoronoiObject() ; // con i controlli sopra fatti rimane validata, ma la grafica va ricalcolata m_OGrMgr.Reset() ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::ExtendStartByLen( double dLenExt) { // la lunghezza deve essere positiva if ( dLenExt < - EPS_ZERO) return false ; // versore della linea Vector3d vtDir ; if ( ! GetStartDir( vtDir)) return false ; // sposto il punto iniziale m_PtStart -= vtDir * dLenExt ; // imposto ricalcolo di Voronoi ResetVoronoiObject() ; // con i controlli sopra fatti rimane validata, ma la grafica va ricalcolata m_OGrMgr.Reset() ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::ExtendEndByLen( double dLenExt) { // la lunghezza deve essere positiva if ( dLenExt < - EPS_ZERO) return false ; // versore della linea Vector3d vtDir ; if ( ! GetEndDir( vtDir)) return false ; // sposto il punto finale m_PtEnd += vtDir * dLenExt ; // imposto ricalcolo di Voronoi ResetVoronoiObject() ; // con i controlli sopra fatti rimane validata, ma la grafica va ricalcolata m_OGrMgr.Reset() ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::Translate( const Vector3d& vtMove) { // la curva deve essere validata if ( m_nStatus != OK) return false ; // traslo Voronoi if ( m_pVoronoiObj != nullptr) m_pVoronoiObj->Translate( vtMove) ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; // traslo i punti estremi m_PtStart.Translate( vtMove) ; m_PtEnd.Translate( vtMove) ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) { // la curva deve essere validata if ( m_nStatus != OK) return false ; // verifico validità dell'asse di rotazione if ( vtAx.IsSmall()) return false ; // ruoto Voronoi if ( m_pVoronoiObj != nullptr) m_pVoronoiObj->Rotate( ptAx, vtAx, dCosAng, dSinAng) ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; // ruoto i punti estremi m_PtStart.Rotate( ptAx, vtAx, dCosAng, dSinAng) ; m_PtEnd.Rotate( ptAx, vtAx, dCosAng, dSinAng) ; // ruoto il vettore estrusione m_VtExtr.Rotate( vtAx, dCosAng, dSinAng) ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) { // la curva deve essere validata if ( m_nStatus != OK) return false ; // verifico non sia nulla if ( abs( dCoeffX) < EPS_ZERO && abs( dCoeffY) < EPS_ZERO && abs( dCoeffZ) < EPS_ZERO) return false ; // verifico che la scalatura dei punti non li porti a coincidere Point3d ptNewStart = m_PtStart ; ptNewStart.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; Point3d ptNewEnd = m_PtEnd ; ptNewEnd.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; if ( AreSamePointApprox( ptNewStart, ptNewEnd)) return false ; // imposto ricalcolo di Voronoi ResetVoronoiObject() ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; // uso i punti estremi m_PtStart = ptNewStart ; m_PtEnd = ptNewEnd ; // scalo vettore estrusione, lo normalizzo e aggiusto spessore m_VtExtr.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; double dLen = m_VtExtr.Len() ; if ( dLen > EPS_ZERO) { m_VtExtr /= dLen ; m_dThick *= dLen ; } m_nStatus = TO_VERIFY ; return Validate() ; } //---------------------------------------------------------------------------- bool CurveLine::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) { // la curva deve essere validata if ( m_nStatus != OK) return false ; // verifico validità del piano di specchiatura if ( vtNorm.IsSmall()) return false ; // imposto ricalcolo di Voronoi ResetVoronoiObject() ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; // specchio i punti estremi m_PtStart.Mirror( ptOn, vtNorm) ; m_PtEnd.Mirror( ptOn, vtNorm) ; // specchio il vettore estrusione m_VtExtr.Mirror( vtNorm) ; return true ; } //---------------------------------------------------------------------------- bool CurveLine::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff) { // la curva deve essere validata if ( m_nStatus != OK) return false ; // verifico validità dei parametri if ( vtNorm.IsSmall() || vtDir.IsSmall()) return false ; // imposto ricalcolo di Voronoi ResetVoronoiObject() ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; // eseguo scorrimento dei punti estremi m_PtStart.Shear( ptOn, vtNorm, vtDir, dCoeff) ; m_PtEnd.Shear( ptOn, vtNorm, vtDir, dCoeff) ; // eseguo scorrimento del vettore estrusione, lo normalizzo e aggiusto spessore m_VtExtr.Shear( vtNorm, vtDir, dCoeff) ; double dLen = m_VtExtr.Len() ; if ( dLen > EPS_ZERO) { m_VtExtr /= dLen ; m_dThick *= dLen ; } return true ; } //---------------------------------------------------------------------------- bool CurveLine::ToGlob( const Frame3d& frRef) { // la curva deve essere validata if ( m_nStatus != OK) return false ; // verifico validità del frame if ( frRef.GetType() == Frame3d::ERR) return false ; // se frame identità, non devo fare alcunché if ( IsGlobFrame( frRef)) return true ; // trasformo Voronoi if ( m_pVoronoiObj != nullptr) m_pVoronoiObj->ToGlob( frRef) ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; // trasformo i punti estremi e il vettore estrusione return ( m_PtStart.ToGlob( frRef) && m_PtEnd.ToGlob( frRef) && m_VtExtr.ToGlob( frRef)) ; } //---------------------------------------------------------------------------- bool CurveLine::ToLoc( const Frame3d& frRef) { // la curva deve essere validata if ( m_nStatus != OK) return false ; // verifico validità del frame if ( frRef.GetType() == Frame3d::ERR) return false ; // se frame identità, non devo fare alcunché if ( IsGlobFrame( frRef)) return true ; // trasformo Voronoi if ( m_pVoronoiObj != nullptr) m_pVoronoiObj->ToLoc( frRef) ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; // trasformo i punti estremi e il vettore estrusione return ( m_PtStart.ToLoc( frRef) && m_PtEnd.ToLoc( frRef) && m_VtExtr.ToLoc( frRef)) ; } //---------------------------------------------------------------------------- bool CurveLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) { // la curva deve essere validata if ( m_nStatus != OK) return false ; // verifico validità dei frame if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR) return false ; // se i due riferimenti coincidono, non devo fare alcunché if ( AreSameFrame( frOri, frDest)) return true ; // trasformo Voronoi if ( m_pVoronoiObj != nullptr) m_pVoronoiObj->LocToLoc( frOri, frDest) ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; // trasformo i punti estremi e il vettore estrusione return ( m_PtStart.LocToLoc( frOri, frDest) && m_PtEnd.LocToLoc( frOri, frDest) && m_VtExtr.LocToLoc( frOri, frDest)) ; } //---------------------------------------------------------------------------- bool CurveLine::CalcPointParamPosiz( const Point3d& ptP, bool bOnXY, double& dU, int& nPos) const { // vettore linea nel piano XY Vector3d vtDir = m_PtEnd - m_PtStart ; if ( bOnXY) vtDir.z = 0 ; if ( vtDir.IsSmall()) return false ; // calcolo parametro dU = ( ptP - m_PtStart) * vtDir / vtDir.SqLen() ; // verifica posizione intersezione su linea nPos = ICurve::PP_NULL ; // fuori if ( ( dU * vtDir).IsSmall()) { nPos = ICurve::PP_START ; // vicino a inizio dU = max( dU, 0.) ; } else if ( (( 1 - dU) * vtDir).IsSmall()) { nPos = ICurve::PP_END ; // vicino a fine dU = min( dU, 1.) ; } else if ( dU > 0 && dU < 1) nPos = ICurve::PP_MID ; // nell'interno return true ; } //---------------------------------------------------------------------------- bool CurveLine::CalcVoronoiObject() const { if ( m_nStatus != OK) return false ; // creo oggetto vroni con la curva m_pVoronoiObj = new( std::nothrow) Voronoi( this, false) ; if ( m_pVoronoiObj == nullptr) return false ; return true ; } //---------------------------------------------------------------------------- Voronoi* CurveLine::GetVoronoiObject() const { if ( m_nStatus != OK) return nullptr ; // se non è stato calcolato, lo calcolo if ( m_pVoronoiObj == nullptr) CalcVoronoiObject() ; // restituisco Voronoi return m_pVoronoiObj ; } //---------------------------------------------------------------------------- void CurveLine::ResetVoronoiObject() const { if ( m_pVoronoiObj != nullptr) delete m_pVoronoiObj ; m_pVoronoiObj = nullptr ; }