00001 #ifndef __VECMATH_AXISANGLE4_HPP
00002 #define __VECMATH_AXISANGLE4_HPP
00003
00004 #ifndef __LANG_MATH_HPP
00005 #include <vecmath/Math.h>
00006 #endif
00007
00008 template <class Type> class _AxisAngle4;
00009
00010 #ifndef __VECMATH_MATRIX4_HPP
00011 #include <vecmath/_Matrix4.h>
00012 #endif
00013
00014
00015 #define DEBUGAXISANGLE4(d)
00016
00017 template <class Type> class VECMATH_EXPORT _AxisAngle4 {
00018 public:
00019 static const Type EPS;
00020 Type x, y, z;
00021 Type angle;
00022
00023 _AxisAngle4<Type>() {}
00024
00025 _AxisAngle4<Type>(Type x, Type y = 0, Type z = 1, Type angle = 0) : x(x), y(y), z(z), angle(angle) {}
00026
00027 explicit _AxisAngle4<Type>(const _AxisAngle4<double>& a) {
00028 set(a);
00029 DEBUGAXISANGLE4(cout << "_AxisAngle4 constructor &double " << *this << endl);
00030 }
00031
00032 _AxisAngle4<Type>(const _AxisAngle4<float>& a) {
00033 set(a);
00034 DEBUGAXISANGLE4(cout << "_AxisAngle4 constructor &float " << *this << endl);
00035 }
00036
00037 _AxisAngle4<Type>(const _Vector3<Type>& v, Type f) {
00038 set(v, f);
00039 DEBUGAXISANGLE4(cout << "_AxisAngle4 constructor &float " << *this << endl);
00040 }
00041
00042 _AxisAngle4<Type>(const Type a[]) {
00043 set(a);
00044 DEBUGAXISANGLE4(cout << "_AxisAngle4 constructor t[4] " << *this << endl);
00045 }
00046
00047 bool epsilonEquals(const _AxisAngle4<Type>& a, double d) const {
00048 DEBUGAXISANGLE4(cout << "_AxisAngle4 epsilonEquals("
00049 << *this << " == " << a << " (" << d << "))" << endl);
00050 return (Math::epsilonEquals(x, a.x, d)
00051 && Math::epsilonEquals(y, a.y, d)
00052 && Math::epsilonEquals(z, a.z, d)
00053 && Math::epsilonEquals(angle, a.angle, d));
00054 }
00055
00056 bool equals(const _AxisAngle4<Type>& a) const {
00057 DEBUGAXISANGLE4(cout << "_AxisAngle4 equals("
00058 << *this << " == " << a << endl);
00059 return (x == a.x && y == a.y && z == a.z && angle == a.angle);
00060 }
00061
00062 void get(Type a[4]) const {
00063 a[0] = x;
00064 a[1] = y;
00065 a[2] = z;
00066 a[3] = angle;
00067 }
00068
00069
00070 double normSquared() const {
00071 return Math::sqr(x) + Math::sqr(y) + Math::sqr(z);
00072 }
00073
00074
00075 double norm() const {
00076 return sqrt(normSquared());
00077 }
00078
00079
00080 void set(Type xx = 0.0, Type yy = 0.0, Type zz = 1.0, Type a = 0.0) {
00081 x = xx;
00082 y = yy;
00083 z = zz;
00084 angle = a;
00085 }
00086
00087 void set(const _AxisAngle4<double>& a) {
00088 set(a.x, a.y, a.z, a.angle);
00089 DEBUGAXISANGLE4(cout << "_AxisAngle4 set _AxisAngle4<double> " << a << " > " << *this << endl);
00090 }
00091
00092 void set(const _AxisAngle4<float>& a) {
00093 set(a.x, a.y, a.z, a.angle);
00094 DEBUGAXISANGLE4(cout << "_AxisAngle4 set _AxisAngle4<float> " << a << " > " << *this << endl);
00095 }
00096
00097 void set(const _Matrix3<double>& m) {
00098 x = m.m21 - m.m12;
00099 y = m.m02 - m.m20;
00100 z = m.m10 - m.m01;
00101 Type d = sqrt(x * x + y * y + z * z);
00102 set(x / d, y / d, z / d,
00103 atan2(d / 2.0, ((m.m00 + m.m11 + m.m22) - 1.0) / 2.0));
00104 DEBUGAXISANGLE4(cout << "_AxisAngle4 set Matrix3d " << m << " > " << *this << endl);
00105 }
00106
00107 void set(const _Matrix3<float>& m) {
00108 x = m.m21 - m.m12;
00109 y = m.m02 - m.m20;
00110 z = m.m10 - m.m01;
00111 Type d = sqrt(x * x + y * y + z * z);
00112 set(x / d, y / d, z / d,
00113 atan2(d / 2.0, ((m.m00 + m.m11 + m.m22) - 1.0) / 2.0));
00114 DEBUGAXISANGLE4(cout << "_AxisAngle4 set Matrix3f " << m << " > " << *this << endl);
00115 }
00116
00117 void set(const _Matrix4<double>& m) {
00118 _Matrix3<double> mm;
00119 m.get(mm);
00120 set(mm);
00121 DEBUGAXISANGLE4(cout << "_AxisAngle4 set Matrix4d " << m << " > " << *this << endl);
00122 }
00123
00124 void set(const _Matrix4<float>& m) {
00125 _Matrix3<float> mm;
00126 m.get(mm);
00127 set(mm);
00128 DEBUGAXISANGLE4(cout << "_AxisAngle4 set Matrix4f " << m << " > " << *this << endl);
00129 }
00130
00131 void set(const _Quat4<double>& q) {
00132 Type d = sqrt(q.x * q.x + q.y * q.y + q.z * q.z);
00133 if(d < EPS) {
00134 x = y = z = 0.0;
00135 } else {
00136 x = q.x / d;
00137 y = q.y / d;
00138 z = q.z / d;
00139 }
00140 angle = 2.0 * atan2(d, q.w);
00141 DEBUGAXISANGLE4(cout << "_AxisAngle4 set Quat4d " << q << " > " << *this << endl);
00142 }
00143
00144 void set(const _Quat4<float>& q) {
00145 Type d = sqrt(q.x * q.x + q.y * q.y + q.z * q.z);
00146 if (d < EPS) {
00147 x = y = z = 0.0;
00148 } else {
00149 x = q.x / d;
00150 y = q.y / d;
00151 z = q.z / d;
00152 }
00153 angle = 2.0 * atan2(d, q.w);
00154 DEBUGAXISANGLE4(cout << "_AxisAngle4 set Quat4f " << q << " > " << *this << endl);
00155 }
00156
00157 void set(const _Vector3<Type>& v, Type f) {
00158 set(v.x, v.y, v.z, f);
00159 DEBUGAXISANGLE4(cout << "_AxisAngle4 set _AxisAngle4<float> " << a << " > " << *this << endl);
00160 }
00161
00162 void set(Type a[4]) {
00163 set(a[0], a[1], a[2], a[3]);
00164 }
00165 };
00166
00167 #endif