[solved] Rotation - how to rotate twice?
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Be nice to others! Respect the FreeCAD code of conduct!
[solved] Rotation - how to rotate twice?
Is it possible to rotate twice? for example user has custom rotation with unknown angle for Y axis and I want to rotate additionally 15 degree for X axis. Is it possible or rotation is only single rotate? For example I can rotate together 15 degree with 1,0,1 vector or 1.0.0 or 0,0,1 but never once 15 degree in 0,0,1 and than keeping the 15 degree to next 15 degree but this time for 1,0,0.
EDIT:
The .Placement.Rotation.getYawPitchRoll() return 3 angles for each axis, X, Y, Z but at the FreeCAD GUI interface is only one place for angle value. If I want to rotate X and Z I can add 15 degree and set 1,0,1. But.... if there are more rotations like this, once +15 to X once +15 to Y than +30 to Z.... how to deal with such things?
The .Placement.Rotation.getYawPitchRoll() and .Placement.Rotation.setYawPitchRoll not work here, I guess?
EDIT:
The .Placement.Rotation.getYawPitchRoll() return 3 angles for each axis, X, Y, Z but at the FreeCAD GUI interface is only one place for angle value. If I want to rotate X and Z I can add 15 degree and set 1,0,1. But.... if there are more rotations like this, once +15 to X once +15 to Y than +30 to Z.... how to deal with such things?
The .Placement.Rotation.getYawPitchRoll() and .Placement.Rotation.setYawPitchRoll not work here, I guess?
Last edited by dprojects on Wed Jun 22, 2022 7:38 pm, edited 1 time in total.
Thanks
Darek
github.com/dprojects
workbench for woodworking is available at: github.com/dprojects/Woodworking
-
- Veteran
- Posts: 3180
- Joined: Thu Sep 24, 2020 10:31 pm
- Location: Hawaii
- Contact:
Re: Rotation - how to rotate twice?
To make successive (compounded) rotations, you multiply them. See:
wiki.freecadweb.org/Sandbox:Edwilliams16#Rotations
wiki.freecadweb.org/Sandbox:Edwilliams16#Rotations
Re: Rotation - how to rotate twice?
The requested page could not be found.edwilliams16 wrote: ↑Sun Jun 19, 2022 11:20 pm To make successive (compounded) rotations, you multiply them. See:
wiki.freecadweb.org/Sandbox:Edwilliams16#Rotations
I mean the situation for example user has XYZ vector set to 1,1,1 and angle set to 30 degree. Now if I want to rotate for example +15 degree only for X I can set vector to 1,0,0 and rotate but this will remove the previous rotation or add 15 to 30 what give me rotation in all directions 1,1,1 of 45 degree.
I wondering if this is possible for user to start rotation for X and than continue rotation from the same point he finished.
EDIT:
OK, I have it here: https://wiki.freecadweb.org/Sandbox:Edwilliams16
Need to start reading, hope I don't have to know the quaternion rocket science to simply rotate panel
Thanks
Darek
github.com/dprojects
workbench for woodworking is available at: github.com/dprojects/Woodworking
Re: Rotation - how to rotate twice?
It depends on what your trying to achieve:
if you overwrite the placement you have to make some calculations, but if you use:
Code: Select all
import math
import FreeCAD
import Part
from FreeCAD import Placement, Rotation, Vector
def rotate(obj, rotX, rotY, rotZ):
m = obj.Placement.Matrix
m.rotateX(math.radians(rotX))
m.rotateY(math.radians(rotY))
m.rotateZ(math.radians(rotZ))
obj.Placement.Matrix = m
box = Part.makeBox(20,10,5)
Part.show(box, "cube")
box1 = Part.Shape(box)
rotate(box1, 45, 0, 0)
rotate(box1, 15, 0, 0)
rotate(box1, 30, 0, 0)
Part.show(box1, "cube1")
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/
Re: Rotation - how to rotate twice?
I was thinking about something like this below, to create some kind of tool to rotate things easily. I wanted to rotate not only panels based on Cubes but also Construction Profiles based on Thickness and other elements in the future.
But the rocket science is not for me I like simple things, keep things simple and I will go to Draft_Rotate instead, this will not be working at any Pads based objects but only at panels based on Cubes, but should be fine for Woodworking purposes.
I have also some issues related to replace Cube with Construction Profile if the Cube has custom rotation. I observed some strange behavior again at the Y axis. This is strange that X and Z axis works fine but the Y axis has some strange things. But maybe I will fix it somehow.
But the rocket science is not for me I like simple things, keep things simple and I will go to Draft_Rotate instead, this will not be working at any Pads based objects but only at panels based on Cubes, but should be fine for Woodworking purposes.
I have also some issues related to replace Cube with Construction Profile if the Cube has custom rotation. I observed some strange behavior again at the Y axis. This is strange that X and Z axis works fine but the Y axis has some strange things. But maybe I will fix it somehow.
Thanks
Darek
github.com/dprojects
workbench for woodworking is available at: github.com/dprojects/Woodworking
Re: Rotation - how to rotate twice?
Placement is usually a property that is spread over many things.
Problems are as usual when desling with Part Design things that complicate the object with many overehad.
For that reason I prefer operate with Part as it is everytime predictable as the rotation are totally under your control.
Joined with FPO (Feature Python Objects) it will a decent solution even in complex scenarios.
But there no ready made solutions.
Matrix could be manipulated also for translation and scaling, and are not too complicate to manage.
In case if problems order matters as translate and rotate have to be done in a correct order but with scripted objects you have always the mean to make experiments.
A commented out line and some tests will solve the problem.
Regards
Carlo D.
Problems are as usual when desling with Part Design things that complicate the object with many overehad.
For that reason I prefer operate with Part as it is everytime predictable as the rotation are totally under your control.
Joined with FPO (Feature Python Objects) it will a decent solution even in complex scenarios.
But there no ready made solutions.
Matrix could be manipulated also for translation and scaling, and are not too complicate to manage.
In case if problems order matters as translate and rotate have to be done in a correct order but with scripted objects you have always the mean to make experiments.
A commented out line and some tests will solve the problem.
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/
Re: Rotation - how to rotate twice?
This might be an overkill, but I would consider using Coin3D classes and quaternions for calculating and saving rotations (and other transformations).
Something like this:
Quaternions are more reliable than YPR, because they are "singularity (gimbal-lock) resistant".
If you need something more advaced like combining multiple different transformations, take look at SoTransform class and combineLeft/combineRight methods.
Something like this:
Code: Select all
rotz = FreeCAD.Rotation(FreeCAD.Vector(0,0,1),45) #first rotation
roty = FreeCAD.Rotation(FreeCAD.Vector(0,1,0),45) #second rotation
rotz.Q #print FreeCAD.Rotation as quaternion: (0.0, 0.0, 0.3826834323650898, 0.9238795325112867)
coinRotz = coin.SbRotation(rotz.Q) #convert to Coin3D rotation
coinRoty = coin.SbRotation(roty.Q)
finalCoinRot = coinRotz * coinRoty #combine rotations
finalCoinRot.getValue() #print resultant rotation quaternion: (0.1464466005563736, 0.3535533845424652, 0.3535533845424652, 0.8535533547401428)
FreeCAD.getDocument("myDoc").getObject("myObject").Placement = App.Placement(App.Vector(0,0,0),App.Rotation(finalCoinRot.getValue()[0],finalCoinRot.getValue()[1],finalCoinRot.getValue()[2],finalCoinRot.getValue()[3])) #apply final rotation on myObject
If you need something more advaced like combining multiple different transformations, take look at SoTransform class and combineLeft/combineRight methods.
Last edited by kwahoo on Mon Jun 20, 2022 8:08 pm, edited 1 time in total.
Re: Rotation - how to rotate twice?
I did it with rotate() function and it's working fine without the strange Y effect. But need to play more with center point to understand how to use it. Normally, objects should be rotated at the center line of the object, to rotate in-place. But for some reasons the vertex rotation is more useful. However, need to play with it little bit more.
Thanks
Darek
github.com/dprojects
workbench for woodworking is available at: github.com/dprojects/Woodworking
-
- Veteran
- Posts: 3180
- Joined: Thu Sep 24, 2020 10:31 pm
- Location: Hawaii
- Contact:
Re: Rotation - how to rotate twice?
In my opinion using yaw/pitch/roll is not at all suitable for your application. YPR is a way of describing rotations specialized to aerodynamic and rigid body mechanic applications. You want to use axis and angle.
However, making use of it is not trivial. If it were, we'd have a built-in assembly workbench already. The difficulty is that there are many ways of moving an object (B) relative to another fixed one (A), depending on the structure of your document and your design goals.
Simplest: both objects are at the root level.
Or: A and B sit inside Part containers AA and BB, which are respectively at the root level.
Or: There could be a whole nested hierarchy of sub-assemblies inside assemblies and we need to decide which level of the hierarchy we want to move.
B might be a link to an object and we only want to manipulate that links location - or it sits inside a linked Part container and we need to move that.
So a generally applicable tool is a potential UI morass. If you can limit the options sufficiently, then doing the underlying geometry is straightforward enough once you understand the general principles. You don't need to know anything about how the rotation operations are implemented.
Code: Select all
axis = App.Vector(1, 0, 0) # x-axis
angle = 30 #degrees
rot = App.Rotation(axis, angle)
Simplest: both objects are at the root level.
- We can attach B to A and manipulate B's Attachment Offset
- Leave B unattached and change its Placement.
Or: A and B sit inside Part containers AA and BB, which are respectively at the root level.
- We could move B within BB, also changing its position relative BB's other contents
- We could move BB, moving its contents en bloc
Or: There could be a whole nested hierarchy of sub-assemblies inside assemblies and we need to decide which level of the hierarchy we want to move.
B might be a link to an object and we only want to manipulate that links location - or it sits inside a linked Part container and we need to move that.
So a generally applicable tool is a potential UI morass. If you can limit the options sufficiently, then doing the underlying geometry is straightforward enough once you understand the general principles. You don't need to know anything about how the rotation operations are implemented.
Re: Rotation - how to rotate twice?
Hi
more easy if you use Placement
rotation object 10 degrees (here App.Rotation(10,0,0) = Z axis = Yaw and not x)
result : Placement [Pos=(0,0,0), Yaw-Pitch-Roll=(10,0,0)]
here rotation 10 degrees + original position (above) (with function multiply)
result : Placement [Pos=(0,0,0), Yaw-Pitch-Roll=(20,0,0)]
(codes returned in the Python console with placement rotation)
example of macro Macro_Rotate_To_Point
mario
more easy if you use Placement
rotation object 10 degrees (here App.Rotation(10,0,0) = Z axis = Yaw and not x)
Code: Select all
App.getDocument("Unnamed").Box.Placement=App.Placement(App.Vector(0,0,0), App.Rotation(10,0,0), App.Vector(0,0,0))
here rotation 10 degrees + original position (above) (with function multiply)
Code: Select all
App.getDocument("Unnamed").Box.Placement=App.Placement(App.Vector(0,0,0), App.Rotation(10,0,0), App.Vector(0,0,0)).multiply(App.getDocument("Unnamed").Box.Placement)
(codes returned in the Python console with placement rotation)
example of macro Macro_Rotate_To_Point
mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting.
My macros on Gist.github here complete macros Wiki and forum.
My macros on Gist.github here complete macros Wiki and forum.