ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/algorithm/spanned_volume.hpp
Go to the documentation of this file.
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