ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_ALGORITHM_DISTANCE_HPP 00002 #define VIENNAGRID_ALGORITHM_DISTANCE_HPP 00003 00004 /* ======================================================================= 00005 Copyright (c) 2011-2014, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 00009 ----------------- 00010 ViennaGrid - The Vienna Grid Library 00011 ----------------- 00012 00013 License: MIT (X11), see file LICENSE in the base directory 00014 ======================================================================= */ 00015 00016 #include <iostream> 00017 #include <sstream> 00018 #include <string> 00019 #include <stdexcept> 00020 #include <limits> 00021 00022 #include "viennagrid/forwards.hpp" 00023 #include "viennagrid/topology/all.hpp" 00024 #include "viennagrid/algorithm/norm.hpp" 00025 #include "viennagrid/algorithm/inner_prod.hpp" 00026 #include "viennagrid/algorithm/closest_points.hpp" 00027 00033 namespace viennagrid 00034 { 00035 namespace detail 00036 { 00037 00038 // 00039 // Distance between points 00040 // 00041 00042 // Distance between two points: 00043 template <typename PointT1, typename PointT2> 00044 typename viennagrid::result_of::coord<PointT1>::type 00045 distance_impl(PointT1 const & p1, 00046 PointT2 const & p2) 00047 { 00048 return norm_2(p1 - p2); 00049 } 00050 00051 template <typename PointT1, typename PointT2> 00052 typename viennagrid::result_of::coord<PointT1>::type 00053 distance_impl( std::pair<PointT1,PointT2> const & pts) 00054 { 00055 return distance_impl(pts.first, pts.second); 00056 } 00057 00058 template <typename PointAccessorT, typename CoordT1, typename CoordinateSystemT1, typename CoordT2, typename CoordinateSystemT2> 00059 CoordT1 00060 distance_impl(PointAccessorT const, 00061 spatial_point<CoordT1, CoordinateSystemT1> const & p1, 00062 spatial_point<CoordT2, CoordinateSystemT2> const & p2) 00063 { 00064 return distance_impl(p1, p2); 00065 } 00066 00067 template <typename PointAccessorT, typename PointT, typename WrappedConfigT> 00068 typename viennagrid::result_of::coord<PointT>::type 00069 distance_impl(PointAccessorT const accessor, 00070 PointT const & p1, 00071 viennagrid::element<viennagrid::vertex_tag, WrappedConfigT> const & v2) 00072 { 00073 return distance_impl(p1, accessor(v2)); 00074 } 00075 00076 template <typename PointAccessorT, typename PointT, typename WrappedConfigT> 00077 typename viennagrid::result_of::coord<typename PointAccessorT::value_type>::type 00078 distance_impl(PointAccessorT const accessor, 00079 viennagrid::element<viennagrid::vertex_tag, WrappedConfigT> const & v1, 00080 PointT const & p2) 00081 { 00082 return distance_impl(accessor(v1), p2); 00083 } 00084 00085 // Distance between vertices: Use point distance 00086 template <typename PointAccessorT, typename PointT, typename WrappedConfigT1, typename WrappedConfigT2> 00087 typename viennagrid::result_of::coord<typename PointAccessorT::value_type>::type 00088 distance_impl(PointAccessorT const accessor, 00089 viennagrid::element<viennagrid::vertex_tag, WrappedConfigT1> const & v1, 00090 viennagrid::element<viennagrid::vertex_tag, WrappedConfigT2> const & v2) 00091 { 00092 return distance_impl(accessor(v1), accessor(v2)); 00093 } 00094 00095 00096 00097 // 00098 // Generic distance computation: Reuse closest_points() 00099 // 00100 template <typename PointAccessorT, typename SomethingT1, typename SomethingT2> 00101 typename viennagrid::result_of::coord<typename PointAccessorT::value_type>::type 00102 distance_impl(PointAccessorT const accessor, 00103 SomethingT1 const & el1, 00104 SomethingT2 const & el2) 00105 { 00106 //typedef typename result_of::point<ElementType1>::type PointT; 00107 typedef typename PointAccessorT::value_type PointT; 00108 00109 std::pair<PointT, PointT> points = closest_points(accessor, el1, el2); 00110 00111 return distance_impl( points ); 00112 } 00113 00114 00115 00117 00118 00119 template <typename PointT1, typename PointT2> 00120 typename viennagrid::result_of::coord<PointT1>::type 00121 boundary_distance_impl(PointT1 const & p1, 00122 PointT2 const & p2) 00123 { 00124 return norm_2(p1 - p2); 00125 } 00126 00127 template <typename PointT1, typename PointT2> 00128 typename viennagrid::result_of::coord<PointT1>::type 00129 boundary_distance_impl( std::pair<PointT1,PointT2> const & pts) 00130 { 00131 return boundary_distance_impl(pts.first, pts.second); 00132 } 00133 00134 template <typename PointAccessorT, typename CoordT1, typename CoordinateSystemT1, typename CoordT2, typename CoordinateSystemT2> 00135 CoordT1 00136 boundary_distance_impl(PointAccessorT const, 00137 spatial_point<CoordT1, CoordinateSystemT1> const & p1, 00138 spatial_point<CoordT2, CoordinateSystemT2> const & p2) 00139 { 00140 return boundary_distance_impl(p1, p2); 00141 } 00142 00143 template <typename PointAccessorT, typename PointT, typename WrappedConfigT> 00144 typename viennagrid::result_of::coord<PointT>::type 00145 boundary_distance_impl(PointAccessorT const accessor, 00146 PointT const & p1, 00147 viennagrid::element<viennagrid::vertex_tag, WrappedConfigT> const & v2) 00148 { 00149 return boundary_distance_impl(p1, accessor(v2)); 00150 } 00151 00152 template <typename PointAccessorT, typename PointT, typename WrappedConfigT> 00153 typename viennagrid::result_of::coord<typename PointAccessorT::value_type>::type 00154 boundary_distance_impl(PointAccessorT const accessor, 00155 viennagrid::element<viennagrid::vertex_tag, WrappedConfigT> const & v1, 00156 PointT const & p2) 00157 { 00158 return boundary_distance_impl(accessor(v1), p2); 00159 } 00160 00161 // Distance between vertices: Use point distance 00162 template <typename PointAccessorT, typename PointT, typename WrappedConfigT1, typename WrappedConfigT2> 00163 typename viennagrid::result_of::coord<typename PointAccessorT::value_type>::type 00164 boundary_distance_impl(PointAccessorT const accessor, 00165 viennagrid::element<viennagrid::vertex_tag, WrappedConfigT1> const & v1, 00166 viennagrid::element<viennagrid::vertex_tag, WrappedConfigT2> const & v2) 00167 { 00168 return boundary_distance_impl(accessor(v1), accessor(v2)); 00169 } 00170 00171 00172 00173 // 00174 // Generic distance computation: Reuse closest_points() 00175 // 00176 template <typename PointAccessorT, typename SomethingT1, typename SomethingT2> 00177 typename viennagrid::result_of::coord<typename PointAccessorT::value_type>::type 00178 boundary_distance_impl(PointAccessorT const accessor, 00179 SomethingT1 const & el1, 00180 SomethingT2 const & el2) 00181 { 00182 //typedef typename result_of::point<ElementType1>::type PointT; 00183 typedef typename PointAccessorT::value_type PointT; 00184 00185 std::pair<PointT, PointT> points = closest_points_on_boundary(accessor, el1, el2); 00186 00187 return boundary_distance_impl(points); 00188 } 00189 00190 } //namespace detail 00191 00192 // 00193 // The public interface functions 00194 // 00196 template <typename PointAccessorT, typename SomethingT1, typename SomethingT2> 00197 typename viennagrid::result_of::coord<SomethingT1>::type 00198 distance(PointAccessorT const accessor, 00199 SomethingT1 const & el1, 00200 SomethingT2 const & el2) 00201 { 00202 return detail::distance_impl(accessor, el1, el2); 00203 } 00204 00205 00207 template <typename SomethingT1, typename SomethingT2> 00208 typename viennagrid::result_of::coord<SomethingT1>::type 00209 distance(SomethingT1 const & el1, 00210 SomethingT2 const & el2) 00211 { 00212 return detail::distance_impl( default_point_accessor(el1), el1, el2 ); 00213 } 00214 00216 template <typename SomethingT, typename CoordT, typename CoordinateSystemT> 00217 typename viennagrid::result_of::coord<SomethingT>::type 00218 distance(SomethingT const & el1, 00219 spatial_point<CoordT, CoordinateSystemT> const & el2) 00220 { 00221 return detail::distance_impl( default_point_accessor(el1), el1, el2 ); 00222 } 00223 00225 template <typename CoordT, typename CoordinateSystemT, typename SomethingT> 00226 typename viennagrid::result_of::coord<SomethingT>::type 00227 distance(spatial_point<CoordT, CoordinateSystemT> const & el1, 00228 SomethingT const & el2) 00229 { 00230 return detail::distance_impl( default_point_accessor(el2), el1, el2 ); 00231 } 00232 00234 template <typename CoordT1, typename CoordinateSystemT1, typename CoordT2, typename CoordinateSystemT2> 00235 typename viennagrid::result_of::coord< spatial_point<CoordT1, CoordinateSystemT1> >::type 00236 distance(spatial_point<CoordT1, CoordinateSystemT1> const & el1, 00237 spatial_point<CoordT2, CoordinateSystemT2> const & el2) 00238 { 00239 return detail::distance_impl( el1, el2 ); 00240 } 00241 00242 00244 template<typename WrappedMeshConfigT, typename SegmentationT> 00245 typename result_of::coord< segment_handle<SegmentationT> >::type distance( element<line_tag, WrappedMeshConfigT> const & line, segment_handle<SegmentationT> const & segment_handle ) 00246 { 00247 typedef viennagrid::segment_handle<SegmentationT> SegmentHandleType; 00248 typedef typename result_of::const_line_range<SegmentHandleType>::type ConstLineRangeType; 00249 typedef typename result_of::iterator<ConstLineRangeType>::type ConstLineIteratorType; 00250 00251 typedef typename result_of::coord<SegmentHandleType>::type CoordType; 00252 00253 ConstLineRangeType lines(segment_handle); 00254 if (lines.empty()) 00255 return -1; 00256 00257 ConstLineIteratorType lit = lines.begin(); 00258 CoordType min_distance = distance(line, *(lit++)); 00259 00260 for (; lit != lines.end(); ++lit) 00261 { 00262 CoordType current_distance = distance(line, *lit); 00263 if (current_distance < min_distance) 00264 min_distance = current_distance; 00265 } 00266 00267 return min_distance; 00268 } 00269 00270 template<typename SegmentationT, typename WrappedMeshConfigT> 00271 typename result_of::coord< segment_handle<SegmentationT> >::type distance( segment_handle<SegmentationT> const & segment_handle, element<line_tag, WrappedMeshConfigT> const & line ) 00272 { 00273 return distance( line, segment_handle ); 00274 } 00275 00276 00277 00278 00279 00286 template <typename PointAccessorT, typename SomethingT1, typename SomethingT2> 00287 typename viennagrid::result_of::coord<SomethingT1>::type 00288 boundary_distance(PointAccessorT const accessor, 00289 SomethingT1 const & el1, 00290 SomethingT2 const & el2) 00291 { 00292 return detail::boundary_distance_impl(accessor, el1, el2); 00293 } 00294 00296 template <typename SomethingT1, typename SomethingT2> 00297 typename viennagrid::result_of::coord<SomethingT1>::type 00298 boundary_distance(SomethingT1 const & el1, 00299 SomethingT2 const & el2) 00300 { 00301 return detail::boundary_distance_impl( default_point_accessor(el1), el1, el2 ); 00302 } 00303 00305 template <typename SomethingT, typename CoordT, typename CoordinateSystemT> 00306 typename viennagrid::result_of::coord<SomethingT>::type 00307 boundary_distance(SomethingT const & el1, 00308 spatial_point<CoordT, CoordinateSystemT> const & el2) 00309 { 00310 return detail::boundary_distance_impl( default_point_accessor(el1), el1, el2 ); 00311 } 00312 00314 template <typename CoordT, typename CoordinateSystemT, typename SomethingT> 00315 typename viennagrid::result_of::coord<SomethingT>::type 00316 boundary_distance(spatial_point<CoordT, CoordinateSystemT> const & el1, 00317 SomethingT const & el2) 00318 { 00319 return detail::boundary_distance_impl( default_point_accessor(el2), el1, el2 ); 00320 } 00321 00322 00323 } //namespace viennagrid 00324 #endif