1 #ifndef __CPM__ALGORITHMS__BASE__FINDCLOSESTPOINTINMESH__HXX__
2 #define __CPM__ALGORITHMS__BASE__FINDCLOSESTPOINTINMESH__HXX__
6 // -------------------------------------------------------------------------
7 template< class M, class S >
8 void cpm::Algorithms::Base::FindClosestPointInMesh< M, S >::
15 // -------------------------------------------------------------------------
16 template< class M, class S >
17 void cpm::Algorithms::Base::FindClosestPointInMesh< M, S >::
21 this->m_KDSample = TKDSample::New( );
22 this->m_KDSample->SetMeasurementVectorSize( TKDVector::Dimension );
26 unsigned long pId = 0;
27 pId < this->m_Mesh->GetNumberOfPoints( );
31 typename M::PointType pnt = this->m_Mesh->GetPoint( pId );
32 for( unsigned int d = 0; d < TKDVector::Dimension; ++d )
33 mv[ d ] = S( pnt[ d ] );
34 mv.PointId = ( typename M::PointIdentifier )( pId );
35 this->m_KDSample->PushBack( mv );
40 this->m_KDGenerator = TKDGenerator::New( );
41 this->m_KDGenerator->SetSample( this->m_KDSample );
42 this->m_KDGenerator->SetBucketSize( this->m_BucketSize );
43 this->m_KDGenerator->Update( );
44 this->m_KDTree = this->m_KDGenerator->GetOutput( );
47 // -------------------------------------------------------------------------
48 template< class M, class S >
50 typename M::PointIdentifier cpm::Algorithms::Base::FindClosestPointInMesh< M, S >::
51 FindClosestPoint( const P& p ) const
54 for( unsigned int d = 0; d < TKDVector::Dimension; ++d )
55 query[ d ] = S( p[ d ] );
57 typename TKDTree::InstanceIdentifierVectorType neighs;
58 std::vector< double > distances;
59 this->m_KDTree->Search( query, this->m_BucketSize, neighs, distances );
60 unsigned int minId = 0;
61 double minD = distances[ 0 ];
62 for( unsigned int i = 1; i < distances.size( ); ++i )
64 if( distances[ i ] < minD )
67 minD = distances[ i ];
72 std::cout << "TODO: " << minD << std::endl;
73 return( neighs[ minId ] );
76 // -------------------------------------------------------------------------
77 template< class M, class S >
78 template< class P, class C >
79 typename M::PointIdentifier cpm::Algorithms::Base::FindClosestPointInMesh< M, S >::
80 FindClosestPoint( const P& p, const C& c ) const
82 typename TKDVector::Superclass p1, p2, d;
83 for( unsigned int i = 0; i < TKDVector::Dimension; ++i )
85 p1[ i ] = S( p[ i ] );
86 p2[ i ] = S( c[ i ] );
87 d[ i ] = p1[ i ] - p2[ i ];
90 TKDScalar nd = d.GetNorm( );
91 typename TKDVector::Superclass n = itk::CrossProduct( p2, p1 );
92 this->_Dummy( this->m_KDTree->GetRoot( ), d, n, nd );
97 // -------------------------------------------------------------------------
98 template< class M, class S >
99 template< class V, class N >
100 void cpm::Algorithms::Base::FindClosestPointInMesh< M, S >::
101 _Dummy( TKDNode* root, const V& d, const V& n, const N& nd ) const
104 itk::Statistics::KdTreeWeightedCentroidNonterminalNode< TKDSample >
106 _TNode* node = dynamic_cast< _TNode* >( root );
110 S left = std::numeric_limits< S >::max( );
112 if( root->Left( ) != NULL )
114 if( !( root->Left( )->IsTerminal( ) ) )
116 typename _TNode::CentroidType c;
117 root->Left( )->GetCentroid( c );
118 left = Self::_LinePointDistance( c, d, n, nd );
123 if( root->Right( ) != NULL )
125 if( !( root->Right( )->IsTerminal( ) ) )
127 typename _TNode::CentroidType c;
128 root->Right( )->GetCentroid( c );
129 right = Self::_LinePointDistance( c, d, n, nd );
136 if( left <= right && root->Left( ) != NULL )
137 this->_Dummy( root->Left( ), d, n, nd );
138 else if( left > right && root->Right( ) != NULL )
139 this->_Dummy( root->Right( ), d, n, nd );
142 std::cout << "Something nasty happened" << std::endl;
149 std::cout << "Leaf!!!" << std::endl;
154 _LinePointDistance( const P& p0, const D& d, const N& n, const T& nd )
155 std::cout << n << " " << d << " " << nd << std::endl;
157 itk::Statistics::KdTreeWeightedCentroidNonterminalNode< TKDSample >
159 _TNode* node = dynamic_cast< _TNode* >( root );
163 typename _TNode::CentroidType left, right;
164 if( root->Left( ) != NULL )
165 root->Left( )->GetCentroid( left );
166 if( root->Right( ) != NULL )
167 root->Right( )->GetCentroid( right );
172 if( root->Left( ) != NULL )
173 this->_Dummy( root->Left( ) );
174 if( root->Right( ) != NULL )
175 this->_Dummy( root->Right( ) );
178 if( root->IsTerminal( ) )
183 if( root->Left( ) != NULL )
184 this->_Dummy( root->Left( ) );
185 if( root->Right( ) != NULL )
186 this->_Dummy( root->Right( ) );
192 // -------------------------------------------------------------------------
193 template< class M, class S >
194 cpm::Algorithms::Base::FindClosestPointInMesh< M, S >::
195 FindClosestPointInMesh( )
201 // -------------------------------------------------------------------------
202 template< class M, class S >
203 cpm::Algorithms::Base::FindClosestPointInMesh< M, S >::
204 ~FindClosestPointInMesh( )
208 // -------------------------------------------------------------------------
209 template< class M, class S >
210 template< class V, class N, class P >
211 S cpm::Algorithms::Base::FindClosestPointInMesh< M, S >::
212 _LinePointDistance( const P& p0, const V& d, const V& n, const N& nd )
215 for( unsigned int i = 0; i < Self::Dimension; ++i )
216 v0[ i ] = N( p0[ i ] );
217 return( S( ( itk::CrossProduct( v0, d ) - n ).GetNorm( ) / nd ) );
220 #endif // __CPM__ALGORITHMS__BASE__FINDCLOSESTPOINTINMESH__HXX__