Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_GEOMETRY_GEOMETRY_PRISM_H
00002 #define OPENTISSUE_CORE_GEOMETRY_GEOMETRY_PRISM_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/utility/utility_class_id.h>
00014 #include <OpenTissue/core/math/math_constants.h>
00015
00016
00017 #include <cassert>
00018 #include <cmath>
00019 #include <iostream>
00020
00021 namespace OpenTissue
00022 {
00023
00024 namespace geometry
00025 {
00026
00030 template< typename math_types_ >
00031 class Prism
00032 : public VolumeShape< math_types_ >
00033 , public OpenTissue::utility::ClassID< Prism<math_types_> >
00034 {
00035 public:
00036
00037 typedef math_types_ math_types;
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 real_type m_height;
00049
00050 public:
00051
00052 size_t const class_id() const { return OpenTissue::utility::ClassID<OpenTissue::geometry::Prism<math_types_> >::class_id(); }
00053
00054 virtual ~Prism() {}
00055
00056 void compute_surface_points(std::vector<vector3_type> & points) const
00057 {
00058 vector3_type u = (m_p1-m_p0);
00059 vector3_type v = (m_p2-m_p0);
00060 vector3_type n = unit(u % v);
00061 points.push_back(m_p0);
00062 points.push_back(m_p1);
00063 points.push_back(m_p2);
00064 vector3_type p0h = m_p0 + n*m_height;
00065 vector3_type p1h = m_p1 + n*m_height;
00066 vector3_type p2h = m_p2 + n*m_height;
00067 points.push_back(p0h);
00068 points.push_back(p1h);
00069 points.push_back(p2h);
00070 }
00071
00072 vector3_type center() const
00073 {
00074 vector3_type u = (m_p1-m_p0);
00075 vector3_type v = (m_p2-m_p0);
00076 vector3_type n = unit( u % v);
00077 vector3_type tmp = ((m_p0 + m_p1 + m_p2)/3.) + (0.5*m_height)*n;
00078 return tmp;
00079 }
00080
00081 public:
00082
00083 real_type const & height() const { return m_height; }
00084 vector3_type const & p0() const { return m_p0; }
00085 vector3_type const & p1() const { return m_p1; }
00086 vector3_type const & p2() const { return m_p2; }
00087
00088 Prism()
00089 : m_p0(-1,0,0)
00090 , m_p1(1,0,0)
00091 , m_p2(0,1,0)
00092 ,m_height(1.)
00093 { }
00094
00103 Prism(vector3_type const & p0,vector3_type const & p1,vector3_type const & p2, real_type const & height)
00104 {
00105 set(p0,p1,p2,height);
00106 }
00107
00108 Prism(Prism const & p) { set(p); }
00109
00116 void set(Prism const & p) { set(p.m_p0,p.m_p1,p.m_p2,p.m_height); }
00117
00126 void set( vector3_type const & p0_, vector3_type const & p1_, vector3_type const & p2_, real_type const & height_)
00127 {
00128 assert(height_>=0 || !"Prism::set(): Height must be non-negative");
00129 m_p0 = p0_;
00130 m_p1 = p1_;
00131 m_p2 = p2_;
00132 m_height = height_;
00133 }
00134
00142 void xform(vector3_type const & T, matrix3x3_type const & R)
00143 {
00144 vector3_type c = center();
00145 m_p0 = (R * (m_p0 - c)) + c + T;
00146 m_p1 = (R * (m_p1 - c)) + c + T;
00147 m_p2 = (R * (m_p2 - c)) + c + T;
00148 }
00149
00155 real_type diameter() const
00156 {
00157 using std::max;
00158
00159 vector3_type tmp;
00160 tmp = (m_p1-m_p0);
00161 real_type l0 = length(tmp);
00162 tmp = (m_p2-m_p1);
00163 real_type l1 = length(tmp);
00164 tmp = (m_p2-m_p0);
00165 real_type l2 = length(tmp);
00166 return max(l0, max(l1,l2) );
00167 }
00168
00174 real_type area() const
00175 {
00176 vector3_type u = (m_p1-m_p0);
00177 vector3_type v = (m_p2-m_p0);
00178 vector3_type uXv = u % v;
00179
00180 vector3_type w;
00181 w = (m_p2-m_p1);
00182 return length(uXv) + (length(u) + length(v) + length(w))*m_height;
00183 }
00184
00190 real_type volume() const
00191 {
00192 vector3_type u = (m_p1-m_p0);
00193 vector3_type v = (m_p2-m_p0);
00194 vector3_type uXv = u % v;
00195 return 0.5*m_height*length(uXv);
00196 }
00197
00202 void translate(vector3_type const & T)
00203 {
00204 m_p0 += T;
00205 m_p1 += T;
00206 m_p2 += T;
00207 }
00208
00213 void rotate(matrix3x3_type const & R)
00214 {
00215 vector3_type c = center();
00216 m_p0 = (R*(m_p0 - c))+c;
00217 m_p1 = (R*(m_p1 - c))+c;
00218 m_p2 = (R*(m_p2 - c))+c;
00219 }
00220
00225 void scale(real_type const & s)
00226 {
00227 assert(s>=0);
00228 vector3_type c = center();
00229 m_p0 = (s*(m_p0 - c))+c;
00230 m_p1 = (s*(m_p1 - c))+c;
00231 m_p2 = (s*(m_p2 - c))+c;
00232 m_height *= s;
00233 }
00234
00235 vector3_type get_support_point(vector3_type const & v) const
00236 {
00237 vector3_type p;
00238 std::vector<vector3_type> c;
00239 compute_surface_points(c);
00240 real_type tst = math::detail::lowest<real_type>();
00241 for(int i=0;i<6;++i)
00242 {
00243 real_type tmp = v*c[i];
00244 if (tmp>tst)
00245 {
00246 tst = tmp;
00247 p = c[i];
00248 }
00249 }
00250 return p;
00251 }
00252
00264 void compute_collision_aabb(
00265 vector3_type const & r
00266 , matrix3x3_type const & R
00267 , vector3_type & min_coord
00268 , vector3_type & max_coord
00269 ) const
00270 {
00271 assert(false || !"Sorry not implemented yet!");
00272 }
00273
00274 };
00275
00276 }
00277
00278 }
00279
00280
00281 #endif