//---------------------------------------------------------------------------- // EgalTech 2013-2014 //---------------------------------------------------------------------------- // File : CurveByInterp.cpp Data : 05.08.14 Versione : 1.5h1 // Contenuto : Implementazione della classe CurveByInterp, per creare // una curva mediante interpolazione di punti. // // // Modifiche : 05.08.14 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "CalcDerivate.h" #include "CurveBezier.h" #include "CurveComposite.h" #include "/EgtDev/Include/EGkCurveByInterp.h" #include "/EgtDev/Include/EGkBiArcs.h" #include "/EgtDev/Include/EgtPointerOwner.h" //---------------------------------------------------------------------------- bool CurveByInterp::Reset( void) { // pulisco i diversi vettori m_vPnt.clear() ; m_vPar.clear() ; m_vPrevDer.clear() ; m_vNextDer.clear() ; return true ; } //---------------------------------------------------------------------------- bool CurveByInterp::AddPoint( const Point3d& ptP) { // se il punto coincide con il precedente, lo salto if ( ! m_vPnt.empty() && AreSamePointApprox( ptP, m_vPnt.back())) return false ; // aggiungo il punto try { m_vPnt.push_back( ptP) ; } catch ( ...) { return false ; } return true ; } //---------------------------------------------------------------------------- ICurve* CurveByInterp::GetCurve( int nMethod, int nType) { // se richieste curve di Bezier cubiche (ottenute da interpolazione con Nurbs) if ( nType == CUBIC_BEZIERS_LONG) { // creo la curva composita PtrOwner pCrv ; //pCrv.Set( InterpolatePointSetWithBezier( m_vPnt, 50 * EPS_SMALL, 50)) ; //debug pCrv.Set( InterpolatePointSetWithBezier( m_vPnt, 0.1, 100)) ; if ( IsNull(pCrv) || ! pCrv->IsValid()) return nullptr ; return Release( pCrv) ; } // numero di punti int nSize = int( m_vPnt.size()) ; // sono necessari almeno due punti if ( nSize < 2) return nullptr ; // calcolo le distanze tra i punti per derivarne i parametri m_vPar.reserve( nSize) ; double dPar = 0 ; m_vPar.push_back( dPar) ; for ( int i = 1 ; i < nSize ; ++ i) { double dDist = Dist( m_vPnt[i-1], m_vPnt[i]) ; dPar += dDist ; m_vPar.push_back( dPar) ; } // calcolo le tangenti if ( nMethod == BESSEL) { if ( ! CalcBesselTangents()) return nullptr ; } else { if ( ! CalcAkimaTangents( nMethod == AKIMA_CORNER)) return nullptr ; } // se richiesti biarchi if ( nType == BIARCS) { // creo la curva composita PtrOwner pCrvCompo( CreateBasicCurveComposite()) ; if ( IsNull( pCrvCompo)) return nullptr ; // ciclo sugli intervalli for ( int i = 1 ; i < int( m_vPnt.size()) ; ++ i) { // creo un biarco per ogni intervallo double dDirStartDeg ; m_vNextDer[i-1].ToSpherical( nullptr, nullptr, &dDirStartDeg) ; double dDirEndDeg ; m_vPrevDer[i].ToSpherical( nullptr, nullptr, &dDirEndDeg) ; ICurve* pCrv = GetBiArc( m_vPnt[i-1], dDirStartDeg, m_vPnt[i], dDirEndDeg, 0.5) ; if ( ! pCrvCompo->AddCurve( pCrv)) return nullptr ; } return ::Release( pCrvCompo) ; } // se richieste curve di Bezier cubiche if ( nType == CUBIC_BEZIERS) { // creo la curva composita PtrOwner pCrvCompo( CreateBasicCurveComposite()) ; if ( IsNull( pCrvCompo)) return nullptr ; // ciclo sugli intervalli for ( int i = 1 ; i < int( m_vPnt.size()) ; ++ i) { // creo una curva di Bezier cubica per ogni intervallo PtrOwner pCBez( CreateBasicCurveBezier()) ; if ( IsNull( pCBez)) return nullptr ; pCBez->Init( 3, false) ; pCBez->SetControlPoint( 0, m_vPnt[i-1]) ; pCBez->SetControlPoint( 1, m_vPnt[i-1] + ( m_vPar[i] - m_vPar[i-1]) / 3 * m_vNextDer[i-1]) ; pCBez->SetControlPoint( 2, m_vPnt[i] - ( m_vPar[i] - m_vPar[i-1]) / 3 * m_vPrevDer[i]) ; pCBez->SetControlPoint( 3, m_vPnt[i]) ; if ( ! pCrvCompo->AddCurve( ::Release( pCBez))) return nullptr ; } return ::Release( pCrvCompo) ; } return nullptr ; } //---------------------------------------------------------------------------- bool CurveByInterp::CalcAkimaTangents( bool bDetectCorner) { return ComputeAkimaTangents( bDetectCorner, m_vPar, m_vPnt, m_vPrevDer, m_vNextDer) ; } //---------------------------------------------------------------------------- bool CurveByInterp::CalcBesselTangents( void) { return ComputeBesselTangents( m_vPar, m_vPnt, m_vPrevDer, m_vNextDer) ; }