00001 #ifndef OPENTISSUE_CORE_GEOMETRY_GEOMETRY_QUADRIC_H
00002 #define OPENTISSUE_CORE_GEOMETRY_GEOMETRY_QUADRIC_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/math_vector3.h>
00013 #include <OpenTissue/core/math/math_matrix3x3.h>
00014 #include <cmath>
00015
00016 namespace OpenTissue
00017 {
00018 namespace geometry
00019 {
00020
00049 template<typename real_type_>
00050 class Quadric
00051 {
00052 public:
00053
00054 typedef real_type_ real_type;
00055 typedef OpenTissue::math::Vector3<real_type> vector3_type;
00056 typedef OpenTissue::math::Matrix3x3<real_type> matrix3x3_type;
00057 typedef Quadric<real_type> quadric_type;
00058
00059 public:
00060
00061 matrix3x3_type m_A;
00062 vector3_type m_B;
00063 real_type m_C;
00064
00065 public:
00066
00067 Quadric()
00068 : m_A(1,0,0,0,1,0,0,0,1)
00069 , m_B(0,0,0)
00070 , m_C(0)
00071 {}
00072
00073 Quadric(matrix3x3_type const & A,vector3_type const & B,real_type const & C)
00074 : m_A(A)
00075 , m_B(B)
00076 , m_C(C)
00077 {}
00078
00079 public:
00080
00081 real_type operator()(vector3_type const & x){ return x*(m_A*x) + 2.0*m_B*x + m_C; }
00082
00083 quadric_type & operator=(quadric_type const & q)
00084 {
00085 m_A = q.m_A;
00086 m_B = q.m_B;
00087 m_C = q.m_C;
00088 return (*this);
00089 }
00090
00091 quadric_type & operator*(real_type const & s)
00092 {
00093 m_A *= s;
00094 m_B *= s;
00095 m_C *= s;
00096 return (*this);
00097 }
00098
00099 quadric_type operator+(quadric_type const & q){ return quadric_type( m_A + q.m_A, m_B + q.m_B, m_C + q.m_C ); }
00100
00101 public:
00102
00109 void set_sphere(real_type const & radius, vector3_type const & center)
00110 {
00111 m_A = matrix3x3_type( 1,0,0, 0,1,0, 0,0,1);
00112 m_B = - center;
00113 m_C = center*center - radius*radius;
00114 }
00115
00150 void set_plane_product(vector3_type const & p,vector3_type const & np,vector3_type const & q,vector3_type const & nq)
00151 {
00152
00153
00154
00155 m_A = - outer_prod(np,nq);
00156 real_type nqq = nq*q;
00157 real_type npp = np*p;
00158 m_B = (np*nqq + nq*npp)*.5;
00159 m_C = - npp*nqq;
00160
00161
00162
00163
00164 m_A(0,1) += m_A(1,0);
00165 m_A(0,1) *= .5;
00166 m_A(0,2) += m_A(2,0);
00167 m_A(0,2) *= .5;
00168 m_A(1,2) += m_A(2,1);
00169 m_A(1,2) *= .5;
00170 m_A(1,0) = m_A(0,1);
00171 m_A(2,0) = m_A(0,2);
00172 m_A(2,1) = m_A(1,2);
00173 }
00174
00186 void set_cylinder(
00187 vector3_type const & center
00188 , vector3_type const & axis0, real_type const & radius0
00189 , vector3_type const & axis1, real_type const & radius1
00190 )
00191 {
00192 matrix3x3_type A0 = outer_prod(axis0,axis0);
00193 matrix3x3_type A1 = outer_prod(axis1,axis1);
00194 real_type r0r0 = radius0*radius0;
00195 real_type r1r1 = radius1*radius1;
00196 m_A = r1r1*A0 + r0r0*A1;
00197 real_type ca0 = center*axis0;
00198 real_type ca1 = center*axis1;
00199 m_B = - (r1r1*ca0)*axis0 - (r0r0*ca1)*axis1;
00200 m_C = r1r1*ca0*ca0 + r0r0*ca1*ca1 - r0r0*r1r1;
00201 }
00202
00203 };
00204
00205
00206 template<typename real_type,typename vector3_type>
00207 Quadric<real_type> make_sphere_quadric(real_type const & radius, vector3_type const & center)
00208 {
00209 Quadric<real_type> Q;
00210 Q.set_sphere(radius,center);
00211 return Q;
00212 }
00213
00214 template<typename real_type,typename vector3_type>
00215 Quadric<real_type> make_cylinder_quadric(
00216 vector3_type const & center
00217 , vector3_type const & axis0
00218 , real_type const & radius0
00219 , vector3_type const & axis1
00220 , real_type const & radius1
00221 )
00222 {
00223 Quadric<real_type> Q;
00224 Q.set_cylinder(center,axis0,radius0,axis1,radius1);
00225 return Q;
00226 }
00227
00228 template<typename vector3_type>
00229 Quadric<typename vector3_type::value_type> make_plane_product_quadric(vector3_type const & p,vector3_type const & np,vector3_type const & q,vector3_type const & nq)
00230 {
00231 Quadric<typename vector3_type::value_type> Q;
00232 Q.set_plane_product(p,np,q,nq);
00233 return Q;
00234 }
00235
00244 template<typename quadric_type>
00245 bool is_valid_ellipsoid(quadric_type const & Q)
00246 {
00247 typename quadric_type::matrix3x3_type V;
00248 typename quadric_type::vector3_type d;
00249 math::eigen(Q.m_A,V,d);
00250
00251 if(d(0)<0)
00252 return false;
00253 if(d(1)<0)
00254 return false;
00255 if(d(2)<0)
00256 return false;
00257 return true;
00258 }
00259
00260 }
00261 }
00262
00263
00264 #endif