00001 #ifndef OPENTISSUE_CORE_GEOMETRY_GEOMETRY_PLANE_H
00002 #define OPENTISSUE_CORE_GEOMETRY_GEOMETRY_PLANE_H
00003
00004
00005
00006
00007
00008
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
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
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
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
00274 ty = unit(cross(m_n,tx));
00275
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> & ) const
00316 {
00317 }
00318
00319 vector3_type get_support_point(vector3_type const & ) const
00320 {
00321 return vector3_type();
00322 }
00323
00324 void scale(real_type const & )
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 & ) const
00388 {
00389 return m_n;
00390 }
00391
00392 vector3_type normal(vector3_type const & ) const
00393 {
00394 return unit(m_n);
00395 }
00396
00408 void compute_collision_aabb(
00409 vector3_type const &
00410 , matrix3x3_type const &
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 }
00472
00473 }
00474
00475
00476 #endif