## Converting from a different rotation system.

Need help, or want to share a macro? Post here!
keithsloan52
Posts: 1859
Joined: Mon Feb 27, 2012 5:31 pm

### Converting from a different rotation system.

I am trying to deal with some software that specifies rotation as x=<value> y=<value> z=<value>, where the values are passes as either degrees or radians ( Different parameter). As it is possible for more than one axis to be specified the order is important and this system does x rotation, then y, then z. What is the best way to go from the three values x,y,z to a FreeCAD placement rotation? Do I have to go via three separate rotations?

Having created a FreeCAD placement rotation, I also need to be able to go the other way. Thanks
openBrain
Posts: 5784
Joined: Fri Nov 09, 2018 5:38 pm

### Re: Converting from a different rotation system.

Is your system using XYZ or XY'Z''? Ie. does it use extrinsic or intrinsic angles?
You can create the rotation with

Code: Select all

``App.Rotation(angleX, angleY, angleZ)``
In the other direction :

Code: Select all

``rotation.toEuler()``
keithsloan52
Posts: 1859
Joined: Mon Feb 27, 2012 5:31 pm

### Re: Converting from a different rotation system.

openBrain wrote: Fri Feb 05, 2021 2:37 pm Is your system using XYZ or XY'Z''? Ie. does it use extrinsic or intrinsic angles?
You can create the rotation with

Code: Select all

``App.Rotation(angleX, angleY, angleZ)``
In the other direction :

Code: Select all

``rotation.toEuler()``
If FreeCAD uses intrinsic, do I have to set a Direction Axis? or does App.Rotation(anglesX, anglesY, anglesZ) sort things out using a default direction Axis?
openBrain
Posts: 5784
Joined: Fri Nov 09, 2018 5:38 pm

### Re: Converting from a different rotation system.

App.Rotation is pure rotation. There is no direction in this at all.
keithsloan52
Posts: 1859
Joined: Mon Feb 27, 2012 5:31 pm

### Re: Converting from a different rotation system.

openBrain wrote: Fri Feb 05, 2021 3:00 pm App.Rotation is pure rotation. There is no direction in this at all.
Not working for me, having to resort to

Code: Select all

``````        rotX = FreeCAD.Rotation(FreeCAD.Vector(1,0,0), -x)

rot = rotX.multiply(rotY).multiply(rotZ)
``````
if I code

Code: Select all

`````` placement = FreeCAD.Placement(base, FreeCAD.Rotation(-x,-y,-z))
``````
I don't get a correct result.

Also I need to be able to go the other way i.e. Rotation to x,y,z angles
If I use rotation.toEuler() it gives the right result for some objects but not for others
Last edited by keithsloan52 on Fri Feb 05, 2021 6:52 pm, edited 1 time in total.
openBrain
Posts: 5784
Joined: Fri Nov 09, 2018 5:38 pm

### Re: Converting from a different rotation system.

I wonder if FreeCAD is waiting angles in yaw/pitch/roll order even if they are not applied in this order.
Could you try

Code: Select all

``FreeCAD.Rotation(-z,-y,-x)``
keithsloan52
Posts: 1859
Joined: Mon Feb 27, 2012 5:31 pm

### Re: Converting from a different rotation system.

openBrain wrote: Fri Feb 05, 2021 5:47 pm I wonder if FreeCAD is waiting angles in yaw/pitch/roll order even if they are not applied in this order.
Could you try

Code: Select all

``FreeCAD.Rotation(-z,-y,-x)``
This gives the same result as I am getting with using individual rotations on import- all look okay, Euler to output angles and then importing again. i.e. Some objects are okay others not.
ickby
Posts: 3054
Joined: Wed Oct 05, 2011 7:36 am

### Re: Converting from a different rotation system.

Rotation representaitions are a mathematical hell for a engineer like me, but I think the issue you facing is one of reference frames. When multiplying rotation matrices you use a fixed reference frame for the rotations. However, the euler angles in freecad are defined in the xy'z'' notation, which uses a internal reference frame attached to the moving body. So two totally different thing and hence you cannot compare the results (except for some lucky cases)

For visualisation: Using rotation matrices is like always using the global CS. You rotate around global X, than global Y etc. When using the euler angle you start of using global X, but this one rotation also rotates the CS. Hence Y is at annother direction. You use this new direction and rotate around that. Same for Z.
onekk
Posts: 816
Joined: Sat Jan 17, 2015 7:48 am
Contact:

### Re: Converting from a different rotation system.

When specificing three values for rotation FreeCAD is usign euler angles,

It describes roughly the several way to specify a rotation:

under Yaw-Pitch and Roll it show this example

Code: Select all

``````App.getDocument("Sans_nom").Cylinder.Placement=App.Placement(App.Vector(0,0,0), App.Rotation(10,20,30), App.Vector(0,0,0))
``````
Not said tthe third Vector is the center of rotation, but not everytime is consistent to what you are thinking,

in complicated case, is better to use multiply or even better:

Code: Select all

``````def do_rotate(doc, obj, angx, angy, angz, rotC):
"""Rotate an object using transformation matrix"""
ptn = Vector(rotC.x * -1, rotC.y * -1,rotC.z * -1)
m = obj.Placement.Matrix
m.move(ptn)
m.rotateX(angx)
m.rotateY(angy)
m.rotateZ(angz)
m.move(rotC)
obj.Placement.Matrix = m
``````
This code is used somewhere in FreeCAD sources , i don't remember weel where.

It transform the placement in a Matrix and then operate on this matrix using the matrix operations, then reassign the matrix to the object placement.

Internally FreeCAD store the Placement as a Quaternion, so it is relatively easy to convert into and back to a matrix.

Hope it helps

Regards

Carlo D.
keithsloan52
Posts: 1859
Joined: Mon Feb 27, 2012 5:31 pm

### Re: Converting from a different rotation system.

onekk wrote: Fri Feb 05, 2021 7:39 pm When specificing three values for rotation FreeCAD is usign euler angles,

It describes roughly the several way to specify a rotation:

under Yaw-Pitch and Roll it show this example

Code: Select all

``````App.getDocument("Sans_nom").Cylinder.Placement=App.Placement(App.Vector(0,0,0), App.Rotation(10,20,30), App.Vector(0,0,0))
``````
Can confirm that this is not working for some Objects

Not said tthe third Vector is the center of rotation, but not everytime is consistent to what you are thinking,

in complicated case, is better to use multiply or even better:

Code: Select all

``````def do_rotate(doc, obj, angx, angy, angz, rotC):
"""Rotate an object using transformation matrix"""
ptn = Vector(rotC.x * -1, rotC.y * -1,rotC.z * -1)
m = obj.Placement.Matrix
m.move(ptn)
m.rotateX(angx)
m.rotateY(angy)
m.rotateZ(angz)
m.move(rotC)
obj.Placement.Matrix = m
``````
Think is probably more neater, but essential the same as what I had coded doing a rotation for each axis in turn.

What I really still need is a way getting from am existing placement back to the three angles