1 #ifndef __CPM__ALGORITHMS__SIMPLEX__INTERNALFORCEFUNCTION__HXX__
2 #define __CPM__ALGORITHMS__SIMPLEX__INTERNALFORCEFUNCTION__HXX__
5 #include <vnl/vnl_math.h>
7 // -------------------------------------------------------------------------
9 typename cpm::Algorithms::Simplex::InternalForceFunction< M >::
10 TVector cpm::Algorithms::Simplex::InternalForceFunction< M >::
11 Evaluate( const TPointId& pId ) const
13 typedef typename M::BarycenterVector TBarycenter;
15 static const TScalar _1_3 = TScalar( 1 ) / TScalar( 3 );
17 TVector f( TScalar( 0 ) );
18 if( this->m_Mesh.IsNotNull( ) )
20 if( pId < this->m_Mesh->GetNumberOfPoints( ) )
24 TScalar r, d, dp, phi;
27 ComputeSimplexParameters( pId, A, B, C, N, b, r, d, dp, phi )
31 f = A * ( _1_3 - b[ 0 ] );
32 f += B * ( _1_3 - b[ 1 ] );
33 f += C * ( _1_3 - b[ 2 ] );
37 switch( this->m_PhiConstraint )
43 dphi = this->_ComputeMeanPhi( pId );
46 dphi = this->m_InitialPhiAngles[ pId ];
55 f += N * ( Self::_L( r, dp, dphi ) - Self::_L( r, d, phi ) );
65 // -------------------------------------------------------------------------
67 void cpm::Algorithms::Simplex::InternalForceFunction< M >::
70 typedef typename M::BarycenterVector TBarycenter;
72 if( this->m_Mesh != m && m != NULL )
74 this->m_InitialPhiAngles.clear( );
75 for( TPointId i = 0; i < m->GetNumberOfPoints( ); ++i )
79 TScalar a, b, c, phi = TScalar( 0 );
80 m->ComputeSimplexParameters( i, A, B, C, N, e, a, b, c, phi );
81 this->m_InitialPhiAngles.push_back( phi );
86 this->Superclass::SetMesh( m );
89 // -------------------------------------------------------------------------
91 void cpm::Algorithms::Simplex::InternalForceFunction< M >::
92 SetPhiConstraintToC0( )
94 if( this->m_PhiConstraint != Self::C0 )
96 this->m_PhiConstraint = Self::C0;
102 // -------------------------------------------------------------------------
104 void cpm::Algorithms::Simplex::InternalForceFunction< M >::
105 SetPhiConstraintToC1( )
107 if( this->m_PhiConstraint != Self::C1 )
109 this->m_PhiConstraint = Self::C1;
115 // -------------------------------------------------------------------------
117 void cpm::Algorithms::Simplex::InternalForceFunction< M >::
118 SetPhiConstraintToC2( const unsigned int& neigh_order )
120 if( this->m_PhiConstraint != Self::C2 )
122 this->m_PhiConstraint = Self::C2;
123 this->m_NeighborhoodOrder = neigh_order;
129 // -------------------------------------------------------------------------
131 void cpm::Algorithms::Simplex::InternalForceFunction< M >::
132 SetPhiConstraintToC3( )
134 if( this->m_PhiConstraint != Self::C3 )
136 this->m_PhiConstraint = Self::C3;
142 // -------------------------------------------------------------------------
144 cpm::Algorithms::Simplex::InternalForceFunction< M >::
145 InternalForceFunction( )
147 m_PhiConstraint( Self::C0 ),
148 m_NeighborhoodOrder( 1 )
152 // -------------------------------------------------------------------------
154 cpm::Algorithms::Simplex::InternalForceFunction< M >::
155 ~InternalForceFunction( )
159 // -------------------------------------------------------------------------
161 typename cpm::Algorithms::Simplex::InternalForceFunction< M >::
162 TScalar cpm::Algorithms::Simplex::InternalForceFunction< M >::
163 _ComputeMeanPhi( const TPointId& pId ) const
165 // TODO: use this->m_NeighborhoodOrder
166 return( TScalar( 0 ) );
169 // -------------------------------------------------------------------------
171 typename cpm::Algorithms::Simplex::InternalForceFunction< M >::
172 TScalar cpm::Algorithms::Simplex::InternalForceFunction< M >::
173 _L( const TScalar& delta, const TScalar& d, const TScalar& phi )
175 static const double _pi2 = double( vnl_math::pi ) / double( 2 );
177 TScalar eps = TScalar( 1 );
178 if( _pi2 < std::fabs( double( phi ) ) )
181 TScalar sphi = TScalar( std::sin( double( phi ) ) );
182 TScalar cphi = TScalar( std::fabs( std::cos( double( phi ) ) ) );
184 TScalar den = delta * cphi;
185 TScalar s = ( delta + ( d * sphi ) ) * ( delta - ( d * sphi ) );
186 if( s < TScalar( 0 ) )
187 return( TScalar( 0 ) );
189 den += eps * TScalar( std::sqrt( double( s ) ) );
190 if( !( TScalar( 0 ) < den ) )
191 return( TScalar( 0 ) );
193 TScalar num = eps * ( delta + d ) * ( delta - d ) * sphi;
197 #endif // __CPM__ALGORITHMS__SIMPLEX__INTERNALFORCEFUNCTION__HXX__