Rotate a vector with a quaternion#
Build a unit quaternion and use it to rotate a vector 90 degrees.
Time: ~2 min · Runs on: CPU · You need: Quaternions
running on: cpu
A quaternion is stored in a plain aether::Vec4d, in (w, x, y, z)
order. .quatRotate(v) applies it to a Vec3d, one method call:
A rotation by angle theta about an axis uses the half-angle: w = cos(theta/2), and the axis scaled by sin(theta/2) fills (x, y, z).
For 90 degrees about z, that is (cos 45, 0, 0, sin 45), and it must
send (1, 0, 0) to (0, 1, 0):
print(run_cpp(r"""
using aether::Vec3d;
using aether::Vec4d;
const double half_angle = std::numbers::pi / 4.0; // 90 deg rotation
Vec4d q{std::cos(half_angle), 0.0, 0.0, std::sin(half_angle)};
Vec3d v{1.0, 0.0, 0.0};
Vec3d rotated = q.quatRotate(v);
std::printf("rotated = (%.3e, %.6f, %.6f)\n", rotated(0), rotated(1), rotated(2));
""", includes=("<cmath>", "<numbers>")))
rotated = (2.220e-16, 1.000000, 0.000000)
Expected: (0, 1, 0). The tiny nonzero first component above (around
machine epsilon, 2e-16) is floating-point reassociation noise –
rounding error from the order .quatRotate’s internal sandwich
product, q * (0, v) * q^-1, does its multiplications in, not a bug;
see the tolerance note in Quaternions.