#ifndef SIMILAR_H #define SIMILAR_H #include #include namespace vcg { template class Similar { public: Similar() {} Similar operator*(const Similar &affine) const; Similar &operator*=(const Similar &affine); Point3 operator*(const Point3 &p) const; void SetIdentity(); void SetScale(const S s); Similar &SetTranslate(const Point3 &t); ///use radiants for angle. void SetRotate(S angle, const Point3 & axis); Matrix44 Matrix() const; Quaternion rot; Point3 tra; S sca; }; template Similar Similar::operator*(const Similar &a) const { Similar r; r.rot = rot * a.rot; r.sca = sca * a.sca; r.tra = (rot.Rotate(a.tra)) * sca + tra; return r; } template Similar &Similar::operator*=(const Similar &a) { rot = rot * a.rot; sca = sca * a.sca; tra = (rot.Rotate(a.tra)) * sca + tra; return *this; } template Point3 Similar::operator*(const Point3 &p) const { Point3 r = rot.Rotate(p); r *= sca; r += tra; return r; } template void Similar::SetIdentity() { rot.FromAxis(0, Point3(1, 0, 0)); tra = Point3(0, 0, 0); sca = 1; } template void Similar::SetScale(const S s) { SetIdentity(); sca = s; } template Similar &Similar::SetTranslate(const Point3 &t) { SetIdentity(); tra = t; return *this; } template void Similar::SetRotate(S angle, const Point3 &axis) { SetIdentity(); rot.FromAxis(angle, axis); } template Matrix44 Similar::Matrix() const { Matrix44 r; rot.ToMatrix(r); r *= Matrix44().SetScale(sca, sca, sca); Matrix44 t = Matrix44().SetTranslate(tra[0], tra[1], tra[2]); r *= t; return r; } template Similar &invert(Similar &a) { //WARNING:: TEST THIS!!! a.rot.Invert(); a.sca = 1/a.sca; a.tra = a.rot.Rotate(-a.tra)*a.sca; return a; } template Similar interpolate(const Similar &a, const Similar &b, const S t) { Similar r; r.rot = interpolate(a.rot, b.rot, t); r.tra = t * a.tra + (1-t) * b.tra; r.sca = t * a.sca + (1-t) * b.sca; return r; } typedef Similar Similarf; typedef SimilarSimilard; } //namespace #endif