24 #ifndef FIBER_ROTATION_CONVERSIONS_H_
25 #define FIBER_ROTATION_CONVERSIONS_H_
31 template <
typename Scalar>
33 template <
typename Scalar,
int Axis>
34 class CoordinateAxisAngle;
35 template <
typename Scalar>
38 template <
typename Scalar,
int Axis1,
int Axis2,
int Axis3>
49 template <
typename Scalar,
class Exp>
52 Scalar theta_over_2 = angle / Scalar(2.0);
53 Scalar cos_theta_over_2 = std::cos(theta_over_2);
54 Scalar sin_theta_over_2 = std::sin(theta_over_2);
55 (*q)[0] = cos_theta_over_2;
56 (*q)[1] = sin_theta_over_2 * axis[0];
57 (*q)[2] = sin_theta_over_2 * axis[1];
58 (*q)[3] = sin_theta_over_2 * axis[2];
67 template <
typename Scalar>
79 template <
typename Scalar,
class Exp>
82 Scalar sin_theta = std::sin(axis_angle.
GetAngle());
83 Scalar cos_theta = std::cos(axis_angle.
GetAngle());
86 + (1 - cos_theta) * axis_angle.
GetAxis()
96 template <
typename Scalar,
int Axis>
100 Scalar theta_over_2 = axis_angle.
GetAngle() / Scalar(2.0);
101 Scalar cos_theta_over_2 = std::cos(theta_over_2);
102 Scalar sin_theta_over_2 = std::sin(theta_over_2);
103 (*q)[0] = cos_theta_over_2;
104 (*q)[1] = (Axis == 0 ? sin_theta_over_2 : 0);
105 (*q)[2] = (Axis == 1 ? sin_theta_over_2 : 0);
106 (*q)[3] = (Axis == 2 ? sin_theta_over_2 : 0);
115 template <
typename Scalar,
int Axis,
class Exp>
119 Scalar sin_theta = std::sin(axis_angle.
GetAngle());
120 Scalar cos_theta = std::cos(axis_angle.
GetAngle());
123 0, cos_theta, -sin_theta,
124 0, sin_theta, cos_theta;
125 }
else if (Axis == 1) {
126 (*R) << cos_theta, 0, sin_theta,
128 -sin_theta, 0, cos_theta;
129 }
else if (Axis == 2) {
130 (*R) << cos_theta, -sin_theta, 0,
131 sin_theta, cos_theta, 0,
136 template <
typename Scalar,
class Exp>
139 assert(axis->
size() >= 3);
141 Scalar cos_theta_over_2 = q[0];
142 *angle = Scalar(2.0) * std::atan2(sin_theta_over_2, cos_theta_over_2);
145 *axis = Scalar(1.0) / sin_theta_over_2 *
fiber::Rows(q, 1, 3);
151 template <
typename Scalar,
class Exp>
154 assert(R->
size() >= 9);
155 assert(R->
rows() >= 3);
156 assert(R->
cols() >= 3);
160 (*R)(0, 0) = q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3];
161 (*R)(1, 0) = 2 * q[1] * q[2] + 2 * q[0] * q[3];
162 (*R)(2, 0) = 2 * q[1] * q[3] - 2 * q[0] * q[2];
163 (*R)(0, 1) = 2 * q[1] * q[2] - 2 * q[0] * q[3];
164 (*R)(1, 1) = q[0] * q[0] - q[1] * q[1] + q[2] * q[2] - q[3] * q[3];
165 (*R)(2, 1) = 2 * q[2] * q[3] + 2 * q[0] * q[1];
166 (*R)(0, 2) = 2 * q[1] * q[3] + 2 * q[0] * q[2];
167 (*R)(1, 2) = 2 * q[2] * q[3] - 2 * q[0] * q[1];
168 (*R)(2, 2) = q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3];
171 template <
typename Scalar,
class Exp>
174 assert(R.
size() >= 9);
175 assert(R.
rows() >= 3);
176 assert(R.
cols() >= 3);
177 const Scalar r11 = R(0, 0);
178 const Scalar r12 = R(0, 1);
179 const Scalar r13 = R(0, 2);
180 const Scalar r21 = R(1, 0);
181 const Scalar r22 = R(1, 1);
182 const Scalar r23 = R(1, 2);
183 const Scalar r31 = R(2, 0);
184 const Scalar r32 = R(2, 1);
185 const Scalar r33 = R(2, 2);
189 if (r22 > -r33 && r11 > -r22 && r11 > -r33) {
190 const Scalar k = std::sqrt(1 + r11 + r22 + r33);
191 (*q)[0] = Scalar(0.5) * k;
192 (*q)[1] = -Scalar(0.5) * (r23 - r32) / k;
193 (*q)[2] = -Scalar(0.5) * (r31 - r13) / k;
194 (*q)[3] = -Scalar(0.5) * (r12 - r21) / k;
195 }
else if (r22 < -r33 && r11 > r22 && r11 > r33) {
196 const Scalar k = std::sqrt(1 + r11 - r22 - r33);
197 (*q)[0] = Scalar(0.5) * (r23 - r32) / k;
198 (*q)[1] = -Scalar(0.5) * k;
199 (*q)[2] = -Scalar(0.5) * (r12 + r21) / k;
200 (*q)[3] = -Scalar(0.5) * (r31 + r13) / k;
201 }
else if (r22 > r33 && r11 < r22 && r11 < -r33) {
202 const Scalar k = std::sqrt(1 - r11 + r22 - r33);
203 (*q)[0] = Scalar(0.5) * (r31 - r13) / k;
204 (*q)[1] = -Scalar(0.5) * (r21 + r12) / k;
205 (*q)[2] = -Scalar(0.5) * k;
206 (*q)[3] = -Scalar(0.5) * (r23 + r32) / k;
207 }
else if (r22 < r33 && r11 < -r22 && r11 < r33) {
208 const Scalar k = std::sqrt(1 - r11 - r22 + r33);
209 (*q)[0] = Scalar(0.5) * (r12 - r21) / k;
210 (*q)[1] = -Scalar(0.5) * (r31 + r13) / k;
211 (*q)[2] = -Scalar(0.5) * (r23 + r32) / k;
212 (*q)[3] = -Scalar(0.5) * k;
234 template <
typename Scalar,
int Axis1,
int Axis2,
int Axis3>
240 template <
typename Scalar>
246 (*angles)[0] = std::atan2(2 * q[1] * q[2] - 2 * q[0] * q[3],
247 2 * q[1] * q[3] + 2 * q[0] * q[2]);
249 std::acos(q[1] * q[1] + q[0] * q[0] - q[3] * q[3] - q[2] * q[2]);
250 (*angles)[2] = std::atan2(2 * q[1] * q[2] + 2 * q[0] * q[3],
251 -2 * q[1] * q[3] + 2 * q[0] * q[2]);
255 template <
typename Scalar>
262 std::atan2(-2 * q[1] * q[2] + 2 * q[0] * q[3],
263 q[1] * q[1] + q[0] * q[0] - q[3] * q[3] - q[2] * q[2]);
264 (*angles)[1] = std::asin(2 * q[1] * q[3] + 2 * q[0] * q[2]);
266 std::atan2(-2 * q[2] * q[3] + 2 * q[0] * q[1],
267 q[3] * q[3] - q[2] * q[2] - q[1] * q[1] + q[0] * q[0]);
271 template <
typename Scalar>
278 std::atan2(2 * q[2] * q[3] + 2 * q[0] * q[1],
279 q[3] * q[3] - q[2] * q[2] - q[1] * q[1] + q[0] * q[0]);
280 (*angles)[1] = -std::asin(2 * q[1] * q[3] - 2 * q[0] * q[2]);
282 std::atan2(2 * q[1] * q[2] + 2 * q[0] * q[3],
283 q[1] * q[1] + q[0] * q[0] - q[3] * q[3] - q[2] * q[2]);
287 template <
typename Scalar>
293 (*angles)[0] = std::atan2(2 * q[1] * q[3] - 2 * q[0] * q[2],
294 2 * q[2] * q[3] + 2 * q[0] * q[1]);
296 std::acos(q[3] * q[3] - q[2] * q[2] - q[1] * q[1] + q[0] * q[0]);
297 (*angles)[2] = std::atan2(2 * q[1] * q[3] + 2 * q[0] * q[2],
298 -2 * q[2] * q[3] + 2 * q[0] * q[1]);
304 template<
typename Scalar,
int Axis1,
int Axis2,
int Axis3>
317 #endif // FIBER_ROTATION_CONVERSIONS_H_
static void Build(const Quaternion< Scalar > &q, Angles< Scalar, _3, _2, _1 > *angles)
void EulerAnglesToQuaternion(const euler::Angles< Scalar, Axis1, Axis2, Axis3 > &euler, Quaternion< Scalar > *q)
void QuaternionToAxisAngle(const Quaternion< Scalar > &q, fiber::_LValue< Scalar, Exp > *axis, Scalar *angle)
_CrossMatrix< Scalar, Exp > CrossMatrix(_RValue< Scalar, Exp > const &A)
cross-product matrix of a vector
construction euler angles from quaternion, only certain sequences can be constructed this way ...
expression template for rvalues
const AxisType & GetAxis() const
void QuaternionToRotationMatrix(const Quaternion< Scalar > &q, fiber::_LValue< Scalar, Exp > *R)
void CoordinateAxisAngleToRotationMatrix(const CoordinateAxisAngle< Scalar, Axis > &axis_angle, _LValue< Scalar, Exp > *R)
static void Build(const Quaternion< Scalar > &q, Angles< Scalar, _1, _2, _3 > *angles)
static void Build(const Quaternion< Scalar > &q, Angles< Scalar, _3, _1, _3 > *angles)
void AxisAngleToQuaternion(const fiber::_RValue< Scalar, Exp > &axis, const Scalar angle, Quaternion< Scalar > *q)
static void Build(const Quaternion< Scalar > &q, Angles< Scalar, _1, _2, _1 > *angles)
Scalar Norm(_RValue< Scalar, Exp > const &A)
Return the 2-norm of a vector.
void CoordinateAxisAngleToQuaternion(const CoordinateAxisAngle< Scalar, Axis > &axis_angle, Quaternion< Scalar > *q)
void RotationMatrixToQuaternion(const fiber::_RValue< Scalar, Exp > &R, Quaternion< Scalar > *q)
A N x N matrix expression for the identity matrix.
LView< Scalar, Exp, rows, Exp::COLS_ > Rows(_LValue< Scalar, Exp > &A, int i)
_Transpose< Scalar, Exp > Transpose(_RValue< Scalar, Exp > const &A)
expression template for rvalues
A vector of euler angles.
An axis angle rotation about a coordinate axis.
Encodes a rotation in 3-dimensions by an return RView<Scalar, Exp, rows, Exp::COLS>(static_cast<Exp c...
void AxisAngleToRotationMatrix(const AxisAngle< Scalar > &axis_angle, _LValue< Scalar, Exp > *R)