cheshirekow  v0.1.0
quaternion.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Josh Bialkowski (jbialk@mit.edu)
3  *
4  * This file is part of fiber.
5  *
6  * fiber is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * fiber is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with fiber. If not, see <http://www.gnu.org/licenses/>.
18  */
25 #ifndef FIBER_QUATERNION_H_
26 #define FIBER_QUATERNION_H_
27 
28 
29 namespace fiber {
30 
31 template <typename Scalar>
32 class Quaternion : public fiber::_RValue<Scalar, Quaternion<Scalar> > {
33  private:
34  Scalar data_[4];
35 
36  public:
37  enum {
38  ROWS_ = 4,
39  COLS_ = 1,
40  SIZE_ = 1
41  };
42 
43  Size size() const { return 4; }
44  Size rows() const { return 4; }
45  Size cols() const { return 1; }
46 
47  Scalar& w() { return data_[0]; }
48  Scalar w() const { return data_[0]; }
49 
50  Scalar& x() { return data_[1]; }
51  Scalar x() const { return data_[1]; }
52 
53  Scalar& y() { return data_[2]; }
54  Scalar y() const { return data_[2]; }
55 
56  Scalar& z() { return data_[3]; }
57  Scalar z() const { return data_[3]; }
58 
59  Scalar& operator[](Size i) {
60  assert(0 <= i && i < 4);
61  return data_[i];
62  }
63 
64  Scalar operator[](Size i) const {
65  assert(0 <= i && i < 4);
66  return data_[i];
67  }
68 
69  Scalar operator()(Size i, Size j) const {
70  assert(0 <= i && i < 4);
71  assert(j == 0);
72  return data_[i];
73  }
74 
77  data_[0] = 1;
78  for (int i = 0; i < 3; i++) {
79  data_[1 + i] = 0;
80  }
81  }
82 
84  Quaternion(Scalar w, Scalar x, Scalar y, Scalar z) {
85  data_[0] = w;
86  data_[1] = x;
87  data_[2] = y;
88  data_[3] = z;
89  }
90 
92  template <typename Exp>
94  assert(exp.size() == 4);
95  for (int i = 0; i < 4; i++) {
96  data_[i] = exp[i];
97  }
98  }
99 
100  Quaternion(const AxisAngle<Scalar>& axis_angle) {
101  AxisAngleToQuaternion(axis_angle, this);
102  }
103 
104  template <int Axis>
106  CoordinateAxisAngleToQuaternion(axis_angle, this);
107  }
108 
109  template <int... Axes>
111  EulerAnglesToQuaternion(euler, this);
112  }
113 
114  template <typename Exp>
116  assert(exp.size() == 4);
117  for (int i = 0; i < 4; i++) {
118  data_[i] = exp[i];
119  }
120  return *this;
121  }
122 
124  AxisAngleToQuaternion(axis_angle, this);
125  return *this;
126  }
127 
128  template <int Axis>
130  const CoordinateAxisAngle<Scalar, Axis>& axis_angle) {
131  CoordinateAxisAngleToQuaternion(axis_angle, this);
132  return *this;
133  }
134 
135  template <int... Axes>
137  EulerAnglesToQuaternion(euler, this);
138  return *this;
139  }
140 
141  template <typename Exp>
143  assert(exp.size() == 3);
144  Quaternion<Scalar> projected(0, exp[0], exp[1], exp[2]);
145  return fiber::GetRows<3>((*this) * projected * Conjugate(*this), 1);
146  }
147 };
148 
149 template <typename Scalar>
151  return Quaternion<Scalar>(q[0], -q[1], -q[2], -q[3]);
152 }
153 
155 
165 template <typename Scalar>
167  Quaternion<Scalar> const& q_B) {
168  return Quaternion<Scalar>(
169  q_A[0] * q_B[0] - q_A[1] * q_B[1] - q_A[2] * q_B[2] - q_A[3] * q_B[3],
170  q_A[1] * q_B[0] + q_A[0] * q_B[1] - q_A[3] * q_B[2] + q_A[2] * q_B[3],
171  q_A[2] * q_B[0] + q_A[3] * q_B[1] + q_A[0] * q_B[2] - q_A[1] * q_B[3],
172  q_A[3] * q_B[0] - q_A[2] * q_B[1] + q_A[1] * q_B[2] + q_A[0] * q_B[3]);
173 // Same code as above but reordered with the A terms in order, to help
174 // verify correctness
175 // return Quaternion<Scalar>(
176 // q_A[0] * q_B[0] - q_A[1] * q_B[1] - q_A[2] * q_B[2] - q_A[3] * q_B[3],
177 // q_A[0] * q_B[1] + q_A[1] * q_B[0] + q_A[2] * q_B[3] - q_A[3] * q_B[2],
178 // q_A[0] * q_B[2] - q_A[1] * q_B[3] + q_A[2] * q_B[0] + q_A[3] * q_B[1],
179 // q_A[0] * q_B[3] + q_A[1] * q_B[2] - q_A[2] * q_B[1] + q_A[3] * q_B[0]);
180 }
181 
184 
185 } // namespace fiber
186 
187 
188 #endif // FIBER_QUATERNION_H_
Scalar x() const
Definition: quaternion.h:51
Scalar w() const
Definition: quaternion.h:48
void EulerAnglesToQuaternion(const euler::Angles< Scalar, Axis1, Axis2, Axis3 > &euler, Quaternion< Scalar > *q)
Quaternion(const AxisAngle< Scalar > &axis_angle)
Definition: quaternion.h:100
expression template for rvalues
Definition: rvalue.h:33
Quaternion< Scalar > & operator=(const AxisAngle< Scalar > &axis_angle)
Definition: quaternion.h:123
Size cols() const
Definition: quaternion.h:45
Scalar & z()
Definition: quaternion.h:56
Quaternion< float > Quaternionf
Definition: quaternion.h:183
Quaternion< Scalar > & operator=(const CoordinateAxisAngle< Scalar, Axis > &axis_angle)
Definition: quaternion.h:129
Scalar & x()
Definition: quaternion.h:50
Scalar operator()(Size i, Size j) const
Definition: quaternion.h:69
unsigned int Size
Definition: fiber.h:32
Size size() const
Definition: quaternion.h:43
void AxisAngleToQuaternion(const fiber::_RValue< Scalar, Exp > &axis, const Scalar angle, Quaternion< Scalar > *q)
Size rows() const
Definition: quaternion.h:44
Scalar z() const
Definition: quaternion.h:57
Scalar & y()
Definition: quaternion.h:53
Matrix< Scalar, 3, 1 > Rotate(const fiber::_RValue< Scalar, Exp > &exp) const
Definition: quaternion.h:142
Scalar y() const
Definition: quaternion.h:54
void CoordinateAxisAngleToQuaternion(const CoordinateAxisAngle< Scalar, Axis > &axis_angle, Quaternion< Scalar > *q)
Quaternion()
Default constructor, identity quaternion.
Definition: quaternion.h:76
A vector of euler angles.
Definition: euler_angles.h:40
An axis angle rotation about a coordinate axis.
Definition: axis_angle.h:103
Scalar operator[](Size i) const
Definition: quaternion.h:64
Quaternion< Scalar > & operator=(const euler::Angles< Scalar, Axes...> &euler)
Definition: quaternion.h:136
Quaternion< Scalar > & operator=(const fiber::_RValue< Scalar, Exp > &exp)
Definition: quaternion.h:115
Quaternion(Scalar w, Scalar x, Scalar y, Scalar z)
inline constructor
Definition: quaternion.h:84
Quaternion(const fiber::_RValue< Scalar, Exp > &exp)
Construct from any MatrixExpression, copies elements.
Definition: quaternion.h:93
Quaternion(const CoordinateAxisAngle< Scalar, Axis > &axis_angle)
Definition: quaternion.h:105
Scalar & operator[](Size i)
Definition: quaternion.h:59
Encodes a rotation in 3-dimensions by an return RView<Scalar, Exp, rows, Exp::COLS>(static_cast<Exp c...
Definition: axis_angle.h:33
Scalar data_[4]
Definition: quaternion.h:34
Quaternion< Scalar > Conjugate(Quaternion< Scalar > const &q)
Definition: quaternion.h:150
Scalar & w()
Definition: quaternion.h:47
Matrix< Scalar, Exp1::ROWS_, Exp2::COLS_ > operator*(_RValue< Scalar, Exp1 > const &A, _RValue< Scalar, Exp2 > const &B)
Matrix multiplication.
Definition: product.h:34
Quaternion(const euler::Angles< Scalar, Axes...> &euler)
Definition: quaternion.h:110
Size size() const
Definition: rvalue.h:35
Quaternion< double > Quaterniond
Definition: quaternion.h:182