EMAN2
Public Member Functions | Static Public Member Functions | Private Attributes
EMAN::Quaternion Class Reference

Quaternion is used in Rotation and Transformation to replace Euler angles. More...

#include <quaternion.h>

List of all members.

Public Member Functions

 Quaternion ()
 Quaternion (float e0, float e1, float e2, float e3)
 Quaternion (float radians, const Vec3f &axis)
 Quaternion (const Vec3f &axis, float radians)
 Quaternion (const vector< float > &matrix3)
 ~Quaternion ()
float norm () const
Quaternion conj () const
float abs () const
void normalize ()
Quaternioninverse ()
Quaternion create_inverse () const
Vec3f rotate (const Vec3f &v) const
float to_angle () const
Vec3f to_axis () const
vector< float > to_matrix3 () const
float real () const
Vec3f unreal () const
vector< float > as_list () const
Quaternionoperator+= (const Quaternion &q)
Quaternionoperator-= (const Quaternion &q)
Quaternionoperator*= (const Quaternion &q)
Quaternionoperator*= (float s)
Quaternionoperator/= (const Quaternion &q)
Quaternionoperator/= (float s)

Static Public Member Functions

static Quaternion interpolate (const Quaternion &from, const Quaternion &to, float percent)

Private Attributes

float e0
float e1
float e2
float e3

Detailed Description

Quaternion is used in Rotation and Transformation to replace Euler angles.

Quaternions extend the concept of rotation in three dimensions to rotation in four dimensions. This avoids the problem of "gimbal-lock" and allows for the implementation of smooth and continuous rotation.

Euler angles have the disadvantage of being susceptible to "Gimbal lock" where attempts to rotate an object fail due to the order in which the rotations are performed.

Quaternions are a solution to this problem. Instead of rotating an object through a series of successive rotations, a quaternion allows the programmer to rotate an object through a single arbitary rotation axis.

Because the rotation axis is specifed as a unit direction vector, it may be calculated through vector mathematics or from spherical coordinates ie (longitude/latitude).

Quaternions offer another advantage in that they be interpolated. This allows for smooth and predictable rotation effects.

Definition at line 65 of file quaternion.h.


Constructor & Destructor Documentation

Quaternion::Quaternion ( )

Definition at line 40 of file quaternion.cpp.

Referenced by conj().

:       e0(0), e1(0), e2(0), e3(0)
{
}
Quaternion::Quaternion ( float  e0,
float  e1,
float  e2,
float  e3 
)

Definition at line 71 of file quaternion.cpp.

:e0(ee0), e1(ee1), e2(ee2), e3(ee3)
{
        //normalize();
}
Quaternion::Quaternion ( float  radians,
const Vec3f axis 
)

Definition at line 45 of file quaternion.cpp.

References e0, e1, e2, e3, and q.

{
        Vec3f q = axis;
        //normalize();

        q *= sin(radians / 2.0f);
        e0 = cos(radians / 2.0f);

        e1 = q[0];
        e2 = q[1];
        e3 = q[2];
}
Quaternion::Quaternion ( const Vec3f axis,
float  radians 
)

Definition at line 58 of file quaternion.cpp.

References e0, e1, e2, e3, and q.

{
        Vec3f q = axis;
        //normalize();

        q *= sin(radians / 2.0f);
        e0 = cos(radians / 2.0f);

        e1 = q[0];
        e2 = q[1];
        e3 = q[2];
}
Quaternion::Quaternion ( const vector< float > &  matrix3) [explicit]

Definition at line 77 of file quaternion.cpp.

References e0, e1, e2, e3, and sqrt().

{
        int i = 0;

        if (m[0] > m[4]) {
                if (m[0] > m[8]) {
                        i = 0;
                }
                else {
                        i = 2;
                }
        }
        else {
                if (m[4] > m[8]) {
                        i = 1;
                }
                else {
                        i = 2;
                }
        }

        if (m[0] + m[4] + m[8] > m[i*3+i]) {
                e0 = (float) (sqrt(m[0] + m[4] + m[8] + 1) / 2.0);
                e1 = (float) ((m[5] - m[7]) / (4 * e0));
                e2 = (float) ((m[6] - m[2]) / (4 * e0));
                e3 = (float) ((m[1] - m[3]) / (4 * e0));
        }
        else {
                float quat[3];
                int j = (i + 1) % 3;
                int k = (i + 2) % 3;

                quat[i] = (float) (sqrt(m[i*3+i] - m[j*3+j] - m[k*3+k] + 1) / 2.0);
                quat[j] = (float) ((m[i*3+j] + m[j*3+i]) / (4 * quat[i]));
                quat[k] = (float) ((m[i*3+k] + m[k*3+i]) / (4 * quat[i]));

                e0 = (float) ((m[j*3+k] - m[k*3+j]) / (4 * quat[i]));
                e1 = quat[0];
                e2 = quat[1];
                e3 = quat[2];
        }

        //normalize();
}
EMAN::Quaternion::~Quaternion ( ) [inline]

Definition at line 74 of file quaternion.h.

                {
                }

Member Function Documentation

float EMAN::Quaternion::abs ( ) const [inline]

Definition at line 88 of file quaternion.h.

References norm(), and sqrt().

                {
                        return sqrt(norm());
                }
vector< float > Quaternion::as_list ( ) const

Definition at line 222 of file quaternion.cpp.

References e0, e1, e2, e3, and v.

Referenced by EMAN::operator==().

{
        vector < float >v(4);
        v[0] = e0;
        v[1] = e1;
        v[2] = e2;
        v[3] = e3;

        return v;
}
Quaternion EMAN::Quaternion::conj ( ) const [inline]

Definition at line 83 of file quaternion.h.

References Quaternion().

                {
                        return (Quaternion(e0, -e1, -e2, -e3));
                }
Quaternion Quaternion::create_inverse ( ) const

Definition at line 142 of file quaternion.cpp.

References inverse(), and q.

{
        Quaternion q = *this;
        return q.inverse();
}
Quaternion Quaternion::interpolate ( const Quaternion from,
const Quaternion to,
float  percent 
) [static]

Definition at line 376 of file quaternion.cpp.

References e0, e1, e2, e3, q, and t.

{
        const double epsilon = 0.00001;
        double cosom = from.e1 * to.e1 + from.e2 * to.e2 + from.e3 * to.e3 + from.e0 * to.e0;

        Quaternion q;
        if (cosom < 0) {
                cosom = -cosom;
                q = q - to;
        }
        else {
                q = to;
        }

        double scale0 = 1 - t;
        double scale1 = t;

        if ((1 - cosom) > epsilon) {
                double omega = acos(cosom);
                double sinom = sin(omega);
                scale0 = sin((1 - t) * omega) / sinom;
                scale1 = sin(t * omega) / sinom;
        }

        float scale0f = (float) scale0;
        float scale1f = (float) scale1;
        
        return (scale0f * from + scale1f * q);
}
Quaternion & Quaternion::inverse ( )

Definition at line 132 of file quaternion.cpp.

References e0, e1, e2, e3, and norm().

Referenced by create_inverse().

{
        float f = 1.0f / norm();
        e0 *= f;
        e1 *= -f;
        e2 *= -f;
        e3 *= -f;
        return (*this);
}
float EMAN::Quaternion::norm ( ) const [inline]

Definition at line 78 of file quaternion.h.

Referenced by abs(), inverse(), normalize(), and operator/=().

                {
                        return (e0 * e0 + e1 * e1 + e2 * e2 + e3 * e3);
                }
void Quaternion::normalize ( )

Definition at line 123 of file quaternion.cpp.

References dist(), e0, e1, e2, e3, norm(), and sqrt().

{
        float dist = 1.0f / sqrt(norm());
        e0 *= dist;
        e1 *= dist;
        e2 *= dist;
        e3 *= dist;
}
Quaternion & Quaternion::operator*= ( const Quaternion q)

Definition at line 251 of file quaternion.cpp.

References b, e0, e1, e2, and e3.

{
        float a = e0 * q.e0 - e1 * q.e1 - e2 * q.e2 - e3 * q.e3;
        float b = e0 * q.e1 + e1 * q.e0 + e2 * q.e3 - e3 * q.e2;
        float c = e0 * q.e2 - e1 * q.e3 + e2 * q.e0 + e3 * q.e1;
        float d = e0 * q.e3 + e1 * q.e2 - e2 * q.e1 + e3 * q.e0;

        e0 = a;
        e1 = b;
        e2 = c;
        e3 = d;


        // normalize();

        return (*this);
}
Quaternion & Quaternion::operator*= ( float  s)

Definition at line 269 of file quaternion.cpp.

References e0, e1, e2, and e3.

{
        e0 *= s;
        e1 *= s;
        e2 *= s;
        e3 *= s;
        return (*this);
}
Quaternion & Quaternion::operator+= ( const Quaternion q)

Definition at line 233 of file quaternion.cpp.

References e0, e1, e2, and e3.

{
        e0 += q.e0;
        e1 += q.e1;
        e2 += q.e2;
        e3 += q.e3;
        return *this;
}
Quaternion & Quaternion::operator-= ( const Quaternion q)

Definition at line 242 of file quaternion.cpp.

References e0, e1, e2, and e3.

{
        e0 -= q.e0;
        e1 -= q.e1;
        e2 -= q.e2;
        e3 -= q.e3;
        return *this;
}
Quaternion & Quaternion::operator/= ( const Quaternion q)

Definition at line 278 of file quaternion.cpp.

References b, e0, e1, e2, e3, and norm().

{
        float qn = q.norm();

        float a = (+e0 * q.e0 + e1 * q.e1 + e2 * q.e2 + e3 * q.e3) / qn;
        float b = (-e0 * q.e1 + e1 * q.e0 - e2 * q.e3 + e3 * q.e2) / qn;
        float c = (-e0 * q.e2 + e1 * q.e3 + e2 * q.e0 - e3 * q.e1) / qn;
        float d = (-e0 * q.e3 - e1 * q.e2 + e2 * q.e1 + e3 * q.e0) / qn;

        e0 = a;
        e1 = b;
        e2 = c;
        e3 = d;

        return (*this);
}
Quaternion & Quaternion::operator/= ( float  s)

Definition at line 295 of file quaternion.cpp.

References e0, e1, e2, and e3.

{
        if (s != 0) {
                e0 /= s;
                e1 /= s;
                e2 /= s;
                e3 /= s;
        }

        return (*this);
}
float Quaternion::real ( ) const

Definition at line 212 of file quaternion.cpp.

References e0.

{
        return e0;
}
Vec3f Quaternion::rotate ( const Vec3f v) const

Definition at line 149 of file quaternion.cpp.

References EMAN::Vec3< Type >::cross(), e0, e1, e2, and e3.

{
        Vec3f i(e1, e2, e3);
        Vec3f v1 = i.cross(v) * (2 * e0);
        Vec3f v2 = v1.cross(i) * (float) 2;
        Vec3f rotated = v + v1 - v2;

        return rotated;
}
float Quaternion::to_angle ( ) const

Definition at line 160 of file quaternion.cpp.

References e0, e1, e2, e3, EMAN::Vec3< Type >::length(), and q.

{
        Vec3f q(e1, e2, e3);
        float len = q.length();
        float radians = 0;

        if (len > 0.00001f) {
                radians = 2.0f * acos(e0);
        }
        else {
                radians = 0;
        }
        return radians;
}
Vec3f Quaternion::to_axis ( ) const

Definition at line 175 of file quaternion.cpp.

References e1, e2, e3, EMAN::Vec3< Type >::length(), q, and EMAN::Vec3< Type >::set_value().

{
        Vec3f q(e1, e2, e3);
        float len = q.length();
        Vec3f axis;

        if (len > 0.00001f) {
                axis = q * ((float) (1.0f / len));
        }
        else {
                axis.set_value(0.0f, 0.0f, 1.0f);
        }
        return axis;
}
vector< float > Quaternion::to_matrix3 ( ) const

Definition at line 191 of file quaternion.cpp.

References e0, e1, e2, and e3.

{
        vector < float >m(9);

        m[0] = e0 * e0 + e1 * e1 - e2 * e2 - e3 * e3;
        m[1] = 2.0f * (e1 * e2 + e0 * e3);
        m[2] = 2.0f * (e1 * e3 - e0 * e2);

        m[3] = 2.0f * (e1 * e2 - e0 * e3);
        m[4] = e0 * e0 + e1 * e1 + e2 * e2 - e3 * e3;
        m[5] = 2.0f * (e2 * e3 + e0 * e1);

        m[6] = 2.0f * (e1 * e3 + e0 * e2);
        m[7] = 2.0f * (e2 * e3 - e0 * e1);
        m[8] = e0 * e0 - e1 * e1 - e2 * e2 + e3 * e3;

        return m;
}
Vec3f Quaternion::unreal ( ) const

Definition at line 217 of file quaternion.cpp.

References e1, e2, and e3.

{
        return Vec3f(e1, e2, e3);
}

Member Data Documentation

float EMAN::Quaternion::e0 [private]
float EMAN::Quaternion::e1 [private]
float EMAN::Quaternion::e2 [private]
float EMAN::Quaternion::e3 [private]

The documentation for this class was generated from the following files: