Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_GEOMETRY_GEOMETRY_CAPSULE_H
00002 #define OPENTISSUE_CORE_GEOMETRY_GEOMETRY_CAPSULE_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_perpendicular_line_point.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_functions.h>
00017
00018 #include <cmath>
00019
00020 namespace OpenTissue
00021 {
00022
00023 namespace geometry
00024 {
00025
00030 template<typename math_types_>
00031 class Capsule
00032 : public VolumeShape< math_types_ >
00033 , public function::SignedDistanceFunction< math_types_ >
00034 , public OpenTissue::utility::ClassID< Capsule<math_types_> >
00035 {
00036 public:
00037
00038 typedef math_types_ math_types;
00039 typedef typename math_types::value_traits value_traits;
00040 typedef typename math_types::real_type real_type;
00041 typedef typename math_types::vector3_type vector3_type;
00042 typedef typename math_types::matrix3x3_type matrix3x3_type;
00043 typedef typename math_types::quaternion_type quaternion_type;
00044
00045 protected:
00046
00047 vector3_type m_point0;
00048 vector3_type m_point1;
00049 real_type m_radius;
00050
00051 public:
00052
00053 size_t const class_id() const { return OpenTissue::utility::ClassID<OpenTissue::geometry::Capsule<math_types_> >::class_id(); }
00054
00055 Capsule()
00056 : m_point0(value_traits::zero())
00057 , m_point1(value_traits::zero())
00058 , m_radius(value_traits::one())
00059 {}
00060
00061
00062 Capsule(vector3_type const & point0, vector3_type const & point1, real_type const & radius)
00063 {
00064 set(point0, point1, radius);
00065 }
00066
00067 virtual ~Capsule()
00068 {}
00069
00070 public:
00071
00072 void set(vector3_type const & point0, vector3_type const & point1, real_type const & radius)
00073 {
00074 m_point0 = point0;
00075 m_point1 = point1;
00076 m_radius = radius;
00077 }
00078
00079 vector3_type & point0() { return m_point0; }
00080 vector3_type const & point0() const { return m_point0; }
00081 vector3_type & point1() { return m_point1; }
00082 vector3_type const & point1() const { return m_point1; }
00083
00084 real_type & radius() { return m_radius; }
00085 real_type const & radius() const { return m_radius; }
00086
00087 public:
00088
00089 vector3_type get_support_point(vector3_type const & ) const { return vector3_type(); }
00090
00091 real_type volume() const
00092 {
00093 real_type const h = length(m_point1-m_point0);
00094 real_type const tmp = value_traits::pi()*m_radius*m_radius;
00095 real_type const Vcylinder = tmp*h;
00096 real_type const Vsphere = (4./3.)*tmp*m_radius;
00097 return Vcylinder+Vsphere;
00098 }
00099
00100 real_type area() const
00101 {
00102 real_type const h = length(m_point1-m_point0);
00103 real_type const tmp = value_traits::two()*value_traits::pi()*m_radius;
00104 real_type const Scylinder = tmp*h;
00105 real_type const Ssphere = value_traits::two()*tmp*m_radius;
00106 return Scylinder+Ssphere;
00107 }
00108
00109 real_type diameter() const
00110 {
00111
00112
00113 return value_traits::zero();
00114 }
00115
00116 void compute_surface_points(std::vector<vector3_type>& ) const
00117 {
00118
00119
00120
00121 }
00122
00123 vector3_type center() const { return vector3_type( (m_point0+m_point1)/value_traits::two() ); }
00124
00125 public:
00126
00144 real_type evaluate(vector3_type const & x) const
00145 {
00146 vector3_type const l = closest_point_on_line_segment(x)-x;
00147 return l*l - m_radius*m_radius;
00148 }
00149
00150 vector3_type gradient(vector3_type const & x) const
00151 {
00152
00153 return vector3_type();
00154 }
00155
00156 vector3_type normal(vector3_type const & x) const
00157 {
00158 vector3_type const dir = x-closest_point_on_line_segment(x);
00159 return unit(dir);
00160 }
00161
00165 real_type signed_distance(vector3_type const & x) const
00166 {
00167 vector3_type const l = x-closest_point_on_line_segment(x);
00168 return length(l) - m_radius;
00169 }
00170
00174 vector3_type closest_point_on_line_segment(vector3_type const & x) const
00175 {
00176 real_type t;
00177 compute_perpendicular_line_point(m_point0, m_point1, x, t);
00178 return m_point0+math::clamp_zero_one(t)*(m_point1-m_point0);
00179 }
00180
00181 public:
00182
00183 void translate(vector3_type const & T)
00184 {
00185 m_point0 += T;
00186 m_point1 += T;
00187 }
00188
00189 void rotate(matrix3x3_type const & R)
00190 {
00191 vector3_type const c = this->center();
00192 m_point0 = R*(m_point0-c) + c;
00193 m_point1 = R*(m_point1-c) + c;
00194 }
00195
00196 void scale(real_type const & s)
00197 {
00198 vector3_type const c = this->center();
00199
00200 m_point0 = s*(m_point0-c) + c;
00201 m_point1 = s*(m_point1-c) + c;
00202 m_radius *= s;
00203 }
00204
00216 void compute_collision_aabb(
00217 vector3_type const &
00218 , matrix3x3_type const &
00219 , vector3_type & min_coord
00220 , vector3_type & max_coord
00221 ) const
00222 {
00223 using std::min;
00224 using std::max;
00225
00226 min_coord = min(m_point0,m_point1);
00227 max_coord = max(m_point0,m_point1);
00228 min_coord -= vector3_type( m_radius, m_radius, m_radius );
00229 max_coord += vector3_type( m_radius, m_radius, m_radius );
00230 }
00231
00232
00233 };
00234
00235 }
00236
00237 }
00238
00239
00240 #endif