Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_GEOMETRY_GEOMETRY_TORUS_H
00002 #define OPENTISSUE_CORE_GEOMETRY_GEOMETRY_TORUS_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/function/function_signed_distance_function.h>
00014 #include <OpenTissue/utility/utility_class_id.h>
00015
00016 #include <cmath>
00017
00018
00019 namespace OpenTissue
00020 {
00021
00022 namespace geometry
00023 {
00024
00025
00026
00027
00028
00033 template<typename math_types_>
00034 class Torus
00035 : public VolumeShape< math_types_ >
00036 , public function::SignedDistanceFunction< math_types_ >
00037 , public OpenTissue::utility::ClassID< Torus<math_types_> >
00038 {
00039 public:
00040
00041 typedef math_types_ math_types;
00042 typedef typename math_types::value_traits value_traits;
00043 typedef typename math_types::real_type real_type;
00044 typedef typename math_types::vector3_type vector3_type;
00045 typedef typename math_types::matrix3x3_type matrix3x3_type;
00046 typedef typename math_types::quaternion_type quaternion_type;
00047
00048 protected:
00049
00050 vector3_type m_center;
00051 real_type m_radius;
00052 real_type m_tube;
00053
00054 public:
00055
00056 size_t const class_id() const { return OpenTissue::utility::ClassID<OpenTissue::geometry::Torus<math_types_> >::class_id(); }
00057
00058 Torus()
00059 : m_center(value_traits::zero())
00060 , m_radius(value_traits::zero())
00061 , m_tube(value_traits::zero())
00062 {}
00063
00075 Torus(vector3_type const & center, real_type const & radius, real_type const & tube)
00076 {
00077 set(center, radius, tube);
00078 }
00079
00080 virtual ~Torus()
00081 {}
00082
00083 public:
00084
00096 void set(vector3_type const & center, real_type const & radius, real_type const & tube)
00097 {
00098 m_center = center;
00099 m_radius = radius;
00100 m_tube = tube;
00101 }
00102
00103 vector3_type center() const { return m_center; }
00104 real_type const & radius() const { return m_radius; }
00105 real_type const & tube() const { return m_tube; }
00106
00107 public:
00108
00109 vector3_type get_support_point(vector3_type const & ) const
00110 {
00111
00112 return vector3_type();
00113 }
00114
00115 real_type volume() const
00116 {
00117 return real_type(value_traits::two()*value_traits::pi()*value_traits::pi()*m_tube*m_tube*m_radius);
00118 }
00119
00120 real_type area() const
00121 {
00122 return real_type(value_traits::four()*value_traits::pi()*value_traits::pi()*m_tube*m_radius);
00123 }
00124
00125 real_type diameter() const
00126 {
00127 return real_type(m_radius+m_tube);
00128 }
00129
00130 void compute_surface_points(std::vector<vector3_type>& ) const
00131 {
00132
00133 }
00134
00135 public:
00136
00137 void translate(vector3_type const & T)
00138 {
00139 m_center += T;
00140 }
00141
00142 void rotate(matrix3x3_type const & )
00143 {
00144
00145 }
00146
00147 void scale(real_type const & s)
00148 {
00149 m_radius *= s;
00150 m_tube *= s;
00151 }
00152
00153 public:
00154
00159 real_type evaluate(vector3_type const & x) const
00160 {
00161
00162 using std::sqrt;
00163 vector3_type const r = x-m_center;
00164 real_type const tmp = m_radius-sqrt(r[0]*r[0]+r[1]*r[1]);
00165 return real_type(tmp*tmp+r[2]*r[2]-m_tube*m_tube);
00166 }
00167
00168 vector3_type gradient(vector3_type const & x) const
00169 {
00170
00171 using std::sqrt;
00172 vector3_type const r = x-m_center;
00173 real_type const len = sqrt(r[0]*r[0]+r[1]*r[1]);
00174 if (len > value_traits::zero()) {
00175 real_type const tmp = -value_traits::two()*m_radius/len;
00176 return vector3_type(r[0]*tmp+value_traits::two()*r[0], r[1]*tmp+value_traits::two()*r[1], value_traits::two()*r[2]);
00177 }
00178 return vector3_type(value_traits::zero());
00179 }
00180
00181 vector3_type normal(vector3_type const & x) const
00182 {
00183
00184
00185
00186
00187
00188
00189
00190 return unit(gradient(x));
00191 }
00192
00193 real_type signed_distance(vector3_type const & x) const
00194 {
00195
00196 using std::sqrt;
00197 real_type const f = evaluate(x);
00198 real_type const sign = OpenTissue::math::sgn(f);
00199 return real_type(boost::numeric_cast<real_type>(0.1)*sign*sqrt(sign*f));
00200 }
00201
00213 void compute_collision_aabb(
00214 vector3_type const & r
00215 , matrix3x3_type const & R
00216 , vector3_type & min_coord
00217 , vector3_type & max_coord
00218 ) const
00219 {
00220 assert(false || !"Sorry not implemented yet!");
00221 }
00222
00223 };
00224
00225 }
00226
00227 }
00228
00229
00230 #endif