• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

/home/hauberg/Dokumenter/Capture/humim-tracker-0.1/src/OpenTissue/OpenTissue/core/geometry/geometry_plane.h

Go to the documentation of this file.
00001 #ifndef OPENTISSUE_CORE_GEOMETRY_GEOMETRY_PLANE_H
00002 #define OPENTISSUE_CORE_GEOMETRY_GEOMETRY_PLANE_H
00003 //
00004 // OpenTissue Template Library
00005 // - A generic toolbox for physics-based modeling and simulation.
00006 // Copyright (C) 2008 Department of Computer Science, University of Copenhagen.
00007 //
00008 // OTTL is licensed under zlib: http://opensource.org/licenses/zlib-license.php
00009 //
00010 #include <OpenTissue/configuration.h>
00011 
00012 #include <OpenTissue/core/geometry/geometry_base_shape.h>
00013 #include <OpenTissue/core/geometry/geometry_compute_plane_aabb.h>
00014 #include <OpenTissue/core/function/function_signed_distance_function.h>
00015 #include <OpenTissue/utility/utility_class_id.h>
00016 #include <OpenTissue/core/math/math_basic_types.h>
00017 #include <OpenTissue/core/math/math_precision.h>
00018 
00019 #include <cmath>
00020 #include <iosfwd>
00021 
00022 namespace OpenTissue
00023 {
00024 
00025   namespace geometry
00026   {
00027 
00034     template< typename math_types_ >
00035     class Plane
00036       : public BaseShape< math_types_ >
00037       , public function::SignedDistanceFunction< math_types_ >
00038       , public OpenTissue::utility::ClassID< Plane<math_types_> >
00039     {
00040     public:
00041 
00042       typedef          math_types_                   math_types;
00043       typedef typename math_types::vector3_type      vector3_type;
00044       typedef typename math_types::matrix3x3_type    matrix3x3_type;
00045 
00046     protected:
00047 
00048       typedef typename math_types::value_traits      value_traits;
00049       typedef typename math_types::real_type         real_type;
00050       typedef          Plane<math_types>             plane_type;
00051 
00052     public:
00053 
00054       vector3_type m_n;    
00055       real_type    m_d;    
00056 
00057 
00058     public:
00059 
00060       vector3_type const & n() const { return m_n; }
00061       vector3_type       & n()       { return m_n; }
00062       real_type    const & w() const { return m_d; }
00063       real_type          & w()       { return m_d; }
00064 
00065     public:
00066 
00067       size_t const class_id() const { return OpenTissue::utility::ClassID<OpenTissue::geometry::Plane<math_types_> >::class_id(); }
00068 
00078       Plane()
00079         : m_n(value_traits::zero(),value_traits::zero(),value_traits::zero())
00080         , m_d(value_traits::zero())
00081       {}
00082 
00091       explicit Plane(vector3_type const & p1,vector3_type const & p2,vector3_type const & p3)    {      set(p1,p2,p3);    }
00092 
00099       Plane(Plane const & p)    {      set(p);    }
00100 
00107       explicit Plane(vector3_type const & n_val, real_type const & d_val){      set(n_val,d_val);    }
00108 
00116       explicit Plane(vector3_type const & ndir, vector3_type const & p)
00117       {
00118         set(ndir,p);
00119       }
00120 
00121     public:
00122 
00123       bool is_equal(plane_type const & p)const
00124       {
00125         // TODO: Comparing floats with ==
00126         if(m_n==p.m_n && m_d==p.m_d)
00127           return true;
00128         return false;
00129       }
00130 
00131       bool isNearlyEqual(plane_type const & p)const
00132       {
00133         // TODO: Check that this is actually what we want!
00134         real_type epsilon = math::working_precision<real_type>();
00135         if(m_n.is_equal(p.m_n,epsilon)&& std::fabs(m_d-p.m_d)<epsilon)
00136           return true;
00137         return false;
00138       }
00139 
00147       void set(plane_type const & p)
00148       {
00149         m_n = p.m_n;
00150         m_d = p.m_d;
00151       }
00152 
00159       void set(vector3_type const & n_val,real_type const & d_val)
00160       {
00161         m_n = unit(n_val);
00162         m_d = d_val;
00163       }
00164 
00176       void set(vector3_type const & ndir,vector3_type const & p)
00177       {
00178         m_n = unit(ndir);
00179         m_d = m_n *p;
00180       }
00181 
00193       void set(vector3_type const & p1,vector3_type const & p2,vector3_type const & p3)
00194       {
00195         vector3_type u1,u2,u1Xu2;
00196         u2 = p3 - p2;
00197         u1 = p2 - p1;
00198         u1Xu2 = cross(u1,u2);
00199         m_n = unit(u1Xu2);
00200         m_d = m_n * p1;
00201       }
00202 
00211       void set(real_type * c1,real_type * c2,real_type * c3)
00212       {
00213         vector3_type p1(c1[0],c1[1],c1[2]);
00214         vector3_type p2(c2[0],c2[1],c2[2]);
00215         vector3_type p3(c3[0],c3[1],c3[2]);
00216         set(p1,p2,p3);
00217       }
00218 
00225       bool is_coplanar(plane_type const& p) const
00226       {
00227         return (m_n == p.m_n);
00228       }
00229 
00240       void compute_plane_vectors(vector3_type & tx,vector3_type & ty) const
00241       {
00242         //--- Use ty as temporary storage for computing a projection axe (which is temporarily stored in tx)
00243         vector3_type i(value_traits::one(), value_traits::zero(),value_traits::zero());
00244         vector3_type j(value_traits::zero(),value_traits::one(), value_traits::zero());
00245         vector3_type k(value_traits::zero(),value_traits::zero(),value_traits::one());
00246 
00247         ty = cross(m_n,i);
00248         if(!is_zero(ty) )
00249         {
00250           tx = i;
00251         }
00252         else
00253         {
00254           ty = cross(m_n,j);
00255           if( !is_zero(ty) )
00256           {
00257             tx = j;
00258           }
00259           else
00260           {
00261             ty = cross(m_n,k);
00262             if( !is_zero(ty) )
00263             {
00264               tx = k;
00265             }
00266             else
00267             {
00268               std::cout << "plane::compute_plane_vectors(): Could not find non-parallel vector to n" << std::endl;
00269               return;
00270             }
00271           }
00272         }
00273         //--- Now we can compute ty
00274         ty = unit(cross(m_n,tx));
00275         //--- And finally tx
00276         tx = unit(cross(ty,m_n));
00277       }
00278 
00288       real_type get_distance(vector3_type const & p)const
00289       {
00290         using std::fabs;
00291 
00292         return fabs(m_n*p - m_d);
00293       }
00294 
00310       real_type signed_distance(vector3_type const & p)const
00311       {
00312         return m_n*p-m_d;
00313       }
00314 
00315       void compute_surface_points( std::vector<vector3_type> & /*points*/) const
00316       {
00317       }
00318 
00319       vector3_type get_support_point(vector3_type const & /*v*/) const
00320       {
00321         return vector3_type();
00322       }
00323 
00324       void scale(real_type const & /*s*/)
00325       {
00326         assert("Plane::scale doesn't make any sense!");
00327       }
00328 
00343       void rotate(matrix3x3_type const & R)
00344       {
00345         m_n = R * m_n;
00346       }
00347 
00353       void translate(vector3_type const & T)
00354       {
00355         m_d += m_n * T;
00356       }
00357 
00361       void flip()
00362       {
00363         m_n = - m_n;
00364         m_d = -m_d;
00365       }
00366 
00373       vector3_type project(vector3_type const & point) const
00374       {
00375         real_type h = m_n * point - m_d;
00376         vector3_type tmp = point - m_n*h;
00377         return tmp;
00378       }
00379 
00380     public:
00381 
00382       real_type evaluate(vector3_type const & x) const
00383       {
00384         return signed_distance(x);
00385       }
00386 
00387       vector3_type gradient(vector3_type const & /* x */) const
00388       {
00389         return m_n;
00390       }
00391 
00392       vector3_type normal(vector3_type const & /* x */) const
00393       {
00394         return unit(m_n);
00395       }
00396 
00408       void compute_collision_aabb(
00409           vector3_type const & /*r*/
00410         , matrix3x3_type const & /*R*/
00411         , vector3_type & min_coord
00412         , vector3_type & max_coord
00413         ) const
00414       {
00415         OpenTissue::geometry::compute_plane_aabb(this->n(), this->w(), min_coord, max_coord);
00416       }
00417 
00418     };
00419 
00420 
00430     template<typename T>
00431     inline Plane< typename math::BasicMathTypes< T, size_t> > 
00432       make_plane(math::Vector3<T> const & n, T const & w)
00433     {
00434       typedef typename math::BasicMathTypes<T,size_t>  math_types;
00435       typedef          Plane< math_types >             plane_type;
00436       return plane_type(n,w);
00437     }
00438 
00439 
00440     template<typename T>
00441     std::ostream & operator<< (std::ostream & o, Plane<T> const & p)
00442     {
00443       o << "["
00444         << p.n()(0)
00445         << ","
00446         << p.n()(1)
00447         << ","
00448         << p.n()(2)
00449         << ","
00450         << p.w()
00451         << "]";
00452       return o;
00453     }
00454 
00455     template<typename T>
00456     std::istream & operator>>(std::istream & i, Plane<T> & p)
00457     {
00458       char dummy;
00459       i >> dummy;
00460       i >> p.n()(0);
00461       i >> dummy;
00462       i >> p.n()(1);
00463       i >> dummy;
00464       i >> p.n()(2);
00465       i >> dummy;
00466       i >> p.w();
00467       i >> dummy;
00468       return i;
00469     }
00470 
00471   }  // namespace geometry
00472 
00473 } // namespace OpenTissue
00474 
00475 // OPENTISSUE_CORE_GEOMETRY_GEOMETRY_PLANE_H
00476 #endif

Generated on Thu Dec 1 2011 12:51:48 for HUMIM Tracker by  doxygen 1.7.1