[solved] Rotation - how to rotate twice?

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: 721
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

[solved] Rotation - how to rotate twice?

Post by dprojects »

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?
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
edwilliams16
Veteran
Posts: 3106
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Rotation - how to rotate twice?

Post by edwilliams16 »

To make successive (compounded) rotations, you multiply them. See:

wiki.freecadweb.org/Sandbox:Edwilliams16#Rotations
User avatar
dprojects
Posts: 721
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

Re: Rotation - how to rotate twice?

Post by dprojects »

edwilliams16 wrote: Sun Jun 19, 2022 11:20 pm To make successive (compounded) rotations, you multiply them. See:

wiki.freecadweb.org/Sandbox:Edwilliams16#Rotations
The requested page could not be found.

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
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Rotation - how to rotate twice?

Post by onekk »

dprojects wrote: Mon Jun 20, 2022 1:42 pm
I wondering if this is possible for user to start rotation for X and than continue rotation from the same point he finished.



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")
This would work, not very elegant, but...

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: 721
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

Re: Rotation - how to rotate twice?

Post by dprojects »

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.

Image

Thanks
Darek
github.com/dprojects

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

Re: Rotation - how to rotate twice?

Post by onekk »

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.
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
kwahoo
Posts: 680
Joined: Fri Nov 29, 2013 3:09 pm
Contact:

Re: Rotation - how to rotate twice?

Post by kwahoo »

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:

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
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.
Last edited by kwahoo on Mon Jun 20, 2022 8:08 pm, edited 1 time in total.
User avatar
dprojects
Posts: 721
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

Re: Rotation - how to rotate twice?

Post by dprojects »

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.

Image

Thanks
Darek
github.com/dprojects

workbench for woodworking is available at: github.com/dprojects/Woodworking
edwilliams16
Veteran
Posts: 3106
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Rotation - how to rotate twice?

Post by edwilliams16 »

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.

Code: Select all

axis = App.Vector(1, 0, 0) # x-axis
angle = 30 #degrees
rot = App.Rotation(axis, 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.
  • 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.
mario52
Veteran
Posts: 4673
Joined: Wed May 16, 2012 2:13 pm

Re: Rotation - how to rotate twice?

Post by mario52 »

Hi

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))
result : Placement [Pos=(0,0,0), Yaw-Pitch-Roll=(10,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)
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 Image
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.
Post Reply