Converting from a different rotation system.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Be nice to others! Respect the FreeCAD code of conduct!
-
- Veteran
- Posts: 2764
- 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
Having created a FreeCAD placement rotation, I also need to be able to go the other way. Thanks
Re: Converting from a different rotation system.
Is your system using XYZ or XY'Z''? Ie. does it use extrinsic or intrinsic angles?
Freecad uses XY'Z''.
You can create the rotation with
In the other direction :
Freecad uses XY'Z''.
You can create the rotation with
Code: Select all
App.Rotation(angleX, angleY, angleZ)
Code: Select all
rotation.toEuler()
-
- Veteran
- Posts: 2764
- Joined: Mon Feb 27, 2012 5:31 pm
Re: Converting from a different rotation system.
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 wrote: ↑Fri Feb 05, 2021 2:37 pm Is your system using XYZ or XY'Z''? Ie. does it use extrinsic or intrinsic angles?
Freecad uses XY'Z''.
You can create the rotation withIn the other direction :Code: Select all
App.Rotation(angleX, angleY, angleZ)
Code: Select all
rotation.toEuler()
Re: Converting from a different rotation system.
App.Rotation is pure rotation. There is no direction in this at all.
-
- Veteran
- Posts: 2764
- Joined: Mon Feb 27, 2012 5:31 pm
Re: Converting from a different rotation system.
Not working for me, having to resort to
Code: Select all
rotX = FreeCAD.Rotation(FreeCAD.Vector(1,0,0), -x)
rotY = FreeCAD.Rotation(FreeCAD.Vector(0,1,0), -y)
rotZ = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), -z)
rot = rotX.multiply(rotY).multiply(rotZ)
placement = FreeCAD.Placement(base, FreeCAD.Rotation(rot))
Code: Select all
placement = FreeCAD.Placement(base, FreeCAD.Rotation(-x,-y,-z))
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.
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
Could you try
Code: Select all
FreeCAD.Rotation(-z,-y,-x)
-
- Veteran
- Posts: 2764
- Joined: Mon Feb 27, 2012 5:31 pm
Re: Converting from a different rotation system.
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.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 tryCode: Select all
FreeCAD.Rotation(-z,-y,-x)
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.
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.
Re: Converting from a different rotation system.
When specificing three values for rotation FreeCAD is usign euler angles,
See https://wiki.freecadweb.org/Placement
It describes roughly the several way to specify a rotation:
under Yaw-Pitch and Roll it show this example
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:
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.
See https://wiki.freecadweb.org/Placement
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))
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
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.
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/
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.
Blog: https://okkmkblog.wordpress.com/
-
- Veteran
- Posts: 2764
- Joined: Mon Feb 27, 2012 5:31 pm
Re: Converting from a different rotation system.
Can confirm that this is not working for some Objectsonekk wrote: ↑Fri Feb 05, 2021 7:39 pm When specificing three values for rotation FreeCAD is usign euler angles,
See https://wiki.freecadweb.org/Placement
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))
Think is probably more neater, but essential the same as what I had coded doing a rotation for each axis in turn.
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
What I really still need is a way getting from am existing placement back to the three angles