/* * Copyright (C) 2009 * Robert Bosch LLC * Research and Technology Center North America * Palo Alto, California * * All rights reserved. * *------------------------------------------------------------------------------ * project ....: Autonomous Technologies * file .......: rtcTransform2D.h * authors ....: Benjamin Pitzer * organization: Robert Bosch LLC * creation ...: 02/29/2008 * modified ...: $Date: 2009-01-21 18:19:16 -0800 (Wed, 21 Jan 2009) $ * changed by .: $Author: benjaminpitzer $ * revision ...: $Revision: 14 $ */ #ifndef RTC_TRANSFORM2D_H #define RTC_TRANSFORM2D_H //== INCLUDES ================================================================== #include "rtcMath.h" #include "rtcTransform2D.h" #include "rtcRotation2D.h" #include "rtcVec.h" #include "rtcVec2.h" #include "rtcVec3.h" #include "rtcSMat3.h" //== NAMESPACES ================================================================ namespace rtc { //== FORWARD DECLARATIONS ====================================================== template class Transform2D; // Rigid tranform matrix (3x3) template class Rotation2D; // Rotation2D matrix (2x2) template class Vec; // M-d vector template class Vec2; // 2-d vector /** * The Tranform2D Matrix Class * * Defines transformation class for rigid body rotations and translations * that knows how to construct itself from rotation matrices. */ template class Transform2D: public SMat3 { public: // Constructors Transform2D(); Transform2D(const Mat& m); Transform2D(const SMat3& m); Transform2D(const Rotation2D& rot); Transform2D(const Vec2& trans); Transform2D(const Rotation2D& rot, const Vec2& trans); Transform2D(const T& dtheta, const T& dx, const T& dy); // Accessors void get( Rotation2D& rot, Vec2& trans) const; void get(T& theta, T& dx, T& dy) const; Vec2 getTrans( ) const; void getTrans(T& dx, T& dy) const; Rotation2D getRot( ) const; void getRot(T& dtheta) const; // Mutators void set(const Rotation2D& rot); void set(const Vec2& trans); void set(const Rotation2D& rot, const Vec2& trans); void set(const T& dtheta, const T& dx, const T& dy); void rotate(T theta); void translate(T x, T y); void translate(const Vec2& t); // Helper for applying tranform to points: Transform2D * Vec Vec operator * (const Vec2& v) const; void apply(Vec2& v) const; Vec2 apply(const Vec2& v) const; //Special inverse that uses the fact this is a rigid transform matrix Transform2D inverted() const; Transform2D relativeTo(const Transform2D& referenceFrame) const; // Inherited from parent using SMat::set; using SMat::x; using SMat::operator*; }; // Declare a few common typdefs typedef Transform2D Transform2Df; typedef Transform2D Transform2Dd; //============================================================================== // Transform2D //============================================================================== /** Ctor that initializes to no rotation and no translation. */ template inline Transform2D::Transform2D() { set(Rotation2D(),Vec(T(0))); } /** Ctor that initializes to the given rotation and no translation. */ template inline Transform2D::Transform2D(const Rotation2D& r){ set(r,Vec2(T(0))); } /** Ctor that initializes to no rotation and the given translation. */ template inline Transform2D::Transform2D(const Vec2& t){ set(Rotation2D(),t); } /** Ctor that starts with the given rotation and translation. */ template inline Transform2D::Transform2D(const Rotation2D& rot, const Vec2& trans){ set(rot,trans); } /** Ctor that initializes from SMat. */ template inline Transform2D::Transform2D(const SMat3& m) : SMat3(m) {} /** Ctor that initializes from dx, dy, dtheta. */ template inline Transform2D::Transform2D(const T& dtheta, const T& dx, const T& dy){ set(dtheta,dx,dy); } /** Ctor that initializes from Mat. */ template inline Transform2D::Transform2D(const Mat& m) : SMat3(m) {} // Accessors /** Get the rotation and translation */ template inline void Transform2D::get(Rotation2D& r, Vec2& t) const { r=Rotation2D(x[0],x[1], x[3],x[4]); t=Vec2(x[2],x[5]); } /** Get the rotation and translation */ template inline void Transform2D::get(T& theta, T& dx, T& dy) const { getTrans(dx,dy); getRot(theta); } /** Get the translation */ template inline Vec2 Transform2D::getTrans() const { return Vec2(x[2],x[5]); } /** Get the translation */ template inline void Transform2D::getTrans(T& dx, T& dy) const { dx=x[2]; dy=x[5]; } /** Get the rotation */ template inline Rotation2D Transform2D::getRot() const { return Rotation2D(x[0],x[1], x[3],x[4]); } /** Get the rotation */ template inline void Transform2D::getRot(T& dtheta) const { dtheta = atan2(x[3],x[0]); } // Mutators /** Set only the rotation portion of the Transform2D. */ template inline void Transform2D::set(const Rotation2D& r) { for (int i=0;i<2;i++) for (int j=0;j<2;j++) (*this)(i,j) = r(i,j); x[6] = 0; x[7] = 0; x[8] = 1; } /** Set only the translation portion of the Transform2D. */ template inline void Transform2D::set(const Vec2& t) { x[2] = t(0); x[5] = t(1); x[6] = 0; x[7] = 0; x[8] = 1; } /** Set to the given rotation and translation */ template inline void Transform2D::set(const Rotation2D& r, const Vec2& t) { set(r); set(t); } /** Set to the given rotation dtheta and translation dx/dy */ template inline void Transform2D::set(const T& dtheta, const T& dx, const T& dy) { set(Rotation2D(dtheta),Vec2(dx,dy)); } /** Apply a rotation to the transform */ template inline void Transform2D::rotate(T theta) { Transform2D temp; T ctheta = cos(theta), stheta = sin(theta); temp(0,0) = ctheta; temp(0,1) = -stheta; temp(1,0) = stheta; temp(1,1) = ctheta; leftMultiply(temp); } /** Apply a translation to the transform */ template inline void Transform2D::translate(T _x, T _y) { x[2] += _x; x[5] += _y; } /** Apply a translation to the transform */ template inline void Transform2D::translate(const Vec2& t) { translate(t[0],t[1]); } /** Helper function that allows a tranform to operate on a point. */ template inline Vec Transform2D::operator * (const Vec2& v) const { return (*this)*Vec3(v(0),v(1),T(1.0)); } /** Helper function that allows a transform to operate on a point. */ template inline void Transform2D::apply(Vec2& v) const { Vec v1 = (*this)*v; v.set(v1[0],v1[1]); } /** Helper function that allows a transform to operate on a point. */ template inline Vec2 Transform2D::apply(const Vec2& v) const { Vec v1 = (*this)*v; return(Vec2(v1[0],v1[1])); } /** Fast inverse of a rigid transform matrix. * M = [ r t] * [ 0 1] * * inv(M) = [ r' -r'*t] * [ 0 1] */ template inline Transform2D Transform2D::inverted() const{ Rotation2D r(x[0],x[3], x[1],x[4]); Vec2 t(-x[2],-x[5]); return Transform2D(r,r*t); } /** Converts to a new coordinate frame @return this transform relative to the provided reference frame */ template inline Transform2D Transform2D::relativeTo(const Transform2D& referenceFrame) const { return SMat3(referenceFrame.inverted()*(*this)); } //============================================================================== } // NAMESPACE rtc //============================================================================== #endif // RTC_TRANSFORM2D_H //==============================================================================