From: Mikko Rasa Date: Sat, 28 Jan 2023 19:45:31 +0000 (+0200) Subject: Add a function to create a rotation quaternion from two vectors X-Git-Url: https://git.tdb.fi/?a=commitdiff_plain;h=89fe5cbfc6986d740b759066c0de7781826505ab;p=libs%2Fmath.git Add a function to create a rotation quaternion from two vectors --- diff --git a/source/geometry/quaternion.h b/source/geometry/quaternion.h index ef5504e..8a43342 100644 --- a/source/geometry/quaternion.h +++ b/source/geometry/quaternion.h @@ -22,6 +22,7 @@ struct Quaternion static Quaternion one() { return Quaternion(1, 0, 0, 0); } static Quaternion rotation(Angle, const LinAl::Vector &); + static Quaternion rotation(const LinAl::Vector &, const LinAl::Vector &); T scalar() const { return a; } LinAl::Vector vector() const { return LinAl::Vector(b, c, d); } @@ -51,6 +52,17 @@ Quaternion Quaternion::rotation(Angle angle, const LinAl::Vector return Quaternion(c, s*axis.x, s*axis.y, s*axis.z); } +template +Quaternion Quaternion::rotation(const LinAl::Vector &from, const LinAl::Vector &to) +{ + using std::sqrt; + + // https://www.xarg.org/proof/quaternion-from-two-vectors/ + LinAl::Vector axis = cross(from, to); + T c = inner_product(from, to); + return Quaternion(c+sqrt(inner_product(axis, axis)+c*c), axis.x, axis.y, axis.z).normalize(); +} + template Quaternion &Quaternion::operator+=(const Quaternion &q) {