Rotate twice - Draft vs. Rotation

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
edwilliams16
Veteran
Posts: 3106
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Rotate twice - Draft vs. Rotation

Post by edwilliams16 »

Apparently my Sandbox page https://wiki.freecadweb.org/Sandbox:Edw ... #Rotations is insufficiently clear on the compounding of rotations, so here's some material which may be clearer.
The file posted has two coincident cubes at the origin and a Coordinate system for reference.

Let us first consider the effect of two pure rotations. Pure means rotations about the origin with no accompanying translations.
We want rotate first by angle1 about (global) axis1, followed by a rotation of angle2 about axis2.

Code: Select all

import Draft
ZEROVEC = App.Vector(0, 0, 0)
axis1 = App.Vector(0, 0, 1)
angle1 = 45
axis2 = App.Vector(0, 1, 0)
angle2 = 30
Using Draft.rotate(objlist, angle, center, axis), which works at the document object level

Code: Select all

doc = App.ActiveDocument
obj = doc.getObject('Box')
Draft.rotate([obj], angle1, ZEROVEC, axis1)
Draft.rotate([obj], angle2, ZEROVEC, axis2)
doc.recompute()
If we want to work at the Rotation level:

Code: Select all

obj1 = doc.getObject('Link')
rot1 = App.Rotation(axis1, angle1)
rot2 = App.Rotation(axis2, angle2)
obj1.Placement.Rotation = rot2 * rot1 * obj1.Placement.Rotation
doc.recompute()
Note the order of the "multiplications" in the last line. rot2 * rot1 means apply rot2 to rot1. Think of it like a function application.
The results are the same - both manipulate the Placement - the latter directly.

If we consider a more general rigid motion, described by a Placement:

Code: Select all

App.Placement(translation, rotation, center)
which means first rotate with rotation about center, then translate the result by translation

Reset the placements:

Code: Select all

obj.Placement = App.Placement()
obj1.Placement = App.Placement()
doc.recompute()
Now do full placements by the two methods. I've left the translations and the centers as zero vectors. You can change them, of course, but the results are harder to visualize and verify.

Code: Select all

import Draft
ZEROVEC = App.Vector(0, 0, 0)
translation1 = App.Vector(0, 0, 0)
translation2 = App.Vector(0, 0, 0)
center1 = App.Vector(0, 0, 0)
center2 = App.Vector(0, 0, 0)
axis1 = App.Vector(0, 0, 1)
angle1 = 45
axis2 = App.Vector(0, 1, 0)
angle2 = 30


doc = App.ActiveDocument
obj = doc.getObject('Box')
Draft.rotate([obj], angle1, center1, axis1)
Draft.move([obj], translation1)
Draft.rotate([obj], angle2, center2, axis2)
Draft.move([obj], translation2)
doc.recompute()
Directly using Placements, we can combine the two operations by multiplying the Placements. (Again, note the order.)

Code: Select all

obj1 = doc.getObject('Link')
obj1.Placement = App.Placement(translation2, App.Rotation(axis2, angle2), center2) * \
App.Placement(translation1, App.Rotation(axis1, angle1), center1) * obj1.Placement
doc.recompute()
For the above operations, the Draft wrappers are arguably more easily understood. However, the App.Rotation API provides many alternative methods of specifying the desired rotation (other than axis/angle), which can be very useful in practice.
Attachments
rotCube.FCStd
(4.65 KiB) Downloaded 43 times
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Rotate twice - Draft vs. Rotation

Post by onekk »

Many thanks for your hard work.

Probably making this and your sandbox a wiki page will consolidate this knowledge.

However I've added these informations to my collection of notes about FreeCAD.

Regards

Carlo D.
Last edited by onekk on Thu Jan 19, 2023 3:53 pm, edited 1 time in total.
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: Rotate twice - Draft vs. Rotation

Post by dprojects »

edwilliams16 wrote: Tue Dec 13, 2022 9:59 pm

Code: Select all

obj1.Placement.Rotation = rot2 * rot1 * obj1.Placement.Rotation
Note the order of the "multiplications"
It's slightly embarrassing, I spend 1 day to find out that the code is not working because of order of multiplication.
What's even worse is that the correct order is the topmost container, not the one closest to the object,
see: https://forum.freecadweb.org/viewtopic.php?f=22&t=75343

Is there any reason why result of rot2 * rot1 can't be the same as result of rot1 * rot2 ?

Thanks
Darek
github.com/dprojects

workbench for woodworking is available at: github.com/dprojects/Woodworking
chrisb
Veteran
Posts: 53920
Joined: Tue Mar 17, 2015 9:14 am

Re: Rotate twice - Draft vs. Rotation

Post by chrisb »

dprojects wrote: Wed Jan 18, 2023 9:22 pm Is there any reason why result of rot2 * rot1 can't be the same as result of rot1 * rot2 ?
Because it is not the same to rotate e.g. a cube by 90° around the vertical axis and then by 90° around the horizontal axis than doing it in the opposite sequence.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
edwilliams16
Veteran
Posts: 3106
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Rotate twice - Draft vs. Rotation

Post by edwilliams16 »

dprojects wrote: Wed Jan 18, 2023 9:22 pm
Is there any reason why result of rot2 * rot1 can't be the same as result of rot1 * rot2 ?
Work through my article:
https://blog.freecad.org/2023/01/16/the ... n-freecad/
User avatar
dprojects
Posts: 721
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

Re: Rotate twice - Draft vs. Rotation

Post by dprojects »

chrisb wrote: Wed Jan 18, 2023 10:53 pm Because it is not the same to rotate e.g. a cube by 90° around the vertical axis and then by 90° around the horizontal axis than doing it in the opposite sequence.
But the multiplication operator * is a commutative operator and should never be overloaded for non-commutative operations.
If the result of rot1 * rot2 is not the same as rot2 * rot1 the operator should return error.

Additional approach could be overload operator > or <, or some other indicating the order should be used for non-commutative operations.
Also you can add .append(ordered_array) and .pop(ordered_array) functions that indicates the right order.

Thanks
Darek
github.com/dprojects

workbench for woodworking is available at: github.com/dprojects/Woodworking
chrisb
Veteran
Posts: 53920
Joined: Tue Mar 17, 2015 9:14 am

Re: Rotate twice - Draft vs. Rotation

Post by chrisb »

dprojects wrote: Thu Jan 19, 2023 3:23 pm But the multiplication operator * is a commutative operator and should never be overloaded for non-commutative operations.
Widen your view! It is known that matrix multiplication is not commutative. And in mathematics for the matrix multiplication the known symbols star (*) or dot (·) are used as operators.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Rotate twice - Draft vs. Rotation

Post by onekk »

dprojects wrote: Thu Jan 19, 2023 3:23 pm But the multiplication operator * is a commutative operator and should never be overloaded for non-commutative operations.
If the result of rot1 * rot2 is not the same as rot2 * rot1 the operator should return error.
...

You are not speaking about numbers, you are speaking about something different, see as example:

"dot product" and "cross product" of a Vector.

https://en.wikipedia.org/wiki/Vector_multiplication

Rotations are very complex so probably you are dealing with quaternion multiplication that uses "complex numbers" so it is not arithmetics.


from:

https://en.wikipedia.org/wiki/Multiplication
Multiplication is also defined for other types of numbers, such as complex numbers, and for more abstract constructs, like matrices. For some of these more abstract constructs, the order in which the operands are multiplied together matters. A listing of the many different kinds of products used in mathematics is given in Product (mathematics)

You are referring to a "portion" of the meaning of multiplication.

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

Re: Rotate twice - Draft vs. Rotation

Post by edwilliams16 »

The centuries old mathematical convention for multiplication of non numerical objects is that it may be non commutative, the addition operator on such objects is always commutative. A good example is the addition and multiplication of matrices.

Both operators are conventionally always associative.

That is

Code: Select all

rot1* rot2*rot3 = rot1* (rot2*rot3) =(rot1*rot2)*rot3
The study of objects that you can associatively multiply that have an identity operation and an inverse, like matrices, rotations, translations, quaternions and permutations is an entire field of mathematics called group theory which synthesizes the properties they have in common.
User avatar
dprojects
Posts: 721
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

Re: Rotate twice - Draft vs. Rotation

Post by dprojects »

chrisb wrote: Thu Jan 19, 2023 3:55 pm Widen your view! It is known that matrix multiplication is not commutative. And in mathematics for the matrix multiplication the known symbols star (*) or dot (·) are used as operators.
Clever argument but the Placement and Rotation at FreeCAD is not easy to use. It is more like science for science that looks good only at piece of paper but in real life and in practice it not fit well. If someone know how it works, for sure it is easier to use * operator but normally from development, not from scientists, perspective it is difficult and misleading. Maybe this is not exactly fault of * operator, but the whole Placement & Rotation logic, or maybe not accurate API and usage at FreeCAD.

Thanks
Darek
github.com/dprojects

workbench for woodworking is available at: github.com/dprojects/Woodworking
Post Reply