ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_ALGORITHM_SPANNED_VOLUME_HPP 00002 #define VIENNAGRID_ALGORITHM_SPANNED_VOLUME_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 00017 00018 //#include <math.h> 00019 #include "viennagrid/forwards.hpp" 00020 #include "viennagrid/algorithm/cross_prod.hpp" 00021 #include "viennagrid/algorithm/norm.hpp" 00022 #include "viennagrid/algorithm/inner_prod.hpp" 00023 00024 00029 namespace viennagrid 00030 { 00031 00032 namespace detail 00033 { 00034 template <typename PointT, int DimV = viennagrid::result_of::dimension<PointT>::value> 00035 struct signed_spanned_volume_impl; 00036 00037 00039 template <typename PointT> 00040 struct signed_spanned_volume_impl<PointT, 1> 00041 { 00042 typedef typename viennagrid::result_of::coord<PointT>::type value_type; 00043 00044 static value_type apply(PointT const & p1, 00045 PointT const & p2) 00046 { 00047 return p2[0] - p1[0]; 00048 } 00049 }; 00050 00051 //in 2d: 00053 template <typename PointT> 00054 struct signed_spanned_volume_impl<PointT, 2> 00055 { 00056 typedef typename viennagrid::result_of::coord<PointT>::type value_type; 00057 00058 static value_type apply(PointT const & p1, 00059 PointT const & p2) 00060 { 00061 //a line 00062 return sqrt( (p2[0] - p1[0]) * (p2[0] - p1[0]) 00063 + (p2[1] - p1[1]) * (p2[1] - p1[1]) ); 00064 } 00065 00066 static value_type apply(PointT const & A, 00067 PointT const & B, 00068 PointT const & C) 00069 { 00070 //a triangle: 00071 return ( A[0] * (B[1] - C[1]) 00072 + B[0] * (C[1] - A[1]) 00073 + C[0] * (A[1] - B[1]) ) / 2.0; 00074 } 00075 00076 }; 00077 00078 00080 template <typename PointT> 00081 struct signed_spanned_volume_impl<PointT, 3> 00082 { 00083 typedef typename viennagrid::result_of::coord<PointT>::type value_type; 00084 00085 static value_type apply(PointT const & p1, 00086 PointT const & p2) 00087 { 00088 //a line 00089 return sqrt( (p2[0] - p1[0]) * (p2[0] - p1[0]) 00090 + (p2[1] - p1[1]) * (p2[1] - p1[1]) 00091 + (p2[2] - p1[2]) * (p2[2] - p1[2]) ); 00092 } 00093 00094 static value_type apply(PointT const & p1, 00095 PointT const & p2, 00096 PointT const & p3) 00097 { 00098 PointT v1 = p2 - p1; 00099 PointT v2 = p3 - p1; 00100 00101 PointT v3 = cross_prod(v1, v2); 00102 00103 return norm(v3) / 2.0; 00104 } 00105 00106 static value_type apply(PointT const & p1, 00107 PointT const & p2, 00108 PointT const & p3, 00109 PointT const & p4) 00110 { 00111 PointT v1 = p2 - p1; 00112 PointT v2 = p3 - p1; 00113 PointT v3 = p4 - p1; 00114 00115 return (inner_prod(v1, cross_prod(v2, v3)) ) / 6.0; 00116 } 00117 00118 }; 00119 } //namespace detail 00120 00121 00122 00123 00124 00125 00126 // 00127 // Mixed coordinate systems: 00128 // 00130 template<typename PointT1, typename PointT2, typename CoordinateSystemT1, typename CoordinateSystemT2> 00131 typename viennagrid::result_of::coord<PointT1>::type 00132 signed_spanned_volume_impl(PointT1 const & p1, 00133 PointT2 const & p2, 00134 CoordinateSystemT1 const &, 00135 CoordinateSystemT2 const &) 00136 { 00137 typedef typename result_of::cartesian_point<PointT1>::type CartesianPoint1; 00138 00139 return detail::signed_spanned_volume_impl<CartesianPoint1>::apply(to_cartesian(p1), to_cartesian(p2)); 00140 } 00141 00143 template<typename PointT1, typename PointT2, typename PointT3, 00144 typename CoordinateSystemT1, typename CoordinateSystemT2, typename CoordinateSystemT3> 00145 typename viennagrid::result_of::coord<PointT1>::type 00146 signed_spanned_volume_impl(PointT1 const & p1, 00147 PointT2 const & p2, 00148 PointT3 const & p3, 00149 CoordinateSystemT1 const &, 00150 CoordinateSystemT2 const &, 00151 CoordinateSystemT3 const &) 00152 { 00153 typedef typename result_of::cartesian_point<PointT1>::type CartesianPoint1; 00154 00155 return detail::signed_spanned_volume_impl<CartesianPoint1>::apply(to_cartesian(p1), to_cartesian(p2), to_cartesian(p3)); 00156 } 00157 00159 template<typename PointT1, typename PointT2, typename PointT3, typename PointT4, 00160 typename CoordinateSystemT1, typename CoordinateSystemT2, typename CoordinateSystemT3, typename CoordinateSystemT4> 00161 typename viennagrid::result_of::coord<PointT1>::type 00162 signed_spanned_volume_impl(PointT1 const & p1, 00163 PointT2 const & p2, 00164 PointT3 const & p3, 00165 PointT4 const & p4, 00166 CoordinateSystemT1 const &, 00167 CoordinateSystemT2 const &, 00168 CoordinateSystemT3 const &, 00169 CoordinateSystemT4 const &) 00170 { 00171 typedef typename result_of::cartesian_point<PointT1>::type CartesianPoint1; 00172 00173 return detail::signed_spanned_volume_impl<CartesianPoint1>::apply(to_cartesian(p1), to_cartesian(p2), to_cartesian(p3), to_cartesian(p4)); 00174 } 00175 00176 // 00177 // All Cartesian: 00178 // 00180 template<typename PointT1, typename PointT2, int DimV> 00181 typename viennagrid::result_of::coord<PointT1>::type 00182 signed_spanned_volume_impl(PointT1 const & p1, 00183 PointT2 const & p2, 00184 cartesian_cs<DimV>, 00185 cartesian_cs<DimV>) 00186 { 00187 return detail::signed_spanned_volume_impl<PointT1>::apply(p1, p2); 00188 } 00189 00191 template <typename PointT1, typename PointT2, typename PointT3, int DimV> 00192 typename viennagrid::result_of::coord<PointT1>::type 00193 signed_spanned_volume_impl(PointT1 const & p1, 00194 PointT2 const & p2, 00195 PointT3 const & p3, 00196 cartesian_cs<DimV>, 00197 cartesian_cs<DimV>, 00198 cartesian_cs<DimV>) 00199 { 00200 return detail::signed_spanned_volume_impl<PointT1>::apply(p1, p2, p3); 00201 } 00202 00204 template <typename PointT1, typename PointT2, typename PointT3, typename PointT4, int DimV> 00205 typename viennagrid::result_of::coord<PointT1>::type 00206 signed_spanned_volume_impl(PointT1 const & p1, 00207 PointT2 const & p2, 00208 PointT3 const & p3, 00209 PointT4 const & p4, 00210 cartesian_cs<DimV>, 00211 cartesian_cs<DimV>, 00212 cartesian_cs<DimV>, 00213 cartesian_cs<DimV>) 00214 { 00215 return detail::signed_spanned_volume_impl<PointT1>::apply(p1, p2, p3, p4); 00216 } 00217 00218 00219 00220 // 00221 // public interface 00222 // 00224 template <typename PointT1, typename PointT2> 00225 typename viennagrid::result_of::coord<PointT1>::type 00226 signed_spanned_volume(PointT1 const & p1, PointT2 const & p2) 00227 { 00228 return signed_spanned_volume_impl(p1, 00229 p2, 00230 typename viennagrid::result_of::coordinate_system<PointT1>::type(), 00231 typename viennagrid::result_of::coordinate_system<PointT2>::type()); 00232 } 00233 00234 00236 template <typename PointT1, typename PointT2, typename PointT3> 00237 typename viennagrid::result_of::coord<PointT1>::type 00238 signed_spanned_volume(PointT1 const & p1, PointT2 const & p2, PointT3 const & p3) 00239 { 00240 return signed_spanned_volume_impl(p1, 00241 p2, 00242 p3, 00243 typename viennagrid::result_of::coordinate_system<PointT1>::type(), 00244 typename viennagrid::result_of::coordinate_system<PointT2>::type(), 00245 typename viennagrid::result_of::coordinate_system<PointT3>::type() 00246 ); 00247 00248 } 00249 00250 00252 template <typename PointT1, typename PointT2, typename PointT3, typename PointT4> 00253 typename viennagrid::result_of::coord<PointT1>::type 00254 signed_spanned_volume(PointT1 const & p1, 00255 PointT2 const & p2, 00256 PointT3 const & p3, 00257 PointT4 const & p4) 00258 { 00259 return signed_spanned_volume_impl(p1, 00260 p2, 00261 p3, 00262 p4, 00263 typename viennagrid::result_of::coordinate_system<PointT1>::type(), 00264 typename viennagrid::result_of::coordinate_system<PointT2>::type(), 00265 typename viennagrid::result_of::coordinate_system<PointT3>::type(), 00266 typename viennagrid::result_of::coordinate_system<PointT4>::type() 00267 ); 00268 } 00269 00270 00272 template <typename PointT1, typename PointT2> 00273 typename viennagrid::result_of::coord<PointT1>::type 00274 spanned_volume(PointT1 const & p1, PointT2 const & p2) 00275 { 00276 return std::abs(signed_spanned_volume(p1, p2)); 00277 } 00278 00279 00281 template <typename PointT1, typename PointT2, typename PointT3> 00282 typename viennagrid::result_of::coord<PointT1>::type 00283 spanned_volume(PointT1 const & p1, PointT2 const & p2, PointT3 const & p3) 00284 { 00285 return std::abs(signed_spanned_volume(p1, p2, p3)); 00286 } 00287 00288 00290 template <typename PointT1, typename PointT2, typename PointT3, typename PointT4> 00291 typename viennagrid::result_of::coord<PointT1>::type 00292 spanned_volume(PointT1 const & p1, 00293 PointT2 const & p2, 00294 PointT3 const & p3, 00295 PointT4 const & p4) 00296 { 00297 return std::abs(signed_spanned_volume(p1, p2, p3, p4)); 00298 } 00299 00300 } 00301 #endif