26 #include "Quaternion.hh"
33 template<
class QUAT_TYPE>
37 template<
class QUAT_TYPE>
42 template<
class QUAT_TYPE>
48 template<
class QUAT_TYPE>
50 QUAT_TYPE k, QUAT_TYPE r)
51 :
Vector4<QUAT_TYPE>(i, j, k, r)
54 template<
class QUAT_TYPE>
59 res[0][0] = (*this)[3];
60 res[0][1] = -(*this)[2];
61 res[0][2] = (*this)[1];
62 res[0][3] = (*this)[0];
64 res[1][0] = (*this)[2];
65 res[1][1] = (*this)[3];
66 res[1][2] = -(*this)[0];
67 res[1][3] = (*this)[1];
69 res[2][0] = -(*this)[1];
70 res[2][1] = (*this)[0];
71 res[2][2] = (*this)[3];
72 res[2][3] = (*this)[2];
74 res[3][0] = -(*this)[0];
75 res[3][1] = -(*this)[1];
76 res[3][2] = -(*this)[2];
77 res[3][3] = (*this)[3];
82 template<
class QUAT_TYPE>
87 res[0][0] = (*this)[3];
88 res[0][1] = (*this)[2];
89 res[0][2] = -(*this)[1];
90 res[0][3] = (*this)[0];
92 res[1][0] = -(*this)[2];
93 res[1][1] = (*this)[3];
94 res[1][2] = (*this)[0];
95 res[1][3] = (*this)[1];
97 res[2][0] = (*this)[1];
98 res[2][1] = -(*this)[0];
99 res[2][2] = (*this)[3];
100 res[2][3] = (*this)[2];
102 res[3][0] = -(*this)[0];
103 res[3][1] = -(*this)[1];
104 res[3][2] = -(*this)[2];
105 res[3][3] = (*this)[3];
110 template<
class QUAT_TYPE>
112 QUAT_TYPE& angle)
const
117 QUAT_TYPE len = QUAT_TYPE(q.
NormL2());
119 if(len > QUATERNION_EPSILON) {
124 angle = QUAT_TYPE(2.0 * acos((*
this)[3]));
134 template<
class QUAT_TYPE>
138 QUAT_TYPE len = QUAT_TYPE(r.
NormL2());
139 if (len > QUATERNION_EPSILON)
145 template<
class QUAT_TYPE>
148 const QUAT_TYPE angle = QUAT_TYPE(2.0 * acos((*
this)[3]));
149 if (isnan(angle) && fabs(fabs((*
this)[3]) - 1.0) < QUATERNION_EPSILON)
155 template<
class QUAT_TYPE>
158 BIASERR(
"Quaternion<QUAT_TYPE>::GetRotationMatrix() is deprecated, because"
159 <<
" it returned a TRANSPOSED matrix. To prevent code duplication "
160 <<
" this function will be removed in the future. Check your code."
161 <<
"Use RMatrixBase::SetFromQuaternion instead.");
170 if ((scale < 1e-7) && (scale > -1e-7)) {
173 }
else if ((res[3] > 0.999999) || (res[3] < -0.999999)) {
178 QUAT_TYPE temp1 = sin(scale * acos(res[3]))/sin(acos(res[3]));
179 QUAT_TYPE res3 = res[3];
181 res[3] += QUAT_TYPE(sin((1.0-scale) * acos(res3))/sin(acos(res3)));
186 template<
class QUAT_TYPE>
190 BIASASSERT(t >= 0.0 && t <= 1.0);
198 }
else if (1.0-t < 1e-7) {
205 const QUAT_TYPE a = (QUAT_TYPE)1.0 - t;
206 const QUAT_TYPE b = (cosPhi < 0 ? -t : t);
207 res[0] = a*p[0] + b*q[0];
208 res[1] = a*p[1] + b*q[1];
209 res[2] = a*p[2] + b*q[2];
210 res[3] = a*p[3] + b*q[3];
215 template<
class QUAT_TYPE>
219 BIASASSERT(t >= 0.0 && t <= 1.0);
227 }
else if (1.0-t < 1e-7) {
239 if (cosPhi > 0.9999 || cosPhi < -0.9999) {
241 a = (QUAT_TYPE)1.0 - t;
242 b = (cosPhi < 0 ? -t : t);
245 const QUAT_TYPE phi = acos(cosPhi < 0 ? -cosPhi : cosPhi);
246 const QUAT_TYPE sinPhi = sin(phi);
247 a = sin(((QUAT_TYPE)1.0 - t) * phi) / sinPhi;
248 b = sin(t * phi) / sinPhi;
249 if (cosPhi < 0) b = -b;
251 res[0] = a*p[0] + b*q[0];
252 res[1] = a*p[1] + b*q[1];
253 res[2] = a*p[2] + b*q[2];
254 res[3] = a*p[3] + b*q[3];
259 template<
class QUAT_TYPE>
261 SetXYZ(QUAT_TYPE radX, QUAT_TYPE radY, QUAT_TYPE radZ)
279 template<
class QUAT_TYPE>
281 SetZYX(QUAT_TYPE radX, QUAT_TYPE radY, QUAT_TYPE radZ)
299 template<
class QUAT_TYPE>
303 memcpy((
void *)this->data_, (
void *)vec.
GetData(),
304 VECTOR4SIZE*
sizeof(QUAT_TYPE));
308 template<
class QUAT_TYPE>
void
326 q0[3] = q1[3] = QUAT_TYPE(0.5) * (q0[3] + q1[3]);
329 QUAT_TYPE q0norm = q0[0]*q0[0] + q0[1]*q0[1] + q0[2]*q0[2];
330 QUAT_TYPE q1norm = q1[0]*q1[0] + q1[1]*q1[1] + q1[2]*q1[2];
331 if (q0norm > QUAT_TYPE(1e-8) && q1norm > QUAT_TYPE(1e-8)) {
332 QUAT_TYPE qscale0 = (QUAT_TYPE)sqrt(
double((1-q0[3]*q0[3])/q0norm));
333 QUAT_TYPE qscale1 = (QUAT_TYPE)sqrt(
double((1-q1[3]*q1[3])/q1norm));
334 for (
register int l = 0; l < 3; l++) {
343 template<
class QUAT_TYPE>
void
349 if (quats.empty())
return;
352 const int n = quats.
size();
353 for (
int i = 0; i < n; i++)
354 quats[i].MakeUnique();
357 QUAT_TYPE a = quats[0][3];
358 if (!useFirstAngle) {
359 for (
int i = 1; i < n; i++)
363 for (
int i = 0; i < n; i++)
367 for (
int i = 0; i < n; i++) {
369 QUAT_TYPE qnorm = q[0]*q[0] + q[1]*q[1] + q[2]*q[2];
370 if (qnorm > QUAT_TYPE(1e-8)) {
371 QUAT_TYPE qscale = (QUAT_TYPE)sqrt(
double((1-q[3]*q[3])/qnorm));
372 for (
register int l = 0; l < 3; l++)
void Normalize()
Scales quaternion to unit length, i.e.
void MakeUnique()
makes Quaternion-representation uniqe, ensuring vector lies in upper (by real part) hemisphere...
class Vector4 contains a Vector of dim.
const unsigned int size() const
void Mult(const Quaternion< QUAT_TYPE > &quat)
quaternion multiplication: this= this * quat
class Vector3 contains a Vector of fixed dim.
void ScalarProduct(const Vector4< T > &argvec, T &result) const
scalar product (=inner product) of two vectors, storing the result in result
const T * GetData() const
get the data pointer the member function itself is const (before {..}) because it doesn't change the...
void MultiplyIP(const T &scalar)
Multiplication (in place) of an scalar.
Implements a 3D rotation matrix.
is a 'fixed size' quadratic matrix of dim.
class for rotation with axis and angle
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
void SetValueAsAxisRad(const Vector3< QUAT_TYPE > &axis, QUAT_TYPE angle)
sets the quaternion with given rotation axis and angle (in rad)