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
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 #ifndef SIMILARITY_H
00096 #define SIMILARITY_H
00097
00098 #include <vcg/math/quaternion.h>
00099 #include <vcg/math/matrix44.h>
00100
00101 namespace vcg {
00102
00103 template <class S,class RotationType = Quaternion<S> > class Similarity {
00104 public:
00105 Similarity() {}
00106 Similarity(const RotationType &q) { SetRotate(q); }
00107 Similarity(const Point3<S> &p) { SetTranslate(p); }
00108 Similarity(S s) { SetScale(s); }
00109 Similarity(S alpha, S beta, S gamma)
00110 {
00111 rot.FromEulerAngles(alpha, beta, gamma);
00112 tra = Point3<S>(0, 0, 0);
00113 sca = 1;
00114 }
00115
00116 Similarity operator*(const Similarity &affine) const;
00117 Similarity &operator*=(const Similarity &affine);
00118
00119
00120
00121 Similarity &SetIdentity();
00122 Similarity &SetScale(const S s);
00123 Similarity &SetTranslate(const Point3<S> &t);
00125 Similarity &SetRotate(S angle, const Point3<S> & axis);
00126 Similarity &SetRotate(const RotationType &q);
00127
00128 Matrix44<S> Matrix() const;
00129 Matrix44<S> InverseMatrix() const;
00130 void FromMatrix(const Matrix44<S> &m);
00131
00132 RotationType rot;
00133 Point3<S> tra;
00134 S sca;
00135 };
00136
00137
00138
00139 template <class S,class RotationType> Similarity<S,RotationType> &Invert(Similarity<S,RotationType> &m);
00140 template <class S,class RotationType> Similarity<S,RotationType> Inverse(const Similarity<S,RotationType> &m);
00141 template <class S,class RotationType> Point3<S> operator*(const Similarity<S,RotationType> &m, const Point3<S> &p);
00142
00143
00144 template <class S,class RotationType> Similarity<S,RotationType> Similarity<S,RotationType>::operator*(const Similarity &a) const {
00145 Similarity<S,RotationType> r;
00146 r.rot = rot * a.rot;
00147 r.sca = sca * a.sca;
00148 r.tra = (rot.Rotate(a.tra)) * sca + tra;
00149 return r;
00150 }
00151
00152 template <class S,class RotationType> Similarity<S,RotationType> &Similarity<S,RotationType>::operator*=(const Similarity &a) {
00153 rot = rot * a.rot;
00154 sca = sca * a.sca;
00155 tra = (rot.Rotate(a.tra)) * sca + tra;
00156 return *this;
00157 }
00158
00159 template <class S,class RotationType> Similarity<S,RotationType> &Similarity<S,RotationType>::SetIdentity() {
00160 rot.SetIdentity();
00161 tra = Point3<S>(0, 0, 0);
00162 sca = 1;
00163 return *this;
00164 }
00165
00166 template <class S,class RotationType> Similarity<S,RotationType> &Similarity<S,RotationType>::SetScale(const S s) {
00167 SetIdentity();
00168 sca = s;
00169 return *this;
00170 }
00171
00172 template <class S,class RotationType> Similarity<S,RotationType> &Similarity<S,RotationType>::SetTranslate(const Point3<S> &t) {
00173 SetIdentity();
00174 tra = t;
00175 return *this;
00176 }
00177
00178 template <class S,class RotationType> Similarity<S,RotationType> &Similarity<S,RotationType>::SetRotate(S angle, const Point3<S> &axis) {
00179 SetIdentity();
00180 rot.FromAxis(angle, axis);
00181 return *this;
00182 }
00183
00184 template <class S,class RotationType> Similarity<S,RotationType> &Similarity<S,RotationType>::SetRotate(const RotationType &q) {
00185 SetIdentity();
00186 rot = q;
00187 return *this;
00188 }
00189
00190
00191 template <class S,class RotationType> Matrix44<S> Similarity<S,RotationType>::Matrix() const {
00192 Matrix44<S> r;
00193 rot.ToMatrix(r);
00194 Matrix44<S> s = Matrix44<S>().SetScale(sca, sca, sca);
00195 Matrix44<S> t = Matrix44<S>().SetTranslate(tra[0], tra[1], tra[2]);
00196 return Matrix44<S>(s*r*t);
00197 }
00198
00199 template <class S,class RotationType> Matrix44<S> Similarity<S,RotationType>::InverseMatrix() const {
00200 return Inverse(Matrix());
00201 }
00202
00203
00204 template <class S,class RotationType> void Similarity<S,RotationType>::FromMatrix(const Matrix44<S> &m) {
00205
00206 S det = m.Determinant();
00207 assert(det > 0);
00208 sca = (S)pow((S)det, (S)(1/3.0));
00209 Matrix44<S> t = m*Matrix44<S>().SetScale(1/sca, 1/sca, 1/sca);
00210 tra[0] = t.ElementAt(0, 3);t[0][3] = 0.0;
00211 tra[1] = t.ElementAt(1, 3);t[1][3] = 0.0;
00212 tra[2] = t.ElementAt(2, 3);t[2][3] = 0.0;
00213 rot.FromMatrix(t);
00214
00215 Invert(t);
00216 tra = t * tra;
00217 tra/= sca;
00218 }
00219
00220
00221 template <class S,class RotationType> Similarity<S,RotationType> &Invert(Similarity<S,RotationType> &a) {
00222 a.rot.Invert();
00223 a.sca = 1/a.sca;
00224 a.tra = a.rot.Rotate(-a.tra)*a.sca;
00225 return a;
00226 }
00227
00228 template <class S,class RotationType> Similarity<S,RotationType> Inverse(const Similarity<S,RotationType> &m) {
00229 Similarity<S,RotationType> a = m;
00230 return Invert(a);
00231 }
00232
00233
00234 template <class S,class RotationType> Similarity<S,RotationType> Interpolate(const Similarity<S,RotationType> &a, const Similarity<S,RotationType> &b, const S t) {
00235 Similarity<S,RotationType> r;
00236 r.rot = Interpolate(a.rot, b.rot, t);
00237 r.tra = a.tra * t + b.tra * (1-t);
00238 r.sca = a.sca * t + b.sca * (1-t);
00239 return r;
00240 }
00241
00242 template <class S,class RotationType> Point3<S> operator*(const Similarity<S,RotationType> &m, const Point3<S> &p) {
00243 Matrix44<S> t;
00244 m.rot.ToMatrix(t);
00245 Point3<S> r = t*p;
00246 r *= m.sca;
00247 r += m.tra;
00248 return r;
00249 }
00250
00251
00252
00253
00254
00255 class Similarityf:public Similarity<float>{};
00256
00257 class Similarityd:public Similarity<double>{};
00258
00259 }
00260
00261 #endif