opengl-tutorials/ogl

Angle calculation in RotationBetweenVectors

Closed this issue · 2 comments

I don't quite get it, why in RotationBetweenVectors, the cosine of the angle is calculated as s * 0.5f. The following is the relevant code, copied from the function:

	float s = sqrt( (1+cosTheta)*2 );
	float invs = 1 / s;

	return quat(
		s * 0.5f, 
		rotationAxis.x * invs,
		rotationAxis.y * invs,
		rotationAxis.z * invs
	);

Why is it not quat(cosTheta * 0.5f, rotationAxis * sin(acos(cosTheta)) * 0.5f)?

According to the explainations and the tool in [1], I would have thought that would be the way to go.

[1] Interactive quaternion exploration and learning tool by 3blue1brown and Ben Eater: https://eater.net/quaternions/video/intro

Okay, I was able to find out by myself.

I've read "The Shortest Arc Quaternion" in Game Programming Gems 1 by Stan Melax which this implementation is based on. There he states: "[...]the cross product [...] becomes small and potentially unstable when we try to normalize it[...]" and provides the solution which is numerically stable, resulting in the formulae used in the implementation of RotationBetweenVectors.

This, however, brings me to another question: The implementation provided by Stan Melax does not suggest to use case differentiations like if (cosTheta < -1 + 0.001f). So, are these really neccessary?

Okay, I've tried it. It really is a problem. Your code is great! Thank you. This issue is closed.