OpenMD 3.1
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
Quaternion.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2004-present, The University of Notre Dame. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
32 * research, please cite the appropriate papers when you publish your
33 * work. Good starting points are:
34 *
35 * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
36 * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
37 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
38 * [4] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
39 * [5] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
40 * [6] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
41 * [7] Lamichhane, Newman & Gezelter, J. Chem. Phys. 141, 134110 (2014).
42 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
43 */
44
45/**
46 * @file Quaternion.hpp
47 * @author Teng Lin
48 * @date 10/11/2004
49 * @version 1.0
50 */
51
52#ifndef MATH_QUATERNION_HPP
53#define MATH_QUATERNION_HPP
54
55#include <config.h>
56
57#include <cmath>
58
59#include "math/SquareMatrix.hpp"
60#include "math/Vector3.hpp"
61#include "utils/Constants.hpp"
62#define ISZERO(a, eps) ((a) > -(eps) && (a) < (eps))
63const RealType tiny = 1.0e-6;
64
65namespace OpenMD {
66
67 /**
68 * @class Quaternion Quaternion.hpp "math/Quaternion.hpp"
69 * Quaternion is a sort of a higher-level complex number.
70 * It is defined as \f$Q = w + x*i + y*j + z*k\f$,
71 * where w, x, y, and z are numbers of type T (e.g. RealType), and
72 * \f$i*i = -1\f$; \f$j*j = -1\f$; \f$k*k = -1\f$;
73 * \f$i*j = k\f$; \f$j*k = i\f$; \f$k*i = j\f$;
74 */
75 template<typename Real>
76 class Quaternion : public Vector<Real, 4> {
77 public:
79
80 /** Constructs and initializes a Quaternion from w, x, y, z values */
81 Quaternion(Real w, Real x, Real y, Real z) {
82 this->data_[0] = w;
83 this->data_[1] = x;
84 this->data_[2] = y;
85 this->data_[3] = z;
86 }
87
88 /** Constructs and initializes a Quaternion from a Vector<Real,4> */
89 Quaternion(const Vector<Real, 4>& v) : Vector<Real, 4>(v) {}
90
91 /** copy assignment */
93 if (this == &v) return *this;
94
96
97 return *this;
98 }
99
100 /**
101 * Returns the value of the first element of this quaternion.
102 * @return the value of the first element of this quaternion
103 */
104 Real w() const { return this->data_[0]; }
105
106 /**
107 * Returns the reference of the first element of this quaternion.
108 * @return the reference of the first element of this quaternion
109 */
110 Real& w() { return this->data_[0]; }
111
112 /**
113 * Returns the value of the first element of this quaternion.
114 * @return the value of the first element of this quaternion
115 */
116 Real x() const { return this->data_[1]; }
117
118 /**
119 * Returns the reference of the second element of this quaternion.
120 * @return the reference of the second element of this quaternion
121 */
122 Real& x() { return this->data_[1]; }
123
124 /**
125 * Returns the value of the thirf element of this quaternion.
126 * @return the value of the third element of this quaternion
127 */
128 Real y() const { return this->data_[2]; }
129
130 /**
131 * Returns the reference of the third element of this quaternion.
132 * @return the reference of the third element of this quaternion
133 */
134 Real& y() { return this->data_[2]; }
135
136 /**
137 * Returns the value of the fourth element of this quaternion.
138 * @return the value of the fourth element of this quaternion
139 */
140 Real z() const { return this->data_[3]; }
141 /**
142 * Returns the reference of the fourth element of this quaternion.
143 * @return the reference of the fourth element of this quaternion
144 */
145 Real& z() { return this->data_[3]; }
146
147 /**
148 * Tests if this quaternion is equal to other quaternion
149 * @return true if equal, otherwise return false
150 * @param q quaternion to be compared
151 */
152 inline bool operator==(const Quaternion<Real>& q) {
153 for (unsigned int i = 0; i < 4; i++) {
154 if (!equal(this->data_[i], q[i])) { return false; }
155 }
156
157 return true;
158 }
159
160 /**
161 * Returns the inverse of this quaternion
162 * @return inverse
163 * @note since quaternion is a complex number, the inverse of quaternion
164 * q = w + xi + yj+ zk is inv_q = (w -xi - yj - zk)/(|q|^2)
165 */
168 Real d = this->lengthSquare();
169
170 q.w() = w() / d;
171 q.x() = -x() / d;
172 q.y() = -y() / d;
173 q.z() = -z() / d;
174
175 return q;
176 }
177
178 /**
179 * Sets the value to the multiplication of itself and another quaternion
180 * @param q the other quaternion
181 */
182 void mul(const Quaternion<Real>& q) {
183 Quaternion<Real> tmp(*this);
184
185 this->data_[0] =
186 (tmp[0] * q[0]) - (tmp[1] * q[1]) - (tmp[2] * q[2]) - (tmp[3] * q[3]);
187 this->data_[1] =
188 (tmp[0] * q[1]) + (tmp[1] * q[0]) + (tmp[2] * q[3]) - (tmp[3] * q[2]);
189 this->data_[2] =
190 (tmp[0] * q[2]) + (tmp[2] * q[0]) + (tmp[3] * q[1]) - (tmp[1] * q[3]);
191 this->data_[3] =
192 (tmp[0] * q[3]) + (tmp[3] * q[0]) + (tmp[1] * q[2]) - (tmp[2] * q[1]);
193 }
194
195 void mul(const Real& s) {
196 this->data_[0] *= s;
197 this->data_[1] *= s;
198 this->data_[2] *= s;
199 this->data_[3] *= s;
200 }
201
202 /** Set the value of this quaternion to the division of itself by another
203 * quaternion */
204 void div(Quaternion<Real>& q) { mul(q.inverse()); }
205
206 void div(const Real& s) {
207 this->data_[0] /= s;
208 this->data_[1] /= s;
209 this->data_[2] /= s;
210 this->data_[3] /= s;
211 }
212
213 Quaternion<Real>& operator*=(const Quaternion<Real>& q) {
214 mul(q);
215 return *this;
216 }
217
218 Quaternion<Real>& operator*=(const Real& s) {
219 mul(s);
220 return *this;
221 }
222
223 Quaternion<Real>& operator/=(Quaternion<Real>& q) {
224 *this *= q.inverse();
225 return *this;
226 }
227
228 Quaternion<Real>& operator/=(const Real& s) {
229 div(s);
230 return *this;
231 }
232 /**
233 * Returns the conjugate quaternion of this quaternion
234 * @return the conjugate quaternion of this quaternion
235 */
237 return Quaternion<Real>(w(), -x(), -y(), -z());
238 }
239
240 /**
241 return rotation angle from -PI to PI
242 */
243 inline Real get_rotation_angle() const {
244 if (w() < (Real)0.0)
245 return 2.0 * atan2(-sqrt(x() * x() + y() * y() + z() * z()), -w());
246 else
247 return 2.0 * atan2(sqrt(x() * x() + y() * y() + z() * z()), w());
248 }
249
250 /**
251 create a unit quaternion from axis angle representation
252 */
254 const Real& angle) {
255 Vector3<Real> v(axis);
256 v.normalize();
257 Real half_angle = angle * 0.5;
258 Real sin_a = sin(half_angle);
259 *this = Quaternion<Real>(cos(half_angle), v.x() * sin_a, v.y() * sin_a,
260 v.z() * sin_a);
261 return *this;
262 }
263
264 /**
265 convert a quaternion to axis angle representation,
266 preserve the axis direction and angle from -PI to +PI
267 */
268 void toAxisAngle(Vector3<Real>& axis, Real& angle) const {
269 Real vl = sqrt(x() * x() + y() * y() + z() * z());
270 if (vl > tiny) {
271 Real ivl = 1.0 / vl;
272 axis.x() = x() * ivl;
273 axis.y() = y() * ivl;
274 axis.z() = z() * ivl;
275
276 if (w() < 0)
277 angle = 2.0 * atan2(-vl, -w()); //-PI,0
278 else
279 angle = 2.0 * atan2(vl, w()); // 0,PI
280 } else {
281 axis = Vector3<Real>(0.0, 0.0, 0.0);
282 angle = 0.0;
283 }
284 }
285
286 /**
287 shortest arc quaternion rotate one vector to another by shortest path.
288 create rotation from -> to, for any length vectors.
289 */
291 Vector3d c(cross(from, to));
292 *this = Quaternion<Real>(dot(from, to), c.x(), c.y(), c.z());
293
294 this->normalize(); // if "from" or "to" not unit, normalize quat
295 w() += 1.0f; // reducing angle to halfangle
296 if (w() <= 1e-6) { // angle close to PI
297 if ((from.z() * from.z()) > (from.x() * from.x())) {
298 this->data_[0] = w();
299 this->data_[1] = 0.0; // cross(from , Vector3d(1,0,0))
300 this->data_[2] = from.z();
301 this->data_[3] = -from.y();
302 } else {
303 this->data_[0] = w();
304 this->data_[1] = from.y(); // cross(from, Vector3d(0,0,1))
305 this->data_[2] = -from.x();
306 this->data_[3] = 0.0;
307 }
308 }
309 this->normalize();
310 }
311
312 Real ComputeTwist(const Quaternion& q) {
313 return (Real)2.0 * atan2(q.z(), q.w());
314 }
315
316 void RemoveTwist(Quaternion& q) {
317 Real t = ComputeTwist(q);
318 Quaternion rt = fromAxisAngle(V3Z, t);
319
320 q *= rt.inverse();
321 }
322
323 void getTwistSwingAxisAngle(Real& twistAngle, Real& swingAngle,
324 Vector3<Real>& swingAxis) {
325 twistAngle = (Real)2.0 * atan2(z(), w());
326 Quaternion rt, rs;
327 rt.fromAxisAngle(V3Z, twistAngle);
328 rs = *this * rt.inverse();
329
330 Real vl = sqrt(rs.x() * rs.x() + rs.y() * rs.y() + rs.z() * rs.z());
331 if (vl > tiny) {
332 Real ivl = 1.0 / vl;
333 swingAxis.x() = rs.x() * ivl;
334 swingAxis.y() = rs.y() * ivl;
335 swingAxis.z() = rs.z() * ivl;
336
337 if (rs.w() < 0.0)
338 swingAngle = 2.0 * atan2(-vl, -rs.w()); //-PI,0
339 else
340 swingAngle = 2.0 * atan2(vl, rs.w()); // 0,PI
341 } else {
342 swingAxis = Vector3<Real>(1.0, 0.0, 0.0);
343 swingAngle = 0.0;
344 }
345 }
346
347 Vector3<Real> rotate(const Vector3<Real>& v) {
348 Quaternion<Real> q(v.x() * w() + v.z() * y() - v.y() * z(),
349 v.y() * w() + v.x() * z() - v.z() * x(),
350 v.z() * w() + v.y() * x() - v.x() * y(),
351 v.x() * x() + v.y() * y() + v.z() * z());
352
353 return Vector3<Real>(
354 w() * q.x() + x() * q.w() + y() * q.z() - z() * q.y(),
355 w() * q.y() + y() * q.w() + z() * q.x() - x() * q.z(),
356 w() * q.z() + z() * q.w() + x() * q.y() - y() * q.x()) *
357 (1.0 / this->lengthSquare());
358 }
359
360 Quaternion<Real>& align(const Vector3<Real>& V1, const Vector3<Real>& V2) {
361 // If V1 and V2 are not parallel, the axis of rotation is the unit-length
362 // vector U = Cross(V1,V2)/Length(Cross(V1,V2)). The angle of rotation,
363 // A, is the angle between V1 and V2. The quaternion for the rotation is
364 // q = cos(A/2) + sin(A/2)*(ux*i+uy*j+uz*k) where U = (ux,uy,uz).
365 //
366 // (1) Rather than extract A = acos(Dot(V1,V2)), multiply by 1/2, then
367 // compute sin(A/2) and cos(A/2), we reduce the computational costs
368 // by computing the bisector B = (V1+V2)/Length(V1+V2), so cos(A/2) =
369 // Dot(V1,B).
370 //
371 // (2) The rotation axis is U = Cross(V1,B)/Length(Cross(V1,B)), but
372 // Length(Cross(V1,B)) = Length(V1)*Length(B)*sin(A/2) = sin(A/2), in
373 // which case sin(A/2)*(ux*i+uy*j+uz*k) = (cx*i+cy*j+cz*k) where
374 // C = Cross(V1,B).
375 //
376 // If V1 = V2, then B = V1, cos(A/2) = 1, and U = (0,0,0). If V1 = -V2,
377 // then B = 0. This can happen even if V1 is approximately -V2 using
378 // floating point arithmetic, since Vector3::Normalize checks for
379 // closeness to zero and returns the zero vector accordingly. The test
380 // for exactly zero is usually not recommend for floating point
381 // arithmetic, but the implementation of Vector3::Normalize guarantees
382 // the comparison is robust. In this case, the A = pi and any axis
383 // perpendicular to V1 may be used as the rotation axis.
384
385 Vector3<Real> Bisector = V1 + V2;
386 Bisector.normalize();
387
388 Real CosHalfAngle = dot(V1, Bisector);
389
390 this->data_[0] = CosHalfAngle;
391
392 if (CosHalfAngle != (Real)0.0) {
393 Vector3<Real> Cross = cross(V1, Bisector);
394 this->data_[1] = Cross.x();
395 this->data_[2] = Cross.y();
396 this->data_[3] = Cross.z();
397 } else {
398 Real InvLength;
399 if (fabs(V1[0]) >= fabs(V1[1])) {
400 // V1.x or V1.z is the largest magnitude component
401 InvLength = (Real)1.0 / sqrt(V1[0] * V1[0] + V1[2] * V1[2]);
402
403 this->data_[1] = -V1[2] * InvLength;
404 this->data_[2] = (Real)0.0;
405 this->data_[3] = +V1[0] * InvLength;
406 } else {
407 // V1.y or V1.z is the largest magnitude component
408 InvLength = (Real)1.0 / sqrt(V1[1] * V1[1] + V1[2] * V1[2]);
409
410 this->data_[1] = (Real)0.0;
411 this->data_[2] = +V1[2] * InvLength;
412 this->data_[3] = -V1[1] * InvLength;
413 }
414 }
415 return *this;
416 }
417
418 void toTwistSwing(Real& tw, Real& sx, Real& sy) {
419 // First test if the swing is in the singularity:
420
421 if (ISZERO(z(), tiny) && ISZERO(w(), tiny)) {
422 sx = sy = Constants::PI;
423 tw = 0;
424 return;
425 }
426
427 // Decompose into twist-swing by solving the equation:
428 //
429 // Qtwist(t*2) * Qswing(s*2) = q
430 //
431 // note: (x,y) is the normalized swing axis (x*x+y*y=1)
432 //
433 // ( Ct 0 0 St ) * ( Cs xSs ySs 0 ) = ( qw qx qy qz )
434 // ( CtCs xSsCt-yStSs xStSs+ySsCt StCs ) = ( qw qx qy qz ) (1)
435 // From (1): CtCs / StCs = qw/qz => Ct/St = qw/qz => tan(t) = qz/qw (2)
436 //
437 // The swing rotation/2 s comes from:
438 //
439 // From (1): (CtCs)^2 + (StCs)^2 = qw^2 + qz^2 =>
440 // Cs = sqrt ( qw^2 + qz^2 ) (3)
441 //
442 // From (1): (xSsCt-yStSs)^2 + (xStSs+ySsCt)^2 = qx^2 + qy^2 =>
443 // Ss = sqrt ( qx^2 + qy^2 ) (4)
444 // From (1): |SsCt -StSs| |x| = |qx|
445 // |StSs +SsCt| |y| |qy| (5)
446
447 Real qw, qx, qy, qz;
448
449 if (w() < 0) {
450 qw = -w();
451 qx = -x();
452 qy = -y();
453 qz = -z();
454 } else {
455 qw = w();
456 qx = x();
457 qy = y();
458 qz = z();
459 }
460
461 Real t = atan2(qz, qw); // from (2)
462 Real s =
463 atan2(sqrt(qx * qx + qy * qy), sqrt(qz * qz + qw * qw)); // from (3)
464 // and (4)
465
466 Real x = 0.0, y = 0.0, sins = sin(s);
467
468 if (!ISZERO(sins, tiny)) {
469 Real sint = sin(t);
470 Real cost = cos(t);
471
472 // by solving the linear system in (5):
473 y = (-qx * sint + qy * cost) / sins;
474 x = (qx * cost + qy * sint) / sins;
475 }
476
477 tw = (Real)2.0 * t;
478 sx = (Real)2.0 * x * s;
479 sy = (Real)2.0 * y * s;
480 }
481
482 void toSwingTwist(Real& sx, Real& sy, Real& tw) {
483 // Decompose q into swing-twist using a similar development as
484 // in function toTwistSwing
485
486 if (ISZERO(z(), tiny) && ISZERO(w(), tiny)) {
487 sx = sy = Constants::PI;
488 tw = 0;
489 }
490
491 Real qw, qx, qy, qz;
492 if (w() < 0) {
493 qw = -w();
494 qx = -x();
495 qy = -y();
496 qz = -z();
497 } else {
498 qw = w();
499 qx = x();
500 qy = y();
501 qz = z();
502 }
503
504 // Get the twist t:
505 Real t = 2.0 * atan2(qz, qw);
506
507 Real bet = atan2(sqrt(qx * qx + qy * qy), sqrt(qz * qz + qw * qw));
508 Real gam = t / 2.0;
509 Real sinc = ISZERO(bet, tiny) ? 1.0 : sin(bet) / bet;
510 Real singam = sin(gam);
511 Real cosgam = cos(gam);
512
513 sx = Real((2.0 / sinc) * (cosgam * qx - singam * qy));
514 sy = Real((2.0 / sinc) * (singam * qx + cosgam * qy));
515 tw = Real(t);
516 }
517
518 /**
519 * Returns the corresponding rotation matrix (3x3)
520 * @return a 3x3 rotation matrix
521 */
523 SquareMatrix<Real, 3> rotMat3;
524
525 Real w2;
526 Real x2;
527 Real y2;
528 Real z2;
529
530 if (!this->isNormalized()) this->normalize();
531
532 w2 = w() * w();
533 x2 = x() * x();
534 y2 = y() * y();
535 z2 = z() * z();
536
537 rotMat3(0, 0) = w2 + x2 - y2 - z2;
538 rotMat3(0, 1) = 2.0 * (x() * y() + w() * z());
539 rotMat3(0, 2) = 2.0 * (x() * z() - w() * y());
540
541 rotMat3(1, 0) = 2.0 * (x() * y() - w() * z());
542 rotMat3(1, 1) = w2 - x2 + y2 - z2;
543 rotMat3(1, 2) = 2.0 * (y() * z() + w() * x());
544
545 rotMat3(2, 0) = 2.0 * (x() * z() + w() * y());
546 rotMat3(2, 1) = 2.0 * (y() * z() - w() * x());
547 rotMat3(2, 2) = w2 - x2 - y2 + z2;
548
549 return rotMat3;
550 }
551
552 }; // end Quaternion
553
554 /**
555 * Returns the vaule of scalar multiplication of this quaterion q (q * s).
556 * @return the vaule of scalar multiplication of this vector
557 * @param q the source quaternion
558 * @param s the scalar value
559 */
560 template<typename Real, unsigned int Dim>
562 Quaternion<Real> result(q);
563 result.mul(s);
564 return result;
565 }
566
567 /**
568 * Returns the vaule of scalar multiplication of this quaterion q (q * s).
569 * @return the vaule of scalar multiplication of this vector
570 * @param s the scalar value
571 * @param q the source quaternion
572 */
573 template<typename Real, unsigned int Dim>
574 Quaternion<Real> operator*(const Real& s, const Quaternion<Real>& q) {
575 Quaternion<Real> result(q);
576 result.mul(s);
577 return result;
578 }
579
580 /**
581 * Returns the multiplication of two quaternion
582 * @return the multiplication of two quaternion
583 * @param q1 the first quaternion
584 * @param q2 the second quaternion
585 */
586 template<typename Real>
588 const Quaternion<Real>& q2) {
589 Quaternion<Real> result(q1);
590 result *= q2;
591 return result;
592 }
593
594 /**
595 * Returns the division of two quaternion
596 * @param q1 divisor
597 * @param q2 dividen
598 */
599
600 template<typename Real>
602 Quaternion<Real>& q2) {
603 return q1 * q2.inverse();
604 }
605
606 /**
607 * Returns the value of the division of a scalar by a quaternion
608 * @return the value of the division of a scalar by a quaternion
609 * @param s scalar
610 * @param q quaternion
611 * @note for a quaternion q, 1/q = q.inverse()
612 */
613 template<typename Real>
616 x = q.inverse();
617 x *= s;
618 return x;
619 }
620
621 template<class T>
622 inline bool operator==(const Quaternion<T>& lhs, const Quaternion<T>& rhs) {
623 return equal(lhs[0], rhs[0]) && equal(lhs[1], rhs[1]) &&
624 equal(lhs[2], rhs[2]) && equal(lhs[3], rhs[3]);
625 }
626
627 using Quat4d = Quaternion<RealType>;
628} // namespace OpenMD
629
630#endif // MATH_QUATERNION_HPP
Quaternion is a sort of a higher-level complex number.
Real x() const
Returns the value of the first element of this quaternion.
Real z() const
Returns the value of the fourth element of this quaternion.
Quaternion(const Vector< Real, 4 > &v)
Constructs and initializes a Quaternion from a Vector<Real,4>
SquareMatrix< Real, 3 > toRotationMatrix3()
Returns the corresponding rotation matrix (3x3)
Real & z()
Returns the reference of the fourth element of this quaternion.
Quaternion< Real > fromAxisAngle(const Vector3< Real > &axis, const Real &angle)
create a unit quaternion from axis angle representation
void div(Quaternion< Real > &q)
Set the value of this quaternion to the division of itself by another quaternion.
Quaternion< Real > conjugate() const
Returns the conjugate quaternion of this quaternion.
Real w() const
Returns the value of the first element of this quaternion.
Quaternion(Real w, Real x, Real y, Real z)
Constructs and initializes a Quaternion from w, x, y, z values.
bool operator==(const Quaternion< Real > &q)
Tests if this quaternion is equal to other quaternion.
void toAxisAngle(Vector3< Real > &axis, Real &angle) const
convert a quaternion to axis angle representation, preserve the axis direction and angle from -PI to ...
Real & y()
Returns the reference of the third element of this quaternion.
Real & w()
Returns the reference of the first element of this quaternion.
Quaternion< Real > fromShortestArc(const Vector3d &from, const Vector3d &to)
shortest arc quaternion rotate one vector to another by shortest path.
Quaternion & operator=(const Vector< Real, 4 > &v)
copy assignment
Real & x()
Returns the reference of the second element of this quaternion.
Quaternion< Real > inverse()
Returns the inverse of this quaternion.
Real get_rotation_angle() const
return rotation angle from -PI to PI
Real y() const
Returns the value of the thirf element of this quaternion.
void mul(const Quaternion< Real > &q)
Sets the value to the multiplication of itself and another quaternion.
A square matrix class.
Real & z()
Returns reference of the third element of Vector3.
Definition Vector3.hpp:120
Real & x()
Returns reference of the first element of Vector3.
Definition Vector3.hpp:96
Real & y()
Returns reference of the second element of Vector3.
Definition Vector3.hpp:108
Fix length vector class.
Definition Vector.hpp:78
Vector< Real, Dim > & operator=(const Vector< Real, Dim > &v)
copy assignment operator
Definition Vector.hpp:93
void normalize()
Normalizes this vector in place.
Definition Vector.hpp:402
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
bool equal(const Polynomial< Real > &p1, const Polynomial< Real > &p2)
Tests if two polynomial have the same exponents.
Vector3< Real > cross(const Vector3< Real > &v1, const Vector3< Real > &v2)
Returns the cross product of two Vectors.
Definition Vector3.hpp:136
Real dot(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the dot product of two DynamicVectors.
DynamicRectMatrix< Real > operator*(const DynamicRectMatrix< Real > &m, Real s)
Return the multiplication of scalar and matrix (m * s).
DynamicRectMatrix< Real > operator/(const DynamicRectMatrix< Real > &m, Real s)
Return the scalar division of matrix (m / s).