Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
QuaternionInl.hh
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 template <class QUAT_TYPE> inline
28 {
29  *this = q;
30 }
31 
32 template <class QUAT_TYPE> inline
34 {
35  (*this)[0] *=-1;
36  (*this)[1] *=-1;
37  (*this)[2] *=-1;
38 }
39 
40 template <class QUAT_TYPE> inline
42 {
43  Quaternion<QUAT_TYPE> res(*this);
44  res.Invert();
45  return res;
46 }
47 
48 template <class QUAT_TYPE> inline
50 {
51  //project quaternion to upper hemisphere (first ima.part >= 0)
52  QUAT_TYPE *qThis = this->GetData();
53  if ((qThis[3] <= QUATERNION_EPSILON)
54  &&(qThis[3] >= -QUATERNION_EPSILON)) {
55  if ((qThis[1] <= QUATERNION_EPSILON)
56  &&(qThis[1] >= -QUATERNION_EPSILON)) {
57  if ((qThis[2] <= QUATERNION_EPSILON)
58  &&(qThis[2] >= -QUATERNION_EPSILON)) {
59  if (qThis[0] < 0.0) (*this) *= -1.0;
60  } else if (qThis[2] < 0.0) {
61  (*this) *= -1.0;
62  }
63  } else if (qThis[1] < 0.0) {
64  (*this) *= -1.0;
65  }
66  } else if (qThis[3] < 0.0) {
67  (*this) *= -1.0;
68  }
69 }
70 
71 template <class QUAT_TYPE> inline
73 {
74  QUAT_TYPE s1, s2, s3, s4, s5, s6, s7, s8, s9, t;
75  QUAT_TYPE *qThis = this->GetData();
76 
77  s1 = (qThis[2] - qThis[1]) * (quat[1] - quat[2]);
78  s2 = (qThis[3] + qThis[0]) * (quat[3] + quat[0]);
79  s3 = (qThis[3] - qThis[0]) * (quat[1] + quat[2]);
80  s4 = (qThis[2] + qThis[1]) * (quat[3] - quat[0]);
81  s5 = (qThis[2] - qThis[0]) * (quat[0] - quat[1]);
82  s6 = (qThis[2] + qThis[0]) * (quat[0] + quat[1]);
83  s7 = (qThis[3] + qThis[1]) * (quat[3] - quat[2]);
84  s8 = (qThis[3] - qThis[1]) * (quat[3] + quat[2]);
85 
86  s9 = s6 + s7 + s8;
87 
88  t = (s5 + s9) / 2.0f;
89 
90  qThis[3] = s1 + t - s6;
91  qThis[0] = s2 + t - s9;
92  qThis[1] = s3 + t - s8;
93  qThis[2] = s4 + t - s7;
94 }
95 
96 template <class QUAT_TYPE> inline
98  Quaternion<QUAT_TYPE> &res) const
99 {
100  res = *this;
101  res.Mult(arg);
102 }
103 
104 template <class QUAT_TYPE> inline
106 {
107  QUAT_TYPE s1, s2, s3, s4, s5, s6, s7, s8, s9, t;
108  QUAT_TYPE *qThis = this->GetData();
109 
110  s1 = (quatLeft[2] - quatLeft[1]) * (qThis[1] - qThis[2]);
111  s2 = (quatLeft[3] + quatLeft[0]) * (qThis[3] + qThis[0]);
112  s3 = (quatLeft[3] - quatLeft[0]) * (qThis[1] + qThis[2]);
113  s4 = (quatLeft[2] + quatLeft[1]) * (qThis[3] - qThis[0]);
114  s5 = (quatLeft[2] - quatLeft[0]) * (qThis[0] - qThis[1]);
115  s6 = (quatLeft[2] + quatLeft[0]) * (qThis[0] + qThis[1]);
116  s7 = (quatLeft[3] + quatLeft[1]) * (qThis[3] - qThis[2]);
117  s8 = (quatLeft[3] - quatLeft[1]) * (qThis[3] + qThis[2]);
118 
119  s9 = s6 + s7 + s8;
120 
121  t = (s5 + s9) / 2.0f;
122 
123  qThis[3] = s1 + t - s6;
124  qThis[0] = s2 + t - s9;
125  qThis[1] = s3 + t - s8;
126  qThis[2] = s4 + t - s7;
127 }
128 
129 /** rotates the given Vector with the quaternion ( q v q* )
130  the resulting vector is given in res
131  @returns 0 in case of no error
132  @author Daniel Grest, June 2003
133 */
134 template <class QUAT_TYPE> inline
136  Vector3<QUAT_TYPE> &res) const
137 {
138  register QUAT_TYPE rx,ry,rz;
139  register QUAT_TYPE Vx= vec[0], Vy=vec[1], Vz=vec[2];
140  const QUAT_TYPE *q = this->GetData();
141  {
142  register QUAT_TYPE QwQx, QwQy, QwQz, QxQy, QxQz, QyQz;
143  QwQx = q[3] * q[0]; QwQy = q[3] * q[1]; QwQz = q[3] * q[2];
144  QxQy = q[0] * q[1]; QxQz = q[0] * q[2]; QyQz = q[1] * q[2];
145  rx = 2* (Vy * (-QwQz + QxQy) + Vz *( QwQy + QxQz));
146  ry = 2* (Vx * ( QwQz + QxQy) + Vz *(-QwQx + QyQz));
147  rz = 2* (Vx * (-QwQy + QxQz) + Vy *( QwQx + QyQz));
148  }
149  register QUAT_TYPE QwQw, QxQx, QyQy, QzQz;
150  QwQw= q[3]*q[3]; QxQx = q[0]*q[0]; QyQy = q[1]*q[1]; QzQz= q[2]*q[2];
151  rx+= Vx * (QwQw + QxQx - QyQy - QzQz);
152  ry+= Vy * (QwQw - QxQx + QyQy - QzQz);
153  rz+= Vz * (QwQw - QxQx - QyQy + QzQz);
154  res[0]=rx; res[1]=ry; res[2]=rz;
155  return 0;
156 }
157 
158 template <class QUAT_TYPE> inline
160 MultVec(const Vector3<QUAT_TYPE> &vec) const
161 {
162  Vector3<QUAT_TYPE> r; MultVec(vec,r);
163  return r;
164 }
165 
166 template <class QUAT_TYPE> inline
168 {
169  (*this)[0] = (*this)[1] = (*this)[2] = 0;
170  (*this)[3] = 1;
171 }
172 
173 template <class QUAT_TYPE> inline
174 void Quaternion<QUAT_TYPE>::SetQuaternion(QUAT_TYPE real, QUAT_TYPE i,
175  QUAT_TYPE j, QUAT_TYPE k)
176 {
177  //Components are stored in Vec4 in order imaginary part 1,2,3 and real part
178  this->Set(i,j,k,real);
179 }
180 
181 template <class QUAT_TYPE> inline
183  QUAT_TYPE angle)
184 {
185  SetValueAsAxisRad(axis[0], axis[1], axis[2], angle);
186 }
187 
188 template <class QUAT_TYPE> inline
189 void Quaternion<QUAT_TYPE>::SetValueAsAxisRad(QUAT_TYPE x, QUAT_TYPE y,
190  QUAT_TYPE z, QUAT_TYPE w)
191 {
192  QUAT_TYPE rTmp = QUAT_TYPE(sqrt(x * x + y * y + z * z));
193 
194  if(rTmp > QUATERNION_EPSILON)
195  {
196  rTmp = QUAT_TYPE(sin(w / 2.0f)) / rTmp;
197 
198  (*this)[0] = x * rTmp;
199  (*this)[1] = y * rTmp;
200  (*this)[2] = z * rTmp;
201  (*this)[3] = QUAT_TYPE(cos(w / 2.0f));
202  }
203  else
204  {
205  SetIdentity();
206  }
207 }
208 
209 template <class QUAT_TYPE> inline
212 {
213  // @todo Check if quaternion has unit length!
214  const QUAT_TYPE s = 1 / ((*this)[3] + ((*this)[3] < 0 ? -1 : 1));
215  p3D[0] = s * (*this)[0];
216  p3D[1] = s * (*this)[1];
217  p3D[2] = s * (*this)[2];
218 }
219 
220 template <class QUAT_TYPE> inline
223 {
224  const QUAT_TYPE s = 2 / (p3D[0]*p3D[0] + p3D[1]*p3D[1] + p3D[2]*p3D[2] + 1);
225  (*this)[0] = s * p3D[0];
226  (*this)[1] = s * p3D[1];
227  (*this)[2] = s * p3D[2];
228  (*this)[3] = s - 1;
229 }
void Invert()
inverts this, by changing the rotation axis by *=-1
Definition: Quaternion.hh:34
void Mult(const Quaternion< QUAT_TYPE > &quat)
quaternion multiplication: this= this * quat
Definition: Quaternion.hh:73
class Vector3 contains a Vector of fixed dim.
Definition: Matrix.hh:53
class for rotation with axis and angle