Sometimes, especially in arcRotateCamera animations, you want to clamp radians before animating, to avoid multiple 360° turning around.
Usecase: your user arcRotCam alpha == 22, but in your animation when clicking an object you’ve targetted alpha = 1 > cmaera will start to turn multiple times.
Actually I already use a snippet for that:
function clampRadian(radianValue) {
var cyclesNumber;
// help thanks to http://www.purplemath.com/modules/radianValueians2.htm
if (radianValue < (-2 * Math.PI) || radianValue > (2 * Math.PI)) {
if (radianValue >= 0) {
cyclesNumber = Math.floor(radianValue / (2 * Math.PI));
} else {
cyclesNumber = Math.ceil(radianValue / (2 * Math.PI));
}
radianValue = radianValue - (cyclesNumber * (2 * Math.PI));
}
return radianValue;
}
function clampVector(vector3) {
return BABYLON.Vector3.FromArray([
clampRadians(vector3.x),
clampRadians(vector3.y),
clampRadians(vector3.z),
]);
}
(I hope my maths are OK here)
In short, it could be great to have a BABYLON.Tools.clampRadians(Vector3) or BABYLON.Tools.clampRadian(radian value) so as to get values between -2 * Math.PI & 2 * Math.PI only.
Yep actually this is the logic: we detect how many turn on the trigo circle user have made, and also in which direction, that’s why range here is set to -2PI <> +2PI.
For example, if user do anti-clockwise one turn + 1 radian on camera alpha value, it will be equal to -1-(2*Math.PI) = -7.283185307179586, we can clamp this value but still be able to detect on which direction the user is.
These 2 rad values are in the “same place” in the PI circle: clampRadian(-7.283185307179586) = -1 // user have done 1 turn around anti-clockwise clampRadian(-58.26548245743669) = -1 // user have done 8 turns around anti-clockwise
clampRadian(7.283185307179586) = 1 // user have done 1 turn around clockwise
if the range makes it faster to compute, i am all in and agree on normalize but the main point
we already have it
/**
* Returns the angle converted to equivalent value between -Math.PI and Math.PI radians.
* @param angle The angle to normalize in radian.
* @return The converted angle.
*/
public static NormalizeRadians(angle: number): number {
// More precise but slower version kept for reference.
// angle = angle % Tools.TwoPi;
// angle = (angle + Tools.TwoPi) % Tools.TwoPi;
//if (angle > Math.PI) {
// angle -= Tools.TwoPi;
//}
angle -= (Scalar.TwoPi * Math.floor((angle + Math.PI) / Scalar.TwoPi));
return angle;
}