BABYLON.Tools: 'could be great to be able to clamp radians

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.

Do you fancy creating a PR in math.scalar.ts ???

I don’t know anything about Typescript :smiley:

Actually why -2pi and 2pi and not only -Pi and Pi ???

I’m not sure why, trigo make my brain shutting down.

1 Like

Hi @sebavan I can make the PR if you want, maybe we should call the method “normalize” ?

2Pi because we want to subtract full rotation (360°) ?

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


Sorry I’m not sure how to explain better :nerd_face:

but -2pi to 2pi is 720 :slight_smile:

if the range makes it faster to compute, i am all in and agree on normalize but the main point :slight_smile:
we already have it :slight_smile:

/**
     * 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;
    } 

in Math.Scalar :slight_smile:

2 Likes

@sebavan :joy:

OK :smiley: So it’s BABYLON.Scalar and not BAYLON.Tools, noted !

But I’m not sure it will works on negative radians btw…

Might create a PR for this then :slight_smile:

Ok I will add the negative radian case + make some tests to see the fastest.

1 Like

@sebavan should I add a static method to Vector3 too ?

yup could do :slight_smile: