static Quaternion one() { return Quaternion(1, 0, 0, 0); }
static Quaternion rotation(Angle<T>, const LinAl::Vector<T, 3> &);
+ static Quaternion rotation(const LinAl::Vector<T, 3> &, const LinAl::Vector<T, 3> &);
T scalar() const { return a; }
LinAl::Vector<T, 3> vector() const { return LinAl::Vector<T, 3>(b, c, d); }
return Quaternion<T>(c, s*axis.x, s*axis.y, s*axis.z);
}
+template<typename T>
+Quaternion<T> Quaternion<T>::rotation(const LinAl::Vector<T, 3> &from, const LinAl::Vector<T, 3> &to)
+{
+ using std::sqrt;
+
+ // https://www.xarg.org/proof/quaternion-from-two-vectors/
+ LinAl::Vector<T, 3> axis = cross(from, to);
+ T c = inner_product(from, to);
+ return Quaternion<T>(c+sqrt(inner_product(axis, axis)+c*c), axis.x, axis.y, axis.z).normalize();
+}
+
template<typename T>
Quaternion<T> &Quaternion<T>::operator+=(const Quaternion<T> &q)
{