00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "DistanceMapCalculator.hpp"
00030
00031 #include <queue>
00032
00033
00034 template<unsigned SPACE_DIM>
00035 double DistanceMapCalculator<SPACE_DIM>::EuclideanDistanceTwoPoints(
00036 const c_vector<double, SPACE_DIM>& pointA,
00037 const c_vector<double, SPACE_DIM>& pointB) const
00038 {
00039 double dist=0.0;
00040
00041 for (unsigned dim=0; dim<SPACE_DIM; dim++)
00042 {
00043 dist+=(pointA(dim)-pointB(dim)) * (pointA(dim)-pointB(dim));
00044 }
00045
00046 return sqrt(dist);
00047 }
00048
00049 template<unsigned SPACE_DIM>
00050 double DistanceMapCalculator<SPACE_DIM>::CartToEucliDistance(
00051 c_vector<double, SPACE_DIM>& cartDistance) const
00052 {
00053 double dist=0.0;
00054
00055 for (unsigned dim=0; dim<SPACE_DIM; dim++)
00056 {
00057 dist+=cartDistance(dim) * cartDistance(dim);
00058 }
00059
00060 return sqrt(dist);
00061 }
00062
00063
00064 template<unsigned SPACE_DIM>
00065 DistanceMapCalculator<SPACE_DIM>::DistanceMapCalculator(
00066 TetrahedralMesh<SPACE_DIM,SPACE_DIM>& rMesh)
00067 : mrMesh(rMesh)
00068 {
00069 mNumNodes = mrMesh.GetNumNodes();
00070 }
00071
00072 template<unsigned SPACE_DIM>
00073 void DistanceMapCalculator<SPACE_DIM>::ComputeDistanceMap(
00074 std::vector<unsigned>& rOriginSurface,
00075 std::vector<double>& rNodeDistances)
00076 {
00077 if (rNodeDistances.size() != mNumNodes)
00078 {
00079 rNodeDistances.reserve(mNumNodes);
00080 }
00081
00082
00083
00084
00085 std::vector< c_vector<double, SPACE_DIM> > cart_distances(mNumNodes);
00086 for (unsigned index=0; index<mNumNodes; index++)
00087 {
00088 for (unsigned dim=0; dim<SPACE_DIM; dim++)
00089 {
00090 cart_distances[index][dim] = DBL_MAX;
00091 }
00092 }
00093
00094
00095
00096
00097 std::queue<unsigned> active_nodes;
00098 for (unsigned index=0; index<rOriginSurface.size(); index++)
00099 {
00100 active_nodes.push(rOriginSurface[index]);
00101
00102 for (unsigned dim=0; dim<SPACE_DIM; dim++)
00103 {
00104 cart_distances[rOriginSurface[index]][dim] = 0u;
00105 }
00106 }
00107
00108 while (!active_nodes.empty())
00109 {
00110
00111 unsigned current_node_index = active_nodes.front();
00112 Node<SPACE_DIM>* p_current_node = mrMesh.GetNode(current_node_index);
00113
00114
00115 for(typename Node<SPACE_DIM>::ContainingElementIterator element_iterator = p_current_node->ContainingElementsBegin();
00116 element_iterator != p_current_node->ContainingElementsEnd();
00117 ++element_iterator)
00118 {
00119
00120 Element<SPACE_DIM,SPACE_DIM>* p_containing_element = mrMesh.GetElement(*element_iterator);
00121
00122
00123 for(unsigned node_local_index=0;
00124 node_local_index<p_containing_element->GetNumNodes();
00125 node_local_index++)
00126 {
00127 Node<SPACE_DIM>* p_neighbour_node = p_containing_element->GetNode(node_local_index);
00128 unsigned neighbour_node_index = p_neighbour_node->GetIndex();
00129
00130
00131 if(neighbour_node_index != current_node_index)
00132 {
00133
00134 if ((CartToEucliDistance(cart_distances[current_node_index])
00135 + EuclideanDistanceTwoPoints(p_current_node->rGetLocation(), p_neighbour_node->rGetLocation()))
00136 < CartToEucliDistance(cart_distances[neighbour_node_index])*(1.0 - DBL_EPSILON) )
00137 {
00138 cart_distances[neighbour_node_index] = cart_distances[current_node_index]
00139 + (p_current_node->rGetLocation() - p_neighbour_node->rGetLocation());
00140 active_nodes.push(neighbour_node_index);
00141 }
00142 }
00143 }
00144 }
00145
00146 active_nodes.pop();
00147 }
00148
00149 for (unsigned index=0; index<mNumNodes; index++)
00150 {
00151 rNodeDistances[index] = CartToEucliDistance(cart_distances[index]);
00152 }
00153
00154 }
00155
00156
00158
00160
00161
00162
00163 template class DistanceMapCalculator<3>;