ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/algorithm/geometric_transform.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_ALGORITHM_GEOMETRIC_TRANSFORM_HPP
00002 #define VIENNAGRID_ALGORITHM_GEOMETRIC_TRANSFORM_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 "viennagrid/forwards.hpp"
00017 #include "viennagrid/mesh/mesh.hpp"
00018 
00023 namespace viennagrid
00024 {
00031   template<typename MeshT, typename FunctorT, typename PointAccessorT>
00032   void geometric_transform(MeshT & mesh, FunctorT func, PointAccessorT accessor)
00033   {
00034     typedef typename viennagrid::result_of::element_range<MeshT, viennagrid::vertex_tag>::type   VertexContainer;
00035     typedef typename viennagrid::result_of::iterator<VertexContainer>::type                      VertexIterator;
00036 
00037     VertexContainer vertices(mesh);
00038     for ( VertexIterator vit = vertices.begin();
00039           vit != vertices.end();
00040           ++vit )
00041       accessor(*vit) = func( accessor(*vit) );
00042   }
00043 
00049   template<typename MeshT, typename FunctorT>
00050   void geometric_transform(MeshT & mesh, FunctorT func)
00051   {
00052     geometric_transform(mesh, func, viennagrid::default_point_accessor(mesh));
00053   }
00054 
00055 
00060   template<typename MeshT>
00061   struct scale_functor
00062   {
00063     typedef typename viennagrid::result_of::point<MeshT>::type PointType;
00064     typedef typename viennagrid::result_of::coord<MeshT>::type ScalarType;
00065 
00066     scale_functor() {}
00067     scale_functor(ScalarType factor_) : factor(factor_), scale_center(0) {}
00068     scale_functor(ScalarType factor_, PointType const & scale_center_) :
00069         factor(factor_), scale_center(scale_center_) {}
00070 
00071     PointType operator()(PointType p) const
00072     {
00073       p -= scale_center;
00074       p *= factor;
00075       p += scale_center;
00076       return p;
00077     }
00078 
00079     ScalarType factor;
00080     PointType scale_center;
00081   };
00082 
00089   template<typename MeshT, typename ScalarT, typename PointType>
00090   void scale(MeshT & mesh, ScalarT factor, PointType const & scaling_center)
00091   {
00092     scale_functor<MeshT> func(factor, scaling_center);
00093     geometric_transform(mesh, func);
00094   }
00095 
00101   template<typename MeshT, typename ScalarT>
00102   void scale(MeshT & mesh, ScalarT factor)
00103   {
00104     scale_functor<MeshT> func(factor);
00105     geometric_transform(mesh, func);
00106   }
00107 
00108 
00109 
00110 
00115   template<typename MeshT>
00116   struct affine_transform_functor
00117   {
00118     typedef typename viennagrid::result_of::point<MeshT>::type PointType;
00119     typedef typename viennagrid::result_of::coord<MeshT>::type ScalarType;
00120     static const unsigned int point_dim = viennagrid::result_of::geometric_dimension<MeshT>::value;
00121 
00122     affine_transform_functor() {}
00123     affine_transform_functor(ScalarType const * matrix_) : matrix(matrix_), translation(0) {}
00124     affine_transform_functor(ScalarType const * matrix_, PointType const & translation_) :
00125         matrix(matrix_), translation(translation_) {}
00126 
00127     PointType operator()(PointType const & p) const
00128     {
00129       PointType tmp = translation;
00130       for (unsigned int row = 0; row != point_dim; ++row)
00131       {
00132         for (unsigned int column = 0; column != point_dim; ++column)
00133           tmp[row] += p[column] * matrix[ row*point_dim + column ];
00134       }
00135 
00136       return tmp;
00137     }
00138 
00139     ScalarType const * matrix;
00140     PointType translation;
00141   };
00142 
00149   template<typename MeshT>
00150   void affine_transform( MeshT & mesh,
00151                          typename viennagrid::result_of::coord<MeshT>::type const * matrix,
00152                          typename viennagrid::result_of::point<MeshT>::type const & translation )
00153   {
00154     affine_transform_functor<MeshT> func(matrix, translation);
00155     geometric_transform(mesh, func);
00156   }
00157 
00158 }
00159 
00160 #endif