21#include <Eigen/Geometry>
59 [[nodiscard]]
static constexpr Eigen::Index
75 template <
typename Derived>
79 using T =
typename Derived::Scalar;
81 for (Eigen::Index j = 0; j < q.cols(); ++j)
83 T
const sign = q(3, j) < T(0) ? T(-1) : T(1);
84 q.col(j) *= sign / q.col(j).norm();
91 template <
typename X,
typename D,
typename Out>
93 plus(Eigen::MatrixBase<X>
const & x, Eigen::MatrixBase<D>
const & d, Eigen::MatrixBase<Out>
const & out)
const
95 using T =
typename Out::Scalar;
97 for (Eigen::Index j = 0; j < o.cols(); ++j)
99 o.col(j) = (quaternionOf<T>(x.col(j)) *
exponential(d.col(j).template cast<T>())).coeffs();
107 template <
typename A,
typename B,
typename Out>
109 minus(Eigen::MatrixBase<A>
const & a, Eigen::MatrixBase<B>
const & b, Eigen::MatrixBase<Out>
const & out)
const
111 using T =
typename Out::Scalar;
113 for (Eigen::Index j = 0; j < o.cols(); ++j)
115 o.col(j) =
logarithm(quaternionOf<T>(b.col(j)).conjugate() * quaternionOf<T>(a.col(j)));
122 template <
typename X,
typename D,
typename Out>
125 Eigen::MatrixBase<X>
const &,
126 Eigen::MatrixBase<D>
const & d,
127 Eigen::MatrixBase<Out>
const & out
130 using T =
typename Out::Scalar;
140 template <
typename Derived>
141 [[nodiscard]]
static Eigen::Quaternion<typename Derived::Scalar>
144 using T =
typename Derived::Scalar;
145 T
const angle2 = d.squaredNorm();
146 if (angle2 < T(1e-12))
148 T
const scale = T(0.5) - angle2 / T(48);
149 return Eigen::Quaternion<T>{T(1) - angle2 / T(8), d(0) * scale, d(1) * scale, d(2) * scale};
151 T
const angle = Eigen::numext::sqrt(angle2);
152 T
const scale = T(Eigen::numext::sin(T(angle / T(2))) / angle);
153 return Eigen::Quaternion<T>{Eigen::numext::cos(T(angle / T(2))), d(0) * scale, d(1) * scale, d(2) * scale};
159 template <
typename Derived>
160 [[nodiscard]]
static Eigen::Matrix<typename Derived::Scalar, 3, 1>
163 using T =
typename Derived::Scalar;
164 T
const sign = q.w() < T(0) ? T(-1) : T(1);
165 T
const w = sign * q.w();
166 Eigen::Matrix<T, 3, 1>
const v = sign * q.vec();
167 T
const s2 = v.squaredNorm();
170 return v * T(T(2) / w);
172 T
const s = Eigen::numext::sqrt(s2);
173 T
const angle = T(2) * Eigen::numext::atan2(s, w);
174 return v * T(angle / s);
185 template <
typename Derived>
186 [[nodiscard]]
static Eigen::Matrix<typename Derived::Scalar, 3, 3>
189 using T =
typename Derived::Scalar;
190 auto skew = Eigen::Matrix<T, 3, 3>{};
191 skew << T(0), -d(2), d(1), d(2), T(0), -d(0), -d(1), d(0), T(0);
192 T
const angle2 = d.squaredNorm();
193 if (angle2 < T(1e-8))
195 return Eigen::Matrix<T, 3, 3>::Identity() - T(0.5) * skew + (skew * skew) / T(6);
197 T
const angle = Eigen::numext::sqrt(angle2);
198 return Eigen::Matrix<T, 3, 3>::Identity() - T((T(1) - Eigen::numext::cos(angle)) / angle2) * skew
199 + T((angle - Eigen::numext::sin(angle)) / (angle2 * angle)) * (skew * skew);
205 template <
typename Scalar =
double>
206 [[nodiscard]]
static Eigen::Matrix<Scalar, 4, 1>
209 return Eigen::Matrix<Scalar, 4, 1>{Scalar(0), Scalar(0), Scalar(0), Scalar(1)};
216 template <
typename Derived>
217 [[nodiscard]]
static Eigen::Matrix<typename Derived::Scalar, 4, 1>
238 template <
typename Block>
239 [[nodiscard]]
static auto
242 using Derived = std::remove_cvref_t<Block>;
245 Derived::ColsAtCompileTime == 1
246 && (Derived::RowsAtCompileTime == 4 || Derived::RowsAtCompileTime == Eigen::Dynamic),
247 "map() takes one column of four coordinates (x, y, z, w)"
250 (Derived::Flags & Eigen::DirectAccessBit) && Derived::InnerStrideAtCompileTime == 1,
251 "map() needs coefficients in memory with unit stride; evaluate the expression first"
254 std::is_lvalue_reference_v<Block> || !std::derived_from<Derived, Eigen::PlainObjectBase<Derived>>,
255 "map() of a temporary matrix would dangle; store it first"
257 EMRYS_FILTER_ASSERT(
block.size() == 4 &&
"a unit quaternion has four coordinates");
258 using Scalar =
typename Derived::Scalar;
259 if constexpr (!std::is_const_v<std::remove_reference_t<Block>> && bool(Derived::Flags & Eigen::LvalueBit))
261 return Eigen::Map<Eigen::Quaternion<Scalar>>{
block.derived().data()};
265 return Eigen::Map<Eigen::Quaternion<Scalar>
const>{
block.derived().data()};
275 template <
typename T,
typename Derived>
276 [[nodiscard]]
static Eigen::Quaternion<T>
277 quaternionOf(Eigen::MatrixBase<Derived>
const & coefficients)
279 Eigen::Matrix<T, 4, 1>
const fixed = coefficients.template cast<T>();
280 return Eigen::Quaternion<T>{fixed};
The coordinate types (decisions.md [no-bounded-coordinates]): Linear, plain coordinates,...
How a function that stores a matrix argument takes it (decisions.md [forwarded-matrices]): the concep...
The macros every header includes first.
The Space concept and what every continuous space shares (decisions.md [sizes-and-dimensions]): the t...
A dense matrix or matrix expression, possibly cv- or reference-qualified: what a const Eigen::MatrixB...
Definition Forwarding.h:39
Eigen::MatrixBase< Derived > & writable(Eigen::MatrixBase< Derived > const &block)
block, writable: Eigen's idiom for a function that writes through an expression passed as const&.
Definition Space.h:389
auto block(Space auto const &space, X &&x)
Definition TagPath.h:979
Dimension_ plain coordinates, or a resizable run of at most MaxDimension_ of them if Dimension_ is Ei...
Definition Coordinates.h:87
An attitude: a unit quaternion of four coordinates whose differences are three-coordinate rotation ve...
Definition UnitQuaternion.h:53
static constexpr Eigen::Index valueDimension()
Definition UnitQuaternion.h:60
static Eigen::Matrix< typename Derived::Scalar, 4, 1 > coefficientsOf(Eigen::QuaternionBase< Derived > const &q)
Definition UnitQuaternion.h:218
friend bool operator==(UnitQuaternion const &, UnitQuaternion const &)=default
Spaces compare equal: a UnitQuaternion has no parameters.
static auto map(Block &&block)
Definition UnitQuaternion.h:240
static Eigen::Matrix< Scalar, 4, 1 > identity()
Definition UnitQuaternion.h:207
static Eigen::Matrix< typename Derived::Scalar, 3, 3 > rightJacobian(Eigen::MatrixBase< Derived > const &d)
Definition UnitQuaternion.h:187
static Eigen::Quaternion< typename Derived::Scalar > exponential(Eigen::MatrixBase< Derived > const &d)
Definition UnitQuaternion.h:142
static constexpr int ValueDimensionStep
not resizable
Definition UnitQuaternion.h:55
static constexpr int MaxValueDimension
the value dimension, as for any fixed space
Definition UnitQuaternion.h:56
void minus(Eigen::MatrixBase< A > const &a, Eigen::MatrixBase< B > const &b, Eigen::MatrixBase< Out > const &out) const
Writes through out, column by column.
Definition UnitQuaternion.h:109
static constexpr int FixedValueDimension
four coordinates, (x, y, z, w)
Definition UnitQuaternion.h:54
static Eigen::Matrix< typename Derived::Scalar, 3, 1 > logarithm(Eigen::QuaternionBase< Derived > const &q)
Definition UnitQuaternion.h:161
void plus(Eigen::MatrixBase< X > const &x, Eigen::MatrixBase< D > const &d, Eigen::MatrixBase< Out > const &out) const
Writes through out, column by column, normalized.
Definition UnitQuaternion.h:93
Linear< 3 > difference() const
Definition UnitQuaternion.h:67
void resetJacobian(Eigen::MatrixBase< X > const &, Eigen::MatrixBase< D > const &d, Eigen::MatrixBase< Out > const &out) const
Writes the reset Jacobian at the step d through out: rightJacobian() of d, whatever the value.
Definition UnitQuaternion.h:124
void normalize(Eigen::MatrixBase< Derived > const &block) const
Scales each column of block, a value (x, y, z, w) per column, to unit norm with , writing through the...
Definition UnitQuaternion.h:77