Calculating a rotation with two parameters?
Forum rules
Be nice to others! Read the FreeCAD code of conduct!
Be nice to others! Read the FreeCAD code of conduct!
Calculating a rotation with two parameters?
What I want is to feed two variables ( as angles) into a function (starting at 0,0,0) and get out a rotation, I will insert the output values in a Placement Rotation. I see the rotation as Z = 0 to 360 and y = 0 to 360, ( or +- 180 for both), this should be enough to solve the rotation. Since X and Y are on the same plane they are somewhat redundant. I am presuming this can be done without trig. but I'm not sure how to get there with the axis and vector stuff, any thoughts could be helpful.
Thanks
Thanks
-
- Veteran
- Posts: 3194
- Joined: Thu Sep 24, 2020 10:31 pm
- Location: Hawaii
- Contact:
Re: Calculating a rotation with two parameters?
A general rotation has three degrees of freedom, so to specify it with angles takes three - eg yaw, pitch and roll.
From your post, I think you are looking at the subset of rotations with roll=0 i.e App.Rotation(yaw, pitch, 0)
Code: Select all
yaw =20
pitch = 30
roll = 40
rot = App.Rotation(yaw, pitch, roll)
rot1 = App.Rotation(App.Vector(0,0,1), yaw) * App.Rotation(App.Vector(0, 1, 0), pitch) * App.Rotation(App.Vector(1, 0, 0), roll)
rot.isSame(rot1, 1e-8) # => True
rot.getYawPitchRoll() # => (20.0, 29.999999999999993, 40.0)
Re: Calculating a rotation with two parameters?
Thanks Ed, and for the code. That looks like the right thing to use.
Re: Calculating a rotation with two parameters?
Code is simply telling you two ways of doing rotations.
Note that there is an rotation order.
In first way it is ZYX so first Z is applied then Y and then the X.
If this what you have in mind you should specify a different "order of rotation" or multiply rotation accordingly.
@edwilliams16 has wrote something in some recent post, or in the FreeCAD blog if I remember correctly.
Regards
Carlo D.
Code: Select all
# first way very concise and similar to
# what you get using print(placement)
rot = App.Rotation(yaw, pitch, roll)
# second way. NOTE order of multiplying
rot1 = App.Rotation(App.Vector(0,0,1), yaw) * App.Rotation(App.Vector(0, 1, 0), pitch) * App.Rotation(App.Vector(1, 0, 0), roll)
# proof that the two ways are the same
rot.isSame(rot1, 1e-8) # => True
In first way it is ZYX so first Z is applied then Y and then the X.
If this what you have in mind you should specify a different "order of rotation" or multiply rotation accordingly.
@edwilliams16 has wrote something in some recent post, or in the FreeCAD blog if I remember correctly.
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: 3194
- Joined: Thu Sep 24, 2020 10:31 pm
- Location: Hawaii
- Contact:
Re: Calculating a rotation with two parameters?
@onekk @freedman
There's a discussion of these compound rotations in my blog article: https://blog.freecad.org/2023/01/16/the ... n-freecad/
Yaw/Pitch/Roll is illustrated in the wiki https://wiki.freecadweb.org/Placement#P ... h_and_Roll
If they lack clarity, let me know.
There's a discussion of these compound rotations in my blog article: https://blog.freecad.org/2023/01/16/the ... n-freecad/
Yaw/Pitch/Roll is illustrated in the wiki https://wiki.freecadweb.org/Placement#P ... h_and_Roll
If they lack clarity, let me know.
Re: Calculating a rotation with two parameters?
Thanks for the links.edwilliams16 wrote: ↑Sat Jan 28, 2023 5:49 pm @onekk @freedman
There's a discussion of these compound rotations in my blog article: https://blog.freecad.org/2023/01/16/the ... n-freecad/
Yaw/Pitch/Roll is illustrated in the wiki https://wiki.freecadweb.org/Placement#P ... h_and_Roll
If they lack clarity, let me know.
Not a problem on my side, once learned a couple of things that you kindly "teached" me in your works and forum posts.
Thanks to your help I'm coding slightly better now. Thanks again.
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: Calculating a rotation with two parameters?
This got me curious about the Matrix API. https://wiki.freecadweb.org/Matrix_API
Here is an animation using a cube to visualize matrix rotations of Z & X:
From the consol you can rest the cube with:
edit: fix final angle
Here is an animation using a cube to visualize matrix rotations of Z & X:
Code: Select all
import Part, time, math
# Set ending angle for rotation
eAng = 75
# Zero for rotation steps
rx, rz = 0, 0
doc = App.ActiveDocument
Gui.ActiveDocument.ActiveView.setAxisCross(True)
# Add a colored box
box_obj = doc.addObject('Part::Box', 'Box')
box_obj.recompute()
blue, green, red = (0.,0.,1.,0.), (0.,0.4,0.,0.), (1.,0.,0.,0.)
box_obj.ViewObject.DiffuseColor = [blue, (0.,0.,0.,1.),green ,(0.,0.,1.,1.),red ,(0.,0.,1.,1.)]
#reposition Box xyz if you like, -5 is default Box center
box_obj.Placement.Base = (-5.0,-5.0,-5.0)
# Start loop for rotating the box around the z-axis
while rz < eAng:
# Update the placement of the box object by 1 degree increments about z
box_obj.Placement.Matrix.rotateZ(math.radians(1))
# Increment the rotation value for the z-axis
rz += 1
# Update the gui and recompute the document
App.Gui.updateGui()
doc.recompute()
# Wait for 0.01 seconds before continuing
time.sleep(.01)
# loop rotating the box around the x-axis
while rx < eAng:
box_obj.Placement.Matrix.rotateX(math.radians(1))
rx += 1
App.Gui.updateGui()
doc.recompute()
time.sleep(.01)
Code: Select all
App.ActiveDocument.Box.Placement.Matrix = App.Matrix() #will reset XYZ as well
#or
import math
App.ActiveDocument.Box.Placement.Matrix.rotateX(math.radians(-75))
App.ActiveDocument.Box.Placement.Matrix.rotateZ(math.radians(-75))
App.ActiveDocument.recompute()
-
- Veteran
- Posts: 3194
- Joined: Thu Sep 24, 2020 10:31 pm
- Location: Hawaii
- Contact:
Re: Calculating a rotation with two parameters?
Looking at the reference, this is absurdly wrong:dtay wrote: ↑Sun Jan 29, 2023 5:38 pm This got me curious about the Matrix API. https://wiki.freecadweb.org/Matrix_API
Code: Select all
multiply(Matrix or Vector)
Description: Returns the cross product of a matrix or vector with this matrix
Returns: a Matrix
It return the matrix product - which is either another matrix or a vector.
However it says not to edit it, but refers to the C++ code documentation which is correct but not completely apropos as the python wrapper is incomplete.
https://freecad.github.io/SourceDoc/d5/ ... rix4D.html
Re: Calculating a rotation with two parameters?
dtay, I was also wondering about the matrix. Thanks for the code.
Wow! That is so simple to use and reads like a book. Perfect timing for what I needed.
Thank you
Wow! That is so simple to use and reads like a book. Perfect timing for what I needed.
Thank you
-
- Veteran
- Posts: 3194
- Joined: Thu Sep 24, 2020 10:31 pm
- Location: Hawaii
- Contact:
Re: Calculating a rotation with two parameters?
@dtay
You'll find the API for matrices is impoverished compared to that of Placements or Rotations.
For instance, suppose you want to rotate about an axis that isn't x, y or z. How would you generate the rotation matrix corresponding to
Code: Select all
rot = App.Rotation(App.Vector(1, 1, 1), 30)
Code: Select all
rot = App.Rotation(App.Vector(1, 0, 0), App.Vector(1,1,1))
You could use
Code: Select all
mat = rot.Matrix
Matrices allow you to scale and shear objects as well as translate and rotate them. Scaling is used in FreeCAD, shearing AFAIK only in macros. Don't bother with them unless they are actually required.
Here's the previous script. Run it with usematrix = True or False to see they are the same. How would you generalize both to rotate around the (1,1,1) axis?
Code: Select all
import Part, time, math
# Set ending angle for rotation
eAng = 75
# Zero for rotation steps
rx, rz = 0, 0
usematrix = False
doc = App.ActiveDocument
Gui.ActiveDocument.ActiveView.setAxisCross(True)
# Add a colored box
box_obj = doc.addObject('Part::Box', 'Box')
box_obj.recompute()
blue, green, red = (0.,0.,1.,0.), (0.,0.4,0.,0.), (1.,0.,0.,0.)
box_obj.ViewObject.DiffuseColor = [blue, (0.,0.,0.,1.),green ,(0.,0.,1.,1.),red ,(0.,0.,1.,1.)]
#reposition Box xyz if you like, -5 is default Box center
box_obj.Placement.Base = (-5.0,-5.0,-5.0)
# Start loop for rotating the box around the z-axis
while rz < eAng:
# Update the placement of the box object by 1 degree increments about z
pl1z = App.Placement(App.Vector(), App.Rotation(App.Vector(0, 0, 1), 1))
if usematrix:
box_obj.Placement.Matrix.rotateZ(math.radians(1))
else:
box_obj.Placement = pl1z * box_obj.Placement
# Increment the rotation value for the z-axis
rz += 1
# Update the gui and recompute the document
App.Gui.updateGui()
doc.recompute()
# Wait for 0.01 seconds before continuing
time.sleep(.01)
# loop rotating the box around the x-axis
while rx < eAng:
rx += 1
pl1x = App.Placement(App.Vector(), App.Rotation(App.Vector(1, 0, 0), 1))
if usematrix:
box_obj.Placement.Matrix.rotateX(math.radians(1))
else:
box_obj.Placement = pl1x * box_obj.Placement
App.Gui.updateGui()
doc.recompute()
time.sleep(.01)