Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_GEOMETRY_GEOMETRY_TETRAHEDRON_H
00002 #define OPENTISSUE_CORE_GEOMETRY_GEOMETRY_TETRAHEDRON_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/geometry/geometry_volume_shape.h>
00013 #include <OpenTissue/core/geometry/geometry_compute_tetrahedron_aabb.h>
00014
00015 #include <OpenTissue/utility/utility_class_id.h>
00016 #include <OpenTissue/core/math/math_constants.h>
00017 #include <OpenTissue/core/geometry/geometry_barycentric.h>
00018
00019 #include <cassert>
00020 #include <cmath>
00021
00022
00023 namespace OpenTissue
00024 {
00025
00026 namespace geometry
00027 {
00028
00029 template< typename math_types_ >
00030 class Tetrahedron
00031 : public VolumeShape< math_types_ >
00032 , public OpenTissue::utility::ClassID< OpenTissue::geometry::Tetrahedron<math_types_> >
00033 {
00034 public:
00035
00036 typedef math_types_ math_types;
00037 typedef typename math_types::value_traits value_traits;
00038 typedef typename math_types::real_type real_type;
00039 typedef typename math_types::vector3_type vector3_type;
00040 typedef typename math_types::matrix3x3_type matrix3x3_type;
00041 typedef typename math_types::quaternion_type quaternion_type;
00042
00043 protected:
00044
00045 vector3_type m_p0;
00046 vector3_type m_p1;
00047 vector3_type m_p2;
00048 vector3_type m_p3;
00049
00050 public:
00051
00052 size_t const class_id() const { return OpenTissue::utility::ClassID<OpenTissue::geometry::Tetrahedron<math_types_> >::class_id(); }
00053
00054 Tetrahedron()
00055 {
00056 m_p0.clear();
00057 m_p1.clear();
00058 m_p2.clear();
00059 m_p3.clear();
00060 }
00061
00062 virtual ~Tetrahedron() {}
00063
00064 Tetrahedron(Tetrahedron const & tetrahedron_) { set(tetrahedron_); }
00065
00066 Tetrahedron( vector3_type const & p0, vector3_type const & p1, vector3_type const & p2, vector3_type const & p3)
00067 {
00068 set(p0,p1,p2,p3);
00069 }
00070
00071 Tetrahedron const & operator=(Tetrahedron const & tetrahedron_)
00072 {
00073 set(tetrahedron_);
00074 return *this;
00075 }
00076
00077 void set(Tetrahedron const & t)
00078 {
00079 m_p0 = t.m_p0;
00080 m_p1 = t.m_p1;
00081 m_p2 = t.m_p2;
00082 m_p3 = t.m_p3;
00083 }
00084
00085 void set(vector3_type const & p0, vector3_type const & p1, vector3_type const & p2, vector3_type const & p3)
00086 {
00087 m_p0 = p0;
00088 m_p1 = p1;
00089 m_p2 = p2;
00090 m_p3 = p3;
00091 }
00092
00093 real_type area() const
00094 {
00095 vector3_type u,v,uXv;
00096 real_type A = value_traits::zero();
00097
00098 u = m_p1-m_p0;
00099 v = m_p2-m_p0;
00100 uXv = (u % v);
00101 A += length(uXv);
00102
00103 u = m_p0-m_p3;
00104 v = m_p1-m_p3;
00105 uXv = (u % v);
00106 A += length(uXv);
00107
00108 u = m_p1-m_p3;
00109 v = m_p2-m_p3;
00110 uXv = (u % v);
00111 A += length(uXv);
00112
00113 u = m_p2-m_p3;
00114 v = m_p0-m_p3;
00115 uXv = (u % v);
00116 A += length(uXv);
00117
00118 return A/value_traits::two();
00119 }
00120
00121 void compute_surface_points(std::vector<vector3_type> & points) const
00122 {
00123 points.push_back(m_p0);
00124 points.push_back(m_p1);
00125 points.push_back(m_p2);
00126 points.push_back(m_p3);
00127 }
00128
00129 vector3_type & p0() { return m_p0; };
00130 vector3_type & p1() { return m_p1; };
00131 vector3_type & p2() { return m_p2; };
00132 vector3_type & p3() { return m_p3; };
00133 vector3_type const & p0() const { return m_p0; };
00134 vector3_type const & p1() const { return m_p1; };
00135 vector3_type const & p2() const { return m_p2; };
00136 vector3_type const & p3() const { return m_p3; };
00137
00138 vector3_type center() const { return vector3_type( (m_p0+m_p1+m_p2+m_p3)/4. ); };
00139
00149 void barycentric(vector3_type const & p,real_type & w1,real_type & w2,real_type & w3,real_type & w4) const
00150 {
00151 OpenTissue::geometry::barycentric_algebraic(m_p0,m_p1,m_p2,m_p3,p,w1,w2,w3,w4);
00152 }
00153
00154 real_type diameter() const
00155 {
00156 using std::max;
00157 using std::sqrt;
00158
00159 vector3_type x30 = m_p3 - m_p0;
00160 vector3_type x20 = m_p2 - m_p0;
00161 vector3_type x10 = m_p1 - m_p0;
00162 real_type d = max( max(x30*x30, x20*x20), x10*x10);
00163 return sqrt(d);
00164 }
00165
00166 vector3_type get_support_point(vector3_type const & v) const
00167 {
00168 vector3_type p;
00169 real_type tst = math::detail::lowest<real_type>();
00170 real_type tmp = v * m_p0;
00171 if (tmp>tst)
00172 {
00173 tst = tmp;
00174 p = m_p0;
00175 }
00176 tmp = v * m_p1;
00177 if (tmp>tst)
00178 {
00179 tst = tmp;
00180 p = m_p1;
00181 }
00182 tmp = v *m_p2;
00183 if (tmp>tst)
00184 {
00185 tst = tmp;
00186 p = m_p2;
00187 }
00188 tmp = v * m_p3;
00189 if (tmp>tst)
00190 {
00191 tst = tmp;
00192 p = m_p3;
00193 }
00194 return p;
00195 }
00196
00197 void translate(vector3_type const & T)
00198 {
00199 m_p0 += T;
00200 m_p1 += T;
00201 m_p2 += T;
00202 m_p3 += T;
00203 }
00204
00205 void rotate(matrix3x3_type const & R)
00206 {
00207 vector3_type c = center();
00208 m_p0 = (R*(m_p0 - c)) + c;
00209 m_p1 = (R*(m_p1 - c)) + c;
00210 m_p2 = (R*(m_p2 - c)) + c;
00211 m_p3 = (R*(m_p3 - c)) + c;
00212 }
00213
00214 void scale(real_type const & s)
00215 {
00216 vector3_type c = center();
00217 m_p0 = s*(m_p0 - c) + c;
00218 m_p1 = s*(m_p1 - c) + c;
00219 m_p2 = s*(m_p2 - c) + c;
00220 m_p3 = s*(m_p3 - c) + c;
00221 }
00222
00223 real_type volume() const
00224 {
00225
00226
00227
00228
00229
00230
00231 return (m_p0[2]*m_p1[1]*m_p2[0] - m_p0[1]*m_p1[2]*m_p2[0] - m_p0[2]*m_p1[0]*m_p2[1]
00232 + m_p0[0]*m_p1[2]*m_p2[1] + m_p0[1]*m_p1[0]*m_p2[2] - m_p0[0]*m_p1[1]*m_p2[2]
00233 - m_p0[2]*m_p1[1]*m_p3[0] + m_p0[1]*m_p1[2]*m_p3[0] + m_p0[2]*m_p2[1]*m_p3[0]
00234 - m_p1[2]*m_p2[1]*m_p3[0] - m_p0[1]*m_p2[2]*m_p3[0] + m_p1[1]*m_p2[2]*m_p3[0]
00235 + m_p0[2]*m_p1[0]*m_p3[1] - m_p0[0]*m_p1[2]*m_p3[1] - m_p0[2]*m_p2[0]*m_p3[1]
00236 + m_p1[2]*m_p2[0]*m_p3[1] + m_p0[0]*m_p2[2]*m_p3[1] - m_p1[0]*m_p2[2]*m_p3[1]
00237 - m_p0[1]*m_p1[0]*m_p3[2] + m_p0[0]*m_p1[1]*m_p3[2] + m_p0[1]*m_p2[0]*m_p3[2]
00238 - m_p1[1]*m_p2[0]*m_p3[2] - m_p0[0]*m_p2[1]*m_p3[2] + m_p1[0]*m_p2[1]*m_p3[2])/6.;
00239 }
00240
00241
00253 void compute_collision_aabb(
00254 vector3_type const & r
00255 , matrix3x3_type const & R
00256 , vector3_type & min_coord
00257 , vector3_type & max_coord
00258 ) const
00259 {
00260 compute_tetrahedron_aabb( *this, min_coord, max_coord );
00261 }
00262
00263
00264 };
00265
00266 }
00267
00268 }
00269
00270
00271 #endif