00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00035
00036
00037
00038
00039
00040
00041 #ifndef OPENMESH_GEOMETRY_QUADRIC_HH
00042 #define OPENMESH_GEOMETRY_QUADRIC_HH
00043
00044
00045
00046
00047 #include <OpenMesh/Core/System/config.hh>
00048 #include <OpenMesh/Core/Math/VectorT.hh>
00049 #include <OpenMesh/Core/Utils/GenProg.hh>
00050
00051
00052
00053 namespace OpenMesh {
00054 namespace Geometry {
00055
00056
00057
00058
00059
00066 template <class Scalar>
00067 class QuadricT
00068 {
00069 public:
00070 typedef Scalar value_type;
00071 typedef QuadricT<Scalar> type;
00072 typedef QuadricT<Scalar> Self;
00073
00074
00075
00076
00077
00079 QuadricT(Scalar _a, Scalar _b, Scalar _c, Scalar _d,
00080 Scalar _e, Scalar _f, Scalar _g,
00081 Scalar _h, Scalar _i,
00082 Scalar _j)
00083 : a_(_a), b_(_b), c_(_c), d_(_d),
00084 e_(_e), f_(_f), g_(_g),
00085 h_(_h), i_(_i),
00086 j_(_j)
00087 {
00088 }
00089
00090
00092 QuadricT( Scalar _a=0.0, Scalar _b=0.0, Scalar _c=0.0, Scalar _d=0.0 )
00093 : a_(_a*_a), b_(_a*_b), c_(_a*_c), d_(_a*_d),
00094 e_(_b*_b), f_(_b*_c), g_(_b*_d),
00095 h_(_c*_c), i_(_c*_d),
00096 j_(_d*_d)
00097 {}
00098
00099 template <class _Point>
00100 QuadricT(const _Point& _pt)
00101 {
00102 set_distance_to_point(_pt);
00103 }
00104
00105 template <class _Normal, class _Point>
00106 QuadricT(const _Normal& _n, const _Point& _p)
00107 {
00108 set_distance_to_plane(_n,_p);
00109 }
00110
00111
00112 void set(Scalar _a, Scalar _b, Scalar _c, Scalar _d,
00113 Scalar _e, Scalar _f, Scalar _g,
00114 Scalar _h, Scalar _i,
00115 Scalar _j)
00116 {
00117 a_ = _a; b_ = _b; c_ = _c; d_ = _d;
00118 e_ = _e; f_ = _f; g_ = _g;
00119 h_ = _h; i_ = _i;
00120 j_ = _j;
00121 }
00122
00123
00124 template <class _Point>
00125 void set_distance_to_point(const _Point& _pt)
00126 {
00127 set(1, 0, 0, -_pt[0],
00128 1, 0, -_pt[1],
00129 1, -_pt[2],
00130 dot(_pt,_pt));
00131 }
00132
00133
00134 void set_distance_to_plane(Scalar _a, Scalar _b, Scalar _c, Scalar _d)
00135 {
00136 a_ = _a*_a; b_ = _a*_b; c_ = _a*_c; d_ = _a*_d;
00137 e_ = _b*_b; f_ = _b*_c; g_ = _b*_d;
00138 h_ = _c*_c; i_ = _c*_d;
00139 j_ = _d*_d;
00140 }
00141
00142
00143
00144 template <class _Normal, class _Point>
00145 void set_distance_to_plane(const _Normal& _n, const _Point& _p)
00146 {
00147 set_distance_to_plane(_n[0], _n[1], _n[2], -dot(_n,_p));
00148 }
00149
00151 void clear() { a_ = b_ = c_ = d_ = e_ = f_ = g_ = h_ = i_ = j_ = 0.0; }
00152
00154 QuadricT<Scalar>& operator+=( const QuadricT<Scalar>& _q )
00155 {
00156 a_ += _q.a_; b_ += _q.b_; c_ += _q.c_; d_ += _q.d_;
00157 e_ += _q.e_; f_ += _q.f_; g_ += _q.g_;
00158 h_ += _q.h_; i_ += _q.i_;
00159 j_ += _q.j_;
00160 return *this;
00161 }
00162
00163
00165 QuadricT<Scalar>& operator*=( Scalar _s)
00166 {
00167 a_ *= _s; b_ *= _s; c_ *= _s; d_ *= _s;
00168 e_ *= _s; f_ *= _s; g_ *= _s;
00169 h_ *= _s; i_ *= _s;
00170 j_ *= _s;
00171 return *this;
00172 }
00173
00174
00176 template <class _Vec4>
00177 _Vec4 operator*(const _Vec4& _v) const
00178 {
00179 Scalar x(_v[0]), y(_v[1]), z(_v[2]), w(_v[3]);
00180 return _Vec4(x*a_ + y*b_ + z*c_ + w*d_,
00181 x*b_ + y*e_ + z*f_ + w*g_,
00182 x*c_ + y*f_ + z*h_ + w*i_,
00183 x*d_ + y*g_ + z*i_ + w*j_);
00184 }
00185
00187 template <class _Vec>
00188 Scalar operator()(const _Vec& _v) const
00189 {
00190 return evaluate(_v, GenProg::Int2Type<_Vec::size_>());
00191 }
00192
00193 Scalar a() const { return a_; }
00194 Scalar b() const { return b_; }
00195 Scalar c() const { return c_; }
00196 Scalar d() const { return d_; }
00197 Scalar e() const { return e_; }
00198 Scalar f() const { return f_; }
00199 Scalar g() const { return g_; }
00200 Scalar h() const { return h_; }
00201 Scalar i() const { return i_; }
00202 Scalar j() const { return j_; }
00203
00204 Scalar xx() const { return a_; }
00205 Scalar xy() const { return b_; }
00206 Scalar xz() const { return c_; }
00207 Scalar xw() const { return d_; }
00208 Scalar yy() const { return e_; }
00209 Scalar yz() const { return f_; }
00210 Scalar yw() const { return g_; }
00211 Scalar zz() const { return h_; }
00212 Scalar zw() const { return i_; }
00213 Scalar ww() const { return j_; }
00214
00215 protected:
00216
00218 template <class _Vec3>
00219 Scalar evaluate(const _Vec3& _v, GenProg::Int2Type<3>) const
00220 {
00221 Scalar x(_v[0]), y(_v[1]), z(_v[2]);
00222 return a_*x*x + 2.0*b_*x*y + 2.0*c_*x*z + 2.0*d_*x
00223 + e_*y*y + 2.0*f_*y*z + 2.0*g_*y
00224 + h_*z*z + 2.0*i_*z
00225 + j_;
00226 }
00227
00229 template <class _Vec4>
00230 Scalar evaluate(const _Vec4& _v, GenProg::Int2Type<4>) const
00231 {
00232 Scalar x(_v[0]), y(_v[1]), z(_v[2]), w(_v[3]);
00233 return a_*x*x + 2.0*b_*x*y + 2.0*c_*x*z + 2.0*d_*x*w
00234 + e_*y*y + 2.0*f_*y*z + 2.0*g_*y*w
00235 + h_*z*z + 2.0*i_*z*w
00236 + j_*w*w;
00237 }
00238
00239 private:
00240
00241 Scalar a_, b_, c_, d_,
00242 e_, f_, g_,
00243 h_, i_,
00244 j_;
00245 };
00246
00247
00249 typedef QuadricT<float> Quadricf;
00250
00252 typedef QuadricT<double> Quadricd;
00253
00254
00255
00256 }
00257 }
00258
00259 #endif // OPENMESH_GEOMETRY_HH defined
00260