00001 #ifndef OPENTISSUE_CORE_GEOMETRY_GEOMETRY_TRIANGLE_H
00002 #define OPENTISSUE_CORE_GEOMETRY_GEOMETRY_TRIANGLE_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/utility/utility_class_id.h>
00014
00015 #include <OpenTissue/core/geometry/geometry_barycentric.h>
00016
00017 #include <cassert>
00018
00019 namespace OpenTissue
00020 {
00021
00022 namespace geometry
00023 {
00024
00031 template< typename math_types_ >
00032 class Triangle
00033 : public BaseShape< math_types_ >
00034 , public OpenTissue::utility::ClassID< Triangle<math_types_> >
00035 {
00036 public:
00037
00038 typedef math_types_ math_types;
00039 typedef typename math_types::real_type real_type;
00040 typedef typename math_types::vector3_type vector3_type;
00041 typedef typename math_types::matrix3x3_type matrix3x3_type;
00042
00043 protected:
00044
00045 typedef typename math_types::value_traits value_traits;
00046
00047 protected:
00048
00049 vector3_type * m_p0;
00050 vector3_type * m_p1;
00051 vector3_type * m_p2;
00052 bool m_bound;
00053
00054 public:
00055
00056 size_t const class_id() const { return OpenTissue::utility::ClassID<OpenTissue::geometry::Triangle<math_types_> >::class_id(); }
00057
00058 Triangle()
00059 : m_p0(0)
00060 , m_p1(0)
00061 , m_p2(0)
00062 , m_bound(false)
00063 {}
00064
00065 virtual ~Triangle()
00066 {
00067 if(!m_bound)
00068 {
00069 if(m_p0)
00070 delete m_p0;
00071 if(m_p1)
00072 delete m_p1;
00073 if(m_p2)
00074 delete m_p2;
00075 }
00076 }
00077
00078 Triangle(Triangle const & triangle)
00079 {
00080 m_p0 = 0;
00081 m_p1 = 0;
00082 m_p2 = 0;
00083 m_bound = false;
00084 set(triangle);
00085 }
00086
00087 explicit Triangle(vector3_type const & p0_,vector3_type const & p1_,vector3_type const & p2_)
00088 {
00089 m_p0 = 0;
00090 m_p1 = 0;
00091 m_p2 = 0;
00092 m_bound = false;
00093 set(p0_,p1_,p2_);
00094 }
00095
00104 explicit Triangle(vector3_type * p0_,vector3_type * p1_,vector3_type * p2_)
00105 {
00106 m_p0 = 0;
00107 m_p1 = 0;
00108 m_p2 = 0;
00109 m_bound = false;
00110 bind(p0_,p1_,p2_);
00111 }
00112
00118 template<typename face_type>
00119 Triangle(face_type * f)
00120 : m_p0(0)
00121 , m_p1(0)
00122 , m_p2(0)
00123 , m_bound(false)
00124 {
00125 set(f);
00126 }
00127
00133 Triangle const & operator=(Triangle const & triangle)
00134 {
00135 set(triangle);
00136 return *this;
00137 }
00138
00139 public:
00140
00141 template<typename face_type>
00142 void set(face_type * f)
00143 {
00144 typedef typename face_type::mesh_type mesh_type;
00145 typedef typename mesh_type::face_vertex_circulator face_vertex_circulator;
00146 if( valency(*f)!=3)
00147 return;
00148 face_vertex_circulator v0(*f);
00149 face_vertex_circulator v1(*f);++v1;
00150 face_vertex_circulator v2(*f);++v2;++v2;
00151 bind( &(v0->m_coord), &(v1->m_coord), &(v2->m_coord) );
00152 }
00153
00154 void set(Triangle const & triangle)
00155 {
00156 if(triangle.m_bound)
00157 {
00158 bind(triangle.m_p0,triangle.m_p1,triangle.m_p2);
00159 }
00160 else
00161 {
00162 unbind();
00163 set(*(triangle.m_p0),*(triangle.m_p1),*(triangle.m_p2));
00164 }
00165 }
00166
00167 void set(const vector3_type & p0_, const vector3_type & p1_, const vector3_type & p2_)
00168 {
00169 unbind();
00170 assert(m_p0 || !"Triangle::set(): p0 member was null");
00171 assert(m_p1 || !"Triangle::set(): p1 member was null");
00172 assert(m_p2 || !"Triangle::set(): p2 member was null");
00173 *m_p0 = p0_;
00174 *m_p1 = p1_;
00175 *m_p2 = p2_;
00176 }
00177
00178 public:
00179
00187 void bind(vector3_type * p0_, vector3_type * p1_, vector3_type * p2_)
00188 {
00189 assert(p0_ || !"Triangle::set(): p0 argument was null");
00190 assert(p1_ || !"Triangle::set(): p1 argument was null");
00191 assert(p2_ || !"Triangle::set(): p2 argument was null");
00192 if(m_bound)
00193 {
00194 m_p0 = p0_;
00195 m_p1 = p1_;
00196 m_p2 = p2_;
00197 }
00198 else
00199 {
00200 if(m_p0)
00201 delete m_p0;
00202 m_p0 = p0_;
00203 if(m_p1)
00204 delete m_p1;
00205 m_p1 = p1_;
00206 if(m_p2)
00207 delete m_p2;
00208 m_p2 = p2_;
00209 }
00210 m_bound = true;
00211 }
00212
00213 void unbind()
00214 {
00215 if(!m_bound && m_p0 && m_p1 && m_p2)
00216 return;
00217
00218 vector3_type * tmp = 0;
00219
00220 tmp = m_p0;
00221 m_p0 = new vector3_type(0,0,0);
00222 if(tmp)
00223 (*m_p0) = (*tmp);
00224
00225 tmp = m_p1;
00226 m_p1 = new vector3_type(0,0,0);
00227 if(tmp)
00228 (*m_p1) = (*tmp);
00229
00230 tmp = m_p2;
00231 m_p2 = new vector3_type(0,0,0);
00232 if(tmp)
00233 (*m_p2) = (*tmp);
00234
00235 m_bound = false;
00236 };
00237
00238 public:
00247 void barycentric(vector3_type const & p,real_type & w1,real_type & w2,real_type & w3)const
00248 {
00249 OpenTissue::geometry::barycentric_algebraic((*m_p0),(*m_p1),(*m_p2),p,w1,w2,w3);
00250 }
00251
00252 public:
00253
00254 real_type area()const
00255 {
00256 assert(m_p0 || !"Triangle::area(): p0 member was null");
00257 assert(m_p1 || !"Triangle::area(): p1 member was null");
00258 assert(m_p2 || !"Triangle::area(): p2 member was null");
00259 vector3_type u = (*m_p1)-(*m_p0);
00260 vector3_type v = (*m_p2)-(*m_p0);
00261 vector3_type uXv = u % v;
00262 return 0.5*length(uXv);
00263 };
00264
00270 void compute_surface_points(std::vector<vector3_type> & points)const
00271 {
00272 assert(m_p0 || !"Triangle::compute_surface_points(): p0 member was null");
00273 assert(m_p1 || !"Triangle::compute_surface_points(): p1 member was null");
00274 assert(m_p2 || !"Triangle::compute_surface_points(): p2 member was null");
00275 points.push_back(*m_p0);
00276 points.push_back(*m_p1);
00277 points.push_back(*m_p2);
00278 }
00279
00280 vector3_type get_support_point(vector3_type const & v) const
00281 {
00282 return v;
00283 }
00284
00285 vector3_type & p0() { assert(m_p0); return (*m_p0); }
00286 vector3_type & p1() { assert(m_p1); return (*m_p1); }
00287 vector3_type & p2() { assert(m_p2); return (*m_p2); }
00288 vector3_type const & p0()const { assert(m_p0); return (*m_p0); }
00289 vector3_type const & p1()const { assert(m_p1); return (*m_p1); }
00290 vector3_type const & p2()const { assert(m_p2); return (*m_p2); }
00291
00292 vector3_type center() const
00293 {
00294 assert(m_p0 || !"Triangle::center(): p0 member was null");
00295 assert(m_p1 || !"Triangle::center(): p1 member was null");
00296 assert(m_p2 || !"Triangle::center(): p2 member was null");
00297 vector3_type tmp = ((*m_p0) +(*m_p1) +(*m_p2) )/3.;
00298 return tmp;
00299 }
00300
00301 vector3_type normal()const
00302 {
00303 assert(m_p0 || !"Triangle::normal(): p0 member was null");
00304 assert(m_p1 || !"Triangle::normal(): p1 member was null");
00305 assert(m_p2 || !"Triangle::normal(): p2 member was null");
00306 vector3_type u = (*m_p1)-(*m_p0);
00307 vector3_type v = (*m_p2)-(*m_p0);
00308 return unit(u%v);
00309 }
00310
00311
00312 void translate(vector3_type const & T)
00313 {
00314 assert(m_p0 || !"Triangle::scale() p0 member was NULL");
00315 assert(m_p1 || !"Triangle::scale() p1 member was NULL");
00316 assert(m_p2 || !"Triangle::scale() p2 member was NULL");
00317 *m_p0 += T;
00318 *m_p1 += T;
00319 *m_p2 += T;
00320 }
00321
00322 void rotate(matrix3x3_type const & R)
00323 {
00324
00325 }
00326
00332 void scale(real_type const & s)
00333 {
00334 assert(m_p0 || !"Triangle::scale() p0 member was NULL");
00335 assert(m_p1 || !"Triangle::scale() p1 member was NULL");
00336 assert(m_p2 || !"Triangle::scale() p2 member was NULL");
00337 vector3_type c = center();
00338 *m_p0 = (*m_p0 - c)*s + c;
00339 *m_p1 = (*m_p1 - c)*s + c;
00340 *m_p2 = (*m_p2 - c)*s + c;
00341 }
00342
00354 void compute_collision_aabb(
00355 vector3_type const & r
00356 , matrix3x3_type const & R
00357 , vector3_type & min_coord
00358 , vector3_type & max_coord
00359 ) const
00360 {
00361 assert(m_p0 || !"Triangle::compute_collision_aabb() p0 member was NULL");
00362 assert(m_p1 || !"Triangle::compute_collision_aabb() p1 member was NULL");
00363 assert(m_p2 || !"Triangle::compute_collision_aabb() p2 member was NULL");
00364
00365 using std::min;
00366 using std::max;
00367
00368 min_coord = min( *m_p0, min( *m_p1, *m_p2 ) );
00369 max_coord = max( *m_p0, max( *m_p1, *m_p2 ) );
00370
00371 }
00372
00373 };
00374
00375 }
00376
00377 }
00378
00379
00380 #endif