]> Creatis software - cpPlugins.git/blob - lib/cpExtensions/Algorithms/BezierCurveFunction.hxx
yet another refactoring
[cpPlugins.git] / lib / cpExtensions / Algorithms / BezierCurveFunction.hxx
1 // -------------------------------------------------------------------------
2 // @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
3 // -------------------------------------------------------------------------
4
5 #ifndef __CPEXTENSIONS__ALGORITHMS__BEZIERCURVEFUNCTION__HXX__
6 #define __CPEXTENSIONS__ALGORITHMS__BEZIERCURVEFUNCTION__HXX__
7
8 // -------------------------------------------------------------------------
9 template< class V >
10 void cpExtensions::Algorithms::BezierCurveFunction< V >::
11 AddPoint( const TVector& v )
12 {
13   this->m_Vectors.push_back( v );
14   this->m_DerivativeUpdated = false;
15   this->Modified( );
16 }
17
18 // -------------------------------------------------------------------------
19 template< class V >
20 unsigned int cpExtensions::Algorithms::BezierCurveFunction< V >::
21 GetNumberOfPoints( ) const
22 {
23   return( this->m_Vectors.size( ) );
24 }
25
26 // -------------------------------------------------------------------------
27 template< class V >
28 typename cpExtensions::Algorithms::BezierCurveFunction< V >::
29 TVector cpExtensions::Algorithms::BezierCurveFunction< V >::
30 Evaluate( const TScalar& u ) const
31 {
32   TVectorsContainer Q = this->m_Vectors;
33   unsigned int n = Q.size( );
34   TScalar _1u = TScalar( 1 ) - u;
35
36   for( unsigned int k = 1; k < n; k++ )
37   {
38     // CM Fixed a bug appearing under Windows : changed the stopping
39     // condition from <= to <. Otherwise, on the last step, an element out
40     // of the range of vector Q is accessed (Q[ i + 1 ])...
41     for( unsigned int i = 0; i < n - k; i++ )
42       Q[ i ] = ( Q[ i ] * _1u ) + ( Q[ i + 1 ] * u );
43
44   } // rof
45   return( Q[ 0 ] );
46 }
47
48 // -------------------------------------------------------------------------
49 template< class V >
50 typename cpExtensions::Algorithms::BezierCurveFunction< V >::
51 TFrame cpExtensions::Algorithms::BezierCurveFunction< V >::
52 EvaluateFrenetFrame( const TScalar& u ) const
53 {
54   TFrame fr;
55   fr.Fill( TScalar( 0 ) );
56   if( TVector::Dimension == 2 )
57   {
58     this->_UpdateDerivative( );
59     this->m_Derivative->_UpdateDerivative( );
60
61     TVector vT = this->m_Derivative->Evaluate( u );
62     TScalar nvT = vT.GetNorm( );
63     if( TScalar( 0 ) < nvT )
64       vT /= nvT;
65
66     fr[ 0 ][ 0 ] = vT[ 0 ];
67     fr[ 1 ][ 0 ] = vT[ 1 ];
68
69     fr[ 0 ][ 1 ] = -vT[ 1 ];
70     fr[ 1 ][ 1 ] =  vT[ 0 ];
71   }
72   else if( TVector::Dimension == 3 )
73   {
74     this->_UpdateDerivative( );
75     this->m_Derivative->_UpdateDerivative( );
76     TVector vT = this->m_Derivative->Evaluate( u );
77     TScalar nvT = vT.GetNorm( );
78     if( nvT > TScalar( 0 ) )
79     {
80       vT /= nvT;
81       TVector vN = this->m_Derivative->m_Derivative->Evaluate( u );
82       TScalar nvN = vN.GetNorm( );
83       if( nvT > TScalar( 0 ) )
84       {
85         vN /= nvN;
86         TVector vB;
87         vB[ 0 ] = ( vT[ 1 ] * vN[ 2 ] ) - ( vT[ 2 ] * vN[ 1 ] );
88         vB[ 1 ] = ( vT[ 2 ] * vN[ 0 ] ) - ( vT[ 0 ] * vN[ 2 ] );
89         vB[ 2 ] = ( vT[ 0 ] * vN[ 1 ] ) - ( vT[ 1 ] * vN[ 0 ] );
90
91         for( unsigned int d = 0; d < 3; d++ )
92         {
93           fr[ d ][ 0 ] = vT[ d ];
94           fr[ d ][ 1 ] = vN[ d ];
95           fr[ d ][ 2 ] = vB[ d ];
96
97         } // rof
98       }
99       else
100         std::cerr << "ERROR normal" << std::endl;
101     }
102     else
103       std::cerr << "ERROR tangent" << std::endl;
104
105   } // fi
106   return( fr );
107 }
108
109 // -------------------------------------------------------------------------
110 template< class V >
111 typename cpExtensions::Algorithms::BezierCurveFunction< V >::
112 TScalar cpExtensions::Algorithms::BezierCurveFunction< V >::
113 EvaluateLength( ) const
114 {
115   unsigned int n = this->GetNumberOfPoints( ) << 1;
116   TScalar d = TScalar( 0 );
117   TVector v0 = this->Evaluate( 0 );
118   for( unsigned int i = 1; i < n; i++ )
119   {
120     TVector v1 = this->Evaluate( TScalar( i ) / TScalar( n - 1 ) );
121     d += ( v1 - v0 ).GetNorm( );
122     v0 = v1;
123
124   } // rof
125   return( d );
126 }
127
128 // -------------------------------------------------------------------------
129 template< class V >
130 cpExtensions::Algorithms::BezierCurveFunction< V >::
131 BezierCurveFunction( )
132   : Superclass( ),
133     m_DerivativeUpdated( false )
134 {
135 }
136
137 // -------------------------------------------------------------------------
138 template< class V >
139 void cpExtensions::Algorithms::BezierCurveFunction< V >::
140 _UpdateDerivative( ) const
141 {
142   if( this->m_DerivativeUpdated )
143     return;
144
145   this->m_Derivative = Self::New( );
146   unsigned int n = this->m_Vectors.size( ) - 1;
147   for( unsigned int i = 0; i < n; i++ )
148     this->m_Derivative->AddPoint(
149       TScalar( n ) * ( this->m_Vectors[ i + 1 ] - this->m_Vectors[ i ] )
150       );
151 }
152
153 #endif // __CPEXTENSIONS__ALGORITHMS__BEZIERCURVEFUNCTION__HXX__
154
155 // eof - $RCSfile$