Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_GEOMETRY_GEOMETRY_SPHERE_H
00002 #define OPENTISSUE_CORE_GEOMETRY_GEOMETRY_SPHERE_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_sphere_aabb.h>
00014 #include <OpenTissue/core/function/function_signed_distance_function.h>
00015 #include <OpenTissue/utility/utility_class_id.h>
00016
00017 #include <OpenTissue/core/containers/mesh/polymesh/polymesh.h>
00018 #include <OpenTissue/core/containers/mesh/common/util/mesh_make_sphere.h>
00019 #include <OpenTissue/core/containers/mesh/common/util/mesh_coordinate_iterator.h>
00020
00021 #include <cassert>
00022 #include <algorithm>
00023
00024 namespace OpenTissue
00025 {
00026
00027 namespace geometry
00028 {
00029
00030 template< typename math_types_ >
00031 class Sphere
00032 : public VolumeShape< math_types_ >
00033 , public function::SignedDistanceFunction< math_types_ >
00034 , public OpenTissue::utility::ClassID< Sphere<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_c;
00048 real_type m_r;
00049 real_type m_r_sqr;
00050
00051 public:
00052
00053 size_t const class_id() const { return OpenTissue::utility::ClassID<OpenTissue::geometry::Sphere<math_types_> >::class_id(); }
00054
00055 virtual ~Sphere() {}
00056
00057 Sphere()
00058 : m_c(value_traits::zero(),value_traits::zero(),value_traits::zero())
00059 , m_r(value_traits::zero())
00060 , m_r_sqr(value_traits::zero())
00061 {}
00062
00063 Sphere(Sphere const & s) { set(s); }
00064
00065 explicit Sphere(vector3_type const & center_, real_type const & radius_) { set(center_,radius_); }
00066
00067 real_type volume() const { return (value_traits::four()*value_traits::pi()*m_r_sqr*m_r)/value_traits::three(); }
00068 real_type diameter() const { return value_traits::two()*m_r; }
00069 real_type area() const { return value_traits::four()*value_traits::pi()*m_r_sqr; }
00070 real_type perimeter() const { return value_traits::two()*value_traits::pi()*m_r; }
00071
00072 void set(Sphere const & sphere_)
00073 {
00074 m_c = sphere_.m_c;
00075 m_r = sphere_.m_r;
00076 m_r_sqr = sphere_.m_r_sqr;
00077 }
00078
00079 void set(vector3_type const & center_,real_type const & radius_)
00080 {
00081 center(center_);
00082 radius(radius_);
00083 }
00084
00085 real_type const & radius() const { return m_r; }
00086 vector3_type center() const { return m_c; }
00087
00088 void radius(real_type const & value)
00089 {
00090 assert(value>=value_traits::zero() || !"Sphere::radius(value): Value must be non-negative");
00091 m_r = value;
00092 m_r_sqr = m_r*m_r;
00093 }
00094
00095 real_type const & squared_radius() const { return m_r_sqr; }
00096 void center(vector3_type const & value) { m_c = value; }
00097
00098 void compute_surface_points(std::vector<vector3_type> & points) const
00099 {
00100 typedef polymesh::PolyMesh<math_types> mesh_type;
00101 typedef mesh::CoordinateIterator<mesh_type> coordinate_iterator;
00102
00103 using std::fabs;
00104
00105 if( fabs(m_r) > value_traits::zero())
00106 {
00107 mesh_type mesh;
00108 mesh::make_sphere(m_r,12,12,mesh);
00109 coordinate_iterator c(mesh.vertex_begin());
00110 coordinate_iterator cend(mesh.vertex_end());
00111 for(;c!=cend;++c)
00112 points.push_back( (*c + m_c));
00113 }
00114 else
00115 points.push_back( m_c );
00116 }
00117
00118 void translate(vector3_type const & T) { m_c += T; }
00119 void rotate(matrix3x3_type const & ) {}
00120 void scale(real_type const & s) {
00121 assert(s>=value_traits::zero() || !"Sphere::scale(s): s must be non-negative");
00122 m_r *= s;
00123 m_r_sqr = m_r*m_r;
00124 }
00125 vector3_type get_support_point(vector3_type const & v) const
00126 {
00127 return vector3_type(m_c + unit(v)*m_r);
00128 }
00129
00130 public:
00131
00132 real_type evaluate(vector3_type const & x) const
00133 {
00134 return sqr_length(x-m_c)-m_r_sqr;
00135 }
00136
00137 vector3_type gradient(vector3_type const & x) const
00138 {
00139 return value_traits::two()*(x-m_c);
00140 }
00141
00142 vector3_type normal(vector3_type const & x) const
00143 {
00144 return unit(gradient(x));
00145 }
00146
00147 real_type signed_distance(vector3_type const & x) const
00148 {
00149 return length(x-m_c) - m_r;
00150 }
00151
00152 real_type get_distance(vector3_type const & x) const
00153 {
00154 using std::fabs;
00155 return fabs(signed_distance(x));
00156 }
00157
00158
00170 void compute_collision_aabb(
00171 vector3_type const & r
00172 , matrix3x3_type const &
00173 , vector3_type & min_coord
00174 , vector3_type & max_coord
00175 ) const
00176 {
00177 OpenTissue::geometry::compute_sphere_aabb(r, this->radius(), min_coord, max_coord);
00178 }
00179
00180 };
00181
00182 }
00183
00184 }
00185
00186
00187 #endif