[solved] Rotation - angle float to degrees

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
dprojects
Posts: 722
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

[solved] Rotation - angle float to degrees

Post by dprojects »

I came across this problem again. Once it was in case of BOM constraints report, the constraints angles are stored as float. But I solved it somehow. And now it comes again in more serious way ;-)

The 15 degrees is returned as float: 0.2617993877991499
But 3 * this value will not give me perfect 45 angle (there is little offset if I rotate object around, this will not return to 0 angle).

The solution would be

Code: Select all

.Placement.Rotation.getYawPitchRoll()
but looks like it is buggy? because for

Code: Select all

FreeCAD.Rotation(0.0, 140.0, 0.0)
it returns:

Code: Select all

(180.0, 40.000000000000014, 180.0)
what is far away from 140 degree angle. For other axis X, Z the getYawPitchRoll return angle in degrees correctly.

Looks like this is not possible at FreeCAD to add 15 degree to the existing angle? Yes you can set 30 degrees angle but how to get angle in degrees and add to this value 15 degrees to get prefect angle?
Last edited by dprojects on Sun Jun 19, 2022 5:50 pm, edited 1 time in total.

Thanks
Darek
github.com/dprojects

workbench for woodworking is available at: github.com/dprojects/Woodworking
User avatar
onekk
Veteran
Posts: 6197
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Rotation - angle float to degrees

Post by onekk »

Code: Select all

help(FreeCAD.Rotation)
Probably should gave some hints.

There are some quirks if I remember well there was some time ago some discussion about rotation angles and the 24 or nore way to specify.

there is some spec in the source code but I'm using memory as I'm on mobile so not 100% sure.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
TheMarkster
Veteran
Posts: 5508
Joined: Thu Apr 05, 2018 1:53 am

Re: Rotation - angle float to degrees

Post by TheMarkster »

import math
>>> math.radians(15)
0.2617993877991494

>>> math.degrees(math.radians(15))
14.999999999999998

>>> round(math.degrees(math.radians(15)),5)
15.0
edwilliams16
Veteran
Posts: 3179
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Rotation - angle float to degrees

Post by edwilliams16 »

dprojects wrote: Sun Jun 19, 2022 1:28 pm
The solution would be

Code: Select all

.Placement.Rotation.getYawPitchRoll()
but looks like it is buggy? because for

Code: Select all

FreeCAD.Rotation(0.0, 140.0, 0.0)
it returns:

Code: Select all

(180.0, 40.000000000000014, 180.0)
what is far away from 140 degree angle. For other axis X, Z the getYawPitchRoll return angle in degrees correctly.

Looks like this is not possible at FreeCAD to add 15 degree to the existing angle? Yes you can set 30 degrees angle but how to get angle in degrees and add to this value 15 degrees to get prefect angle?
It isn't a bug. As @TheMarkster pointed out, internally angles are in radians - the process of conversion back and forth is subject to machine floating point precision.

Point #2. Start with plain 2D angles. Rotating an object by 90 or 450 or -270 degrees all give rise to the same result, so map to the same rotation operator. But what about the inverse? Given a rotation, what angle gave rise to it? There's an infinity of possible answers, so a convention is required to pick one. I'm guessing 0 <= angle < 360, but I haven't checked.

In 3D, the inverse of yaw-pitch-roll is even more ambiguous, all three angles have to bracketed by conventions. My guess for pitch is that it is 0 <=pitch < 180, but again, I haven't checked. So your YPR = (0, 140, 0) is a valid input, but when read back you get (180, 40, 180), which is the identical rotation, but is the one of the infinite number of choices that satisfies FreeCAD's choice of convention.

Stripped down to the bare mathematical essential, if you have a function y = f(x), where multiple values of x give the same value of y, then you can't define an inverse function x = finv(y) without a prescription for choosing which root of f(x) = y is to represented.
User avatar
dprojects
Posts: 722
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

Re: Rotation - angle float to degrees

Post by dprojects »

edwilliams16 wrote: Sun Jun 19, 2022 5:13 pm YPR = (0, 140, 0) is a valid input, but when read back you get (180, 40, 180), which is the identical rotation
I am not expert of rotation, for me it looks like bug because I was able to rotate panel at X axis surface and at Z axis surface around and get 0 degree (starting point) but for Y when it goes to around 100 degree it stops and starting add strange numbers. Also there are some -1 values at axis, something like -1,0,-1 but the problem with rotation and wrong (in my opinion return for this function) was only in case of Y.

From development perspective it would be much better to have simple functions like toAngle() and toFloat() and I am surprised they don't exists if the angle is stored as float. For me this is strange.

Also from development perspective I don't see any reason to keep float for angle from 0 to around 6.4 instead of 0 to 360. The 0 to 6.4 could be hidden in FreeCAD engine if needed somewhere but I don't get it why it is exposed to API. Maybe there is other reason but for me it is complicated without reason.

EDIT:

Also I observe not first time values like this:

Code: Select all

40.000000000000014
instead of 40 or 40.0. Something must be deeply wrong.
Last edited by dprojects on Sun Jun 19, 2022 5:58 pm, edited 1 time in total.

Thanks
Darek
github.com/dprojects

workbench for woodworking is available at: github.com/dprojects/Woodworking
User avatar
dprojects
Posts: 722
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

Re: Rotation - angle float to degrees

Post by dprojects »

TheMarkster wrote: Sun Jun 19, 2022 4:04 pm import math
>>> math.radians(15)
0.2617993877991494

>>> math.degrees(math.radians(15))
14.999999999999998

>>> round(math.degrees(math.radians(15)),5)
15.0
Thanks TheMarkster, this is the only choice to write it like this ;-(

Thanks
Darek
github.com/dprojects

workbench for woodworking is available at: github.com/dprojects/Woodworking
User avatar
onekk
Veteran
Posts: 6197
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: [solved] Rotation - angle float to degrees

Post by onekk »

Nite that accepting TheMarkster solution you simply apply a correction to result.

As angles are stored as float in radians, you are subject to the infamous but omni oresent ieee floating point precision "problem".

So it is a simple problem of point of view.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
User avatar
dprojects
Posts: 722
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

Re: [solved] Rotation - angle float to degrees

Post by dprojects »

The funny part is that at FreeCAD GUI property box it says it is degree, is visible as float 15,00 but is increased +1,00, so what the float is for there? and the most funny part, you can add angle -1760 or 2333 and this will be accepted and rotated, so there also need to be recalculation to 360 ;-) LOL epic

As I remember the function Placement.rotate() worked fine but it works only for Cubes. There is also something like .Rotation.setYawPitchRoll() but I am not sure if this recalculate 360 to 0 degree, and it also needs X,Y, Z angles but the .Rotation.getYawPitchRoll() is not reliable here for Y axis ;-(

EDIT:

There is also issue that by default Cube has 0,0,1 axis vector for rotation and if you want to start rotate for X axis this will be rotated by default with X and Z ;-) you can reset it but what if there was custom rotation for Z?

Thanks
Darek
github.com/dprojects

workbench for woodworking is available at: github.com/dprojects/Woodworking
User avatar
onekk
Veteran
Posts: 6197
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: [solved] Rotation - angle float to degrees

Post by onekk »

you must take in account if you see some documentation that placement and rotation has several ways to be specified.

Rotation could also be specified as quaternions (4 floats) and with one string and three float (Euler angles that has not a unique way to be specified, as there is also the "order of application" to be taken in account).

In the source code there are some interesting comments if I remember well.

help(Rotation) is a very interesting reading.


Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
edwilliams16
Veteran
Posts: 3179
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Rotation - angle float to degrees

Post by edwilliams16 »

dprojects wrote: Sun Jun 19, 2022 5:43 pm
From development perspective it would be much better to have simple functions like toAngle() and toFloat() and I am surprised they don't exists if the angle is stored as float. For me this is strange.
OK. Let's be more specific. Angles are not stored at all, as float or anything else. When you construct a rotation - and if you look at the API, there are many ways to do this - the code computes a quaternion representation. This encodes in four floating point numbers the axis and angle of rotation.
If you query the rotation, you can get the output in many different forms
Axis and Angle
Yaw-Pitch-Roll
Quaternion
4*4 Affine Matrix
These quantities are computed from the stored quaternion representation.

So if you create a rotation from Axis and Angle, it is converted to quaternion form. If you then read back the Angle property of the Rotation, it is computed from the quaternions. This back and forth conversion is subject to floating point error, so you can't expect to get back exactly what you put in.

EDIT:

Also I observe not first time values like this:

Code: Select all

40.000000000000014
instead of 40 or 40.0. Something must be deeply wrong.
Rubbish. Unless you think that the problem with computers is that they don't have the infinite memory required to encode pi.
Post Reply