• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.12
  • kdeedu
  • marble
  • src
  • lib
  • marble
Quaternion.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
9 // Copyright 2007 Inge Wallin <ingwa@kde.org>
10 // Copyright 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
11 //
12 
13 #include "Quaternion.h"
14 
15 #include <cmath>
16 using namespace std;
17 
18 #include <QString>
19 #include <QDebug>
20 
21 
22 using namespace Marble;
23 
24 Quaternion::Quaternion()
25 {
26 // like in libeigen we keep the quaternion uninitialized
27 // set( 1.0, 0.0, 0.0, 0.0 );
28 }
29 
30 Quaternion::Quaternion(qreal w, qreal x, qreal y, qreal z)
31 {
32  v[Q_W] = w;
33  v[Q_X] = x;
34  v[Q_Y] = y;
35  v[Q_Z] = z;
36 }
37 
38 Quaternion Quaternion::fromSpherical(qreal lon, qreal lat)
39 {
40  const qreal w = 0.0;
41  const qreal x = cos(lat) * sin(lon);
42  const qreal y = sin(lat);
43  const qreal z = cos(lat) * cos(lon);
44 
45  return Quaternion( w, x, y, z );
46 }
47 
48 void Quaternion::getSpherical(qreal &lon, qreal &lat) const
49 {
50  qreal y = v[Q_Y];
51  if ( y > 1.0 )
52  y = 1.0;
53  else if ( y < -1.0 )
54  y = -1.0;
55 
56  lat = asin( y );
57 
58  if(v[Q_X] * v[Q_X] + v[Q_Z] * v[Q_Z] > 0.00005)
59  lon = atan2(v[Q_X], v[Q_Z]);
60  else
61  lon = 0.0;
62 }
63 
64 void Quaternion::normalize()
65 {
66  (*this) *= 1.0 / length();
67 }
68 
69 qreal Quaternion::length() const
70 {
71  return sqrt(v[Q_W] * v[Q_W] + v[Q_X] * v[Q_X] + v[Q_Y] * v[Q_Y] + v[Q_Z] * v[Q_Z]);
72 }
73 
74 Quaternion& Quaternion::operator*=(qreal mult)
75 {
76  (*this) = (*this) * mult;
77 
78  return *this;
79 }
80 
81 Quaternion Quaternion::inverse() const
82 {
83  Quaternion inverse( v[Q_W], -v[Q_X], -v[Q_Y], -v[Q_Z] );
84  inverse.normalize();
85 
86  return inverse;
87 }
88 
89 Quaternion Quaternion::fromEuler(qreal pitch, qreal yaw, qreal roll)
90 {
91  const qreal cPhi = cos(0.5 * pitch); // also: "heading"
92  const qreal cThe = cos(0.5 * yaw); // also: "attitude"
93  const qreal cPsi = cos(0.5 * roll); // also: "bank"
94 
95  const qreal sPhi = sin(0.5 * pitch);
96  const qreal sThe = sin(0.5 * yaw);
97  const qreal sPsi = sin(0.5 * roll);
98 
99  const qreal w = cPhi * cThe * cPsi + sPhi * sThe * sPsi;
100  const qreal x = sPhi * cThe * cPsi - cPhi * sThe * sPsi;
101  const qreal y = cPhi * sThe * cPsi + sPhi * cThe * sPsi;
102  const qreal z = cPhi * cThe * sPsi - sPhi * sThe * cPsi;
103 
104  return Quaternion( w, x, y, z );
105 }
106 
107 qreal Quaternion::pitch() const // "heading", phi
108 {
109  return atan2( 2.0*(v[Q_X]*v[Q_W]-v[Q_Y]*v[Q_Z]),
110  ( 1.0 - 2.0*(v[Q_X]*v[Q_X]+v[Q_Z]*v[Q_Z]) ) );
111 }
112 
113 qreal Quaternion::yaw() const // "attitude", theta
114 {
115  return atan2( 2.0*(v[Q_Y]*v[Q_W]-v[Q_X]*v[Q_Z]),
116  ( 1.0 - 2.0*(v[Q_Y]*v[Q_Y]+v[Q_Z]*v[Q_Z]) ) );
117 }
118 
119 qreal Quaternion::roll() const // "bank", psi
120 {
121  return asin(2.0*(v[Q_X]*v[Q_Y]+v[Q_Z]*v[Q_W]));
122 }
123 
124 #ifndef QT_NO_DEBUG_STREAM
125 QDebug operator<<(QDebug debug, const Quaternion &q)
126 {
127  QString quatdisplay = QString("Quaternion: w= %1, x= %2, y= %3, z= %4, |q|= %5" )
128  .arg(q.v[Q_W]).arg(q.v[Q_X]).arg(q.v[Q_Y]).arg(q.v[Q_Z]).arg(q.length());
129 
130  debug << quatdisplay;
131 
132  return debug;
133 }
134 #endif
135 
136 Quaternion& Quaternion::operator*=(const Quaternion &q)
137 {
138  (*this) = (*this) * q;
139 
140  return *this;
141 }
142 
143 bool Quaternion::operator==(const Quaternion &q) const
144 {
145 
146  return ( v[Q_W] == q.v[Q_W]
147  && v[Q_X] == q.v[Q_X]
148  && v[Q_Y] == q.v[Q_Y]
149  && v[Q_Z] == q.v[Q_Z] );
150 }
151 
152 Quaternion Quaternion::operator*(const Quaternion &q) const
153 {
154  const qreal w = v[Q_W] * q.v[Q_W] - v[Q_X] * q.v[Q_X] - v[Q_Y] * q.v[Q_Y] - v[Q_Z] * q.v[Q_Z];
155  const qreal x = v[Q_W] * q.v[Q_X] + v[Q_X] * q.v[Q_W] + v[Q_Y] * q.v[Q_Z] - v[Q_Z] * q.v[Q_Y];
156  const qreal y = v[Q_W] * q.v[Q_Y] - v[Q_X] * q.v[Q_Z] + v[Q_Y] * q.v[Q_W] + v[Q_Z] * q.v[Q_X];
157  const qreal z = v[Q_W] * q.v[Q_Z] + v[Q_X] * q.v[Q_Y] - v[Q_Y] * q.v[Q_X] + v[Q_Z] * q.v[Q_W];
158 
159  return Quaternion( w, x, y, z );
160 }
161 
162 Quaternion Quaternion::operator*(qreal factor) const
163 {
164  return Quaternion( v[Q_W] * factor, v[Q_X] * factor, v[Q_Y] * factor, v[Q_Z] * factor );
165 }
166 
167 void Quaternion::rotateAroundAxis(const Quaternion &q)
168 {
169  const qreal w = + v[Q_X] * q.v[Q_X] + v[Q_Y] * q.v[Q_Y] + v[Q_Z] * q.v[Q_Z];
170  const qreal x = + v[Q_X] * q.v[Q_W] - v[Q_Y] * q.v[Q_Z] + v[Q_Z] * q.v[Q_Y];
171  const qreal y = + v[Q_X] * q.v[Q_Z] + v[Q_Y] * q.v[Q_W] - v[Q_Z] * q.v[Q_X];
172  const qreal z = - v[Q_X] * q.v[Q_Y] + v[Q_Y] * q.v[Q_X] + v[Q_Z] * q.v[Q_W];
173 
174  (*this) = q * Quaternion( w, x, y, z );
175 }
176 
177 Quaternion Quaternion::slerp(const Quaternion &q1, const Quaternion &q2, qreal t)
178 {
179  qreal p1;
180  qreal p2;
181 
182  // Let alpha be the angle between the two quaternions.
183  qreal cosAlpha = ( q1.v[Q_X] * q2.v[Q_X]
184  + q1.v[Q_Y] * q2.v[Q_Y]
185  + q1.v[Q_Z] * q2.v[Q_Z]
186  + q1.v[Q_W] * q2.v[Q_W] );
187  qreal alpha = acos( cosAlpha );
188  qreal sinAlpha = sin( alpha );
189 
190  if ( sinAlpha > 0.0 ) {
191  p1 = sin( ( 1.0 - t ) * alpha ) / sinAlpha;
192  p2 = sin( t * alpha ) / sinAlpha;
193  } else {
194  // both Quaternions are equal
195  p1 = 1.0;
196  p2 = 0.0;
197  }
198 
199  const qreal w = p1 * q1.v[Q_W] + p2 * q2.v[Q_W];
200  const qreal x = p1 * q1.v[Q_X] + p2 * q2.v[Q_X];
201  const qreal y = p1 * q1.v[Q_Y] + p2 * q2.v[Q_Y];
202  const qreal z = p1 * q1.v[Q_Z] + p2 * q2.v[Q_Z];
203 
204  return Quaternion( w, x, y, z );
205 }
206 
207 Quaternion Quaternion::nlerp(const Quaternion &q1, const Quaternion &q2, qreal t)
208 {
209  const qreal p1 = 1.0 - t;
210 
211  const qreal w = p1 * q1.v[Q_W] + t * q2.v[Q_W];
212  const qreal x = p1 * q1.v[Q_X] + t * q2.v[Q_X];
213  const qreal y = p1 * q1.v[Q_Y] + t * q2.v[Q_Y];
214  const qreal z = p1 * q1.v[Q_Z] + t * q2.v[Q_Z];
215 
216  Quaternion result( w, x, y, z );
217  result.normalize();
218 
219  return result;
220 }
221 
222 void Quaternion::toMatrix(matrix &m) const
223 {
224 
225  const qreal xy = v[Q_X] * v[Q_Y], xz = v[Q_X] * v[Q_Z];
226  const qreal yy = v[Q_Y] * v[Q_Y], yw = v[Q_Y] * v[Q_W];
227  const qreal zw = v[Q_Z] * v[Q_W], zz = v[Q_Z] * v[Q_Z];
228 
229  m[0][0] = 1.0 - 2.0 * (yy + zz);
230  m[0][1] = 2.0 * (xy + zw);
231  m[0][2] = 2.0 * (xz - yw);
232  m[0][3] = 0.0;
233 
234  const qreal xx = v[Q_X] * v[Q_X];
235  const qreal xw = v[Q_X] * v[Q_W];
236  const qreal yz = v[Q_Y] * v[Q_Z];
237 
238  m[1][0] = 2.0 * (xy - zw);
239  m[1][1] = 1.0 - 2.0 * (xx + zz);
240  m[1][2] = 2.0 * (yz + xw);
241  m[1][3] = 0.0;
242 
243  m[2][0] = 2.0 * (xz + yw);
244  m[2][1] = 2.0 * (yz - xw);
245  m[2][2] = 1.0 - 2.0 * (xx + yy);
246  m[2][3] = 0.0;
247 }
248 
249 void Quaternion::rotateAroundAxis(const matrix &m)
250 {
251  const qreal x = m[0][0] * v[Q_X] + m[1][0] * v[Q_Y] + m[2][0] * v[Q_Z];
252  const qreal y = m[0][1] * v[Q_X] + m[1][1] * v[Q_Y] + m[2][1] * v[Q_Z];
253  const qreal z = m[0][2] * v[Q_X] + m[1][2] * v[Q_Y] + m[2][2] * v[Q_Z];
254 
255  v[Q_W] = 1.0;
256  v[Q_X] = x;
257  v[Q_Y] = y;
258  v[Q_Z] = z;
259 }
Quaternion.h
Marble::matrix
xmmfloat matrix[3]
Definition: Quaternion.h:40
operator<<
QDebug operator<<(QDebug debug, const Quaternion &q)
Definition: Quaternion.cpp:125
Marble::Q_W
Definition: Quaternion.h:35
Marble::operator==
bool operator==(const DownloadPolicyKey &lhs, const DownloadPolicyKey &rhs)
Definition: DownloadPolicy.h:49
normalize
void normalize(const QString &output)
Definition: tools/speaker-files/main.cpp:135
Marble::Q_Z
Definition: Quaternion.h:34
Marble::Q_Y
Definition: Quaternion.h:33
Marble::Q_X
Definition: Quaternion.h:32
Marble::Quaternion::length
qreal length() const
Definition: Quaternion.cpp:69
operator*
Vec3 operator*(double r, const Vec3 &c1)
Definition: attlib.cpp:134
Marble::Quaternion
Definition: Quaternion.h:43
Marble::Quaternion::v
xmmfloat v
Definition: Quaternion.h:86
Marble::Quaternion::normalize
void normalize()
Definition: Quaternion.cpp:64
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:52 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal