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 template <class S,class RotationType> Similarity<S,RotationType> &Invert(Similarity<S,RotationType> &m);
00138 template <class S,class RotationType> Similarity<S,RotationType> Inverse(const Similarity<S,RotationType> &m);
00139 template <class S,class RotationType> Point3<S> operator*(const Similarity<S,RotationType> &m, const Point3<S> &p);
00140
00141
00142 template <class S,class RotationType> Similarity<S,RotationType> Similarity<S,RotationType>::operator*(const Similarity &a) const {
00143 Similarity<S,RotationType> r;
00144 r.rot = rot * a.rot;
00145 r.sca = sca * a.sca;
00146 r.tra = (rot.Rotate(a.tra)) * sca + tra;
00147 return r;
00148 }
00149
00150 template <class S,class RotationType> Similarity<S,RotationType> &Similarity<S,RotationType>::operator*=(const Similarity &a) {
00151 rot = rot * a.rot;
00152 sca = sca * a.sca;
00153 tra = (rot.Rotate(a.tra)) * sca + tra;
00154 return *this;
00155 }
00156
00157 template <class S,class RotationType> Similarity<S,RotationType> &Similarity<S,RotationType>::SetIdentity() {
00158 rot.SetIdentity();
00159 tra = Point3<S>(0, 0, 0);
00160 sca = 1;
00161 return *this;
00162 }
00163
00164 template <class S,class RotationType> Similarity<S,RotationType> &Similarity<S,RotationType>::SetScale(const S s) {
00165 SetIdentity();
00166 sca = s;
00167 return *this;
00168 }
00169
00170 template <class S,class RotationType> Similarity<S,RotationType> &Similarity<S,RotationType>::SetTranslate(const Point3<S> &t) {
00171 SetIdentity();
00172 tra = t;
00173 return *this;
00174 }
00175
00176 template <class S,class RotationType> Similarity<S,RotationType> &Similarity<S,RotationType>::SetRotate(S angle, const Point3<S> &axis) {
00177 SetIdentity();
00178 rot.FromAxis(angle, axis);
00179 return *this;
00180 }
00181
00182 template <class S,class RotationType> Similarity<S,RotationType> &Similarity<S,RotationType>::SetRotate(const RotationType &q) {
00183 SetIdentity();
00184 rot = q;
00185 return *this;
00186 }
00187
00188
00189 template <class S,class RotationType> Matrix44<S> Similarity<S,RotationType>::Matrix() const {
00190 Matrix44<S> r;
00191 rot.ToMatrix(r);
00192 Matrix44<S> s = Matrix44<S>().SetScale(sca, sca, sca);
00193 Matrix44<S> t = Matrix44<S>().SetTranslate(tra[0], tra[1], tra[2]);
00194 return Matrix44<S>(s*r*t);
00195 }
00196
00197 template <class S,class RotationType> Matrix44<S> Similarity<S,RotationType>::InverseMatrix() const {
00198 return Inverse(Matrix());
00199 }
00200
00201
00202 template <class S,class RotationType> void Similarity<S,RotationType>::FromMatrix(const Matrix44<S> &m) {
00203
00204 S det = m.Determinant();
00205 assert(det > 0);
00206 sca = (S)pow((S)det, (S)(1/3.0));
00207 Matrix44<S> t = m*Matrix44<S>().SetScale(1/sca, 1/sca, 1/sca);
00208 tra[0] = t.ElementAt(0, 3);t[0][3] = 0.0;
00209 tra[1] = t.ElementAt(1, 3);t[1][3] = 0.0;
00210 tra[2] = t.ElementAt(2, 3);t[2][3] = 0.0;
00211 rot.FromMatrix(t);
00212
00213 Invert(t);
00214 tra = t * tra;
00215 tra/= sca;
00216 }
00217
00218
00219 template <class S,class RotationType> Similarity<S,RotationType> &Invert(Similarity<S,RotationType> &a) {
00220 a.rot.Invert();
00221 a.sca = 1/a.sca;
00222 a.tra = a.rot.Rotate(-a.tra)*a.sca;
00223 return a;
00224 }
00225
00226 template <class S,class RotationType> Similarity<S,RotationType> Inverse(const Similarity<S,RotationType> &m) {
00227 Similarity<S,RotationType> a = m;
00228 return Invert(a);
00229 }
00230
00231
00232 template <class S,class RotationType> Similarity<S,RotationType> Interpolate(const Similarity<S,RotationType> &a, const Similarity<S,RotationType> &b, const S t) {
00233 Similarity<S,RotationType> r;
00234 r.rot = interpolate(a.rot, b.rot, t);
00235 r.tra = t * a.tra + (1-t) * b.tra;
00236 r.sca = t * a.sca + (1-t) * b.sca;
00237 return r;
00238 }
00239
00240 template <class S,class RotationType> Point3<S> operator*(const Similarity<S,RotationType> &m, const Point3<S> &p) {
00241 Matrix44<S> t;
00242 m.rot.ToMatrix(t);
00243 Point3<S> r = t*p;
00244 r *= m.sca;
00245 r += m.tra;
00246 return r;
00247 }
00248
00249
00250
00251
00252 class Similarityf:public Similarity<float>{};
00253
00254 class Similarityd:public Similarity<double>{};
00255
00256 }
00257
00258 #endif