[Scripting] Is there a reliable way to get 0-359 degree?


#1

Currently i use this, it works.

Math.round(Quat.safeEulerAngles(data.rotation).y+180);

but because hifi use default -180 to +180 the results seems to be a bit random sometimes. Or it’s something else.

But is this the most reliable way to convert the annoying -180 to +180 to 0-359 degree. i cannot really work with the -180 and +180 especially when you need to start calculate on it. Because you never know when , what and it need more code. and harder for errors to normally.

And mabye am missing just some logic and avoid it because that.
Sometimes it’s going a few script changes fine. and then your puzzle yourself crazy why the numbers got up to above 359 degree. Rerlog or domain TP sometimes fix it. so possible soemthing else wrong too.


#2

This is not right, you end up with a flipped angle.
What you need is:

var original = Quat.safeEulerAngles(data.rotation).y;
var angle = Math.round(original < 0.0 ? original + 360.0 : original);

Actually I just came up with something better if the mod works with floats in JS (Not sure about that):

Math.round((Quat.safeEulerAngles(data.rotation).y + 360.0) % 360.0); // TBT, To Be Tested

You can only add k * 360, k ∈ ℤ to angles in degrees, otherwise it’s not the same angle


#3

I go look into this tomorrow. this are things that would be good on wiki or docs. Very usefull information for people.


#4

How about:
Math.round(180.0 - Quat.safeEulerAngles(data.rotation).y);
or maybe:
-Math.round(180.0 - Quat.safeEulerAngles(data.rotation).y);
if the sign is not usable.


#5

Same, you don’t get the same angle. (i.e. for an angle of 0 degrees, you get 180 degrees)
The only possible operation the will conserve the correct value of the angle is adding/subtracting multiples of 360.


#6

What then does that say about the choice to have used -180 to 180 instead of 0 to 360?


#7

The function is inspired from that paper: http://www.geometrictools.com/Documentation/EulerAngles.pdf
That’s just how the maths turns out. That method uses trigonometric functions, mostly atan which has a [-π/2 , π/2] range.


#8

So far it looks like both work. I keep using the last one. off course i do not understand that one complete. i know waht i need to change in it for other axis.

While tuning my script i will see if it keeps working. Thanks.


#9

Works in 2 steps:

First we shift the range:
            +360
[-180, 180] =====> [180, 540]

Then we wrap the end of it thanks to the modulus operation:
            %360
[180, 360[ =====> [180, 360[
[360, 540] =====> [  0, 180]

#10

My object with script decided to rotate the other wrong direction.
I go back to your first conversion methode. mabye the second is failing now.


#11

Weird, it work in the console for me:

Are you sure your script logic is correct? eulerAngles.y is yaw and increasing the yaw will make the entity spin toward the left (ie. counter clockwise rotation if you look from above)


#12

Let me suggest that the c++ code should be doing the normalizations and should accept 0 to 360 (or 0 to 2PI) where appropriate. Wee really should not be asking all the javascripts to have to hork out adjustment code that rns at 1/10th the speed of native code.


#13

It already does, you can give 10,000,000 degrees as an angles to the interface if you want and it’ll do the right thing. Both for degrees and radians:

glm::quat fromVec3Degrees(const glm::vec3& vec3);
glm::quat fromVec3Radians(const glm::vec3& vec3);
glm::quat fromPitchYawRollDegrees(float pitch, float yaw, float roll);
glm::quat fromPitchYawRollRadians(float pitch, float yaw, float roll);

@Richardus.Raymaker wanted to know how to normalize the angle to [0, 360] for display purposes I assume after reading his script. But he doesn’t have to, he could just remove that formula from his script and it would work all the same.
But instead of displaying an angle between [0, 360], he would display it between [-180, 180].


#14

Yes you are right, my post was just a hack to show how it can be done for relative stuff. I did not know how Richardus was using it.


#15

Need to test it, but it’s debugging more eay if there’s no - and + but it’s more intressting to learn it the correct way. because for some other ideas it’s more easy.

It’s all learning, the script i make now is usefull for everybody. When it’s finished.

ADD: Just did simple test by removing all the 360 conversions so technical it’s using -180 to +180 but then things not working anymore. becaue comparing things are unreliable because you never know if it’s -180 or +180 or between it. So i stay for this function on the 359.


#16

That’s probably because of this kinds of checks:

if (currentrot>=baserot+80 && currentrot<=baserot+95 ...) {

It can cross over the edge (ie. 180).
if baserot = 90, then baserot + 80 = 170 and baserot + 95 = 5 with range [-180, 180]

But that’s still the case if you go from 0 to 360, it just moves the problem and in a different orientation you’ll encounter the same problem.
if baserot = 270, then baserot + 80 = 350 and baserot + 95 = 5 with range [0, 360]

Instead, the correct operation would be:

var threshold = 5;
var target = baserot + 90;
var signedDistance = (target - currentrot) % 360;
if (Math.abs(signedDistance) < threashold) {
    ...
} else if (-10 < signedDistance && signedDistance < 15) {

The first one will be true when currentrot gets within 5 degrees of baserot + 90.
And the second one it current rot is within 10 degrees coming from the bottom or 15 degrees coming from the top.


#17

It all works…

Also with , Math.round((Quat.safeEulerAngles(data.rotation).y + 360.0) % 360.0);