/** * @file AxisAngle.hpp * * @author James Goppert */ #pragma once #include "math.hpp" namespace matrix { template class Dcm; template class Euler; template class AxisAngle; /** * AxisAngle class * * The rotation between two coordinate frames is * described by this class. */ template class AxisAngle : public Vector { public: typedef Matrix Matrix31; /** * Constructor from array * * @param data_ array */ explicit AxisAngle(const Type data_[3]) : Vector(data_) { } /** * Standard constructor */ AxisAngle() = default; /** * Constructor from Matrix31 * * @param other Matrix31 to copy */ AxisAngle(const Matrix31 &other) : Vector(other) { } /** * Constructor from quaternion * * This sets the instance from a quaternion representing coordinate transformation from * frame 2 to frame 1 where the rotation from frame 1 to frame 2 is described * by a 3-2-1 intrinsic Tait-Bryan rotation sequence. * * @param q quaternion */ AxisAngle(const Quaternion &q) { AxisAngle &v = *this; Type ang = Type(2) * acos(q(0)); Type mag = sin(ang/2.0f); if (fabs(mag) > 0) { v(0) = ang*q(1)/mag; v(1) = ang*q(2)/mag; v(2) = ang*q(3)/mag; } else { v(0) = 0; v(1) = 0; v(2) = 0; } } /** * Constructor from dcm * * Instance is initialized from a dcm representing coordinate transformation * from frame 2 to frame 1. * * @param dcm dcm to set quaternion to */ AxisAngle(const Dcm &dcm) { AxisAngle &v = *this; v = Quaternion(dcm); } /** * Constructor from euler angles * * This sets the instance to a quaternion representing coordinate transformation from * frame 2 to frame 1 where the rotation from frame 1 to frame 2 is described * by a 3-2-1 intrinsic Tait-Bryan rotation sequence. * * @param euler euler angle instance */ AxisAngle(const Euler &euler) { AxisAngle &v = *this; v = Quaternion(euler); } /** * Constructor from 3 axis angle values (unit vector * angle) * * @param x r_x*angle * @param y r_y*angle * @param z r_z*angle */ AxisAngle(Type x, Type y, Type z) { AxisAngle &v = *this; v(0) = x; v(1) = y; v(2) = z; } /** * Constructor from axis and angle * * @param axis An axis of rotation, normalized if not unit length * @param angle The amount to rotate */ AxisAngle(const Matrix31 & axis_, Type angle_) { AxisAngle &v = *this; // make sure axis is a unit vector Vector a = axis_; a = a.unit(); v(0) = a(0)*angle_; v(1) = a(1)*angle_; v(2) = a(2)*angle_; } Vector axis() { if (Vector::norm() > 0) { return Vector::unit(); } else { return Vector3(1, 0, 0); } } Type angle() { return Vector::norm(); } }; typedef AxisAngle AxisAnglef; } // namespace matrix /* vim: set et fenc=utf-8 ff=unix sts=0 sw=4 ts=4 : */