rotation operators

Need help, or want to share a macro? Post here!
Post Reply
Vasten
Posts: 21
Joined: Wed May 18, 2022 9:00 pm

rotation operators

Post by Vasten »

pardon my ignorance

suppose I have 2 Placements, object A and B

I want to rotate A to be the same global orientation as B

But because they are in different containers, I cant simply set the rotations to be equal

I can check global Placements of A and B....

but how do i determine the difference (rotation I need to apply to A to make it the same global orientation as B)

I basically want to do

Code: Select all

A.Rotation += (B_Global_Rotation - A_Global_Rotation) - Container_Global_Rotation
I feel a bit frustrated, I have all the information (global rotation values) but i cant put them together, I have been digging through documentation and examples, I tried the matrix overload operators, but still no luck..

a pointer in the right direction or help would be much appreciated

OS: Windows 10 Version 2009
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 2022.430.28641 (Git)
Build type: Release
Branch: LinkStage3
Hash: a77045488092c24ece25d63c91f362cbd2181d36
Python version: 3.8.6+
Qt version: 5.15.2
Coin version: 4.0.1
OCC version: 7.5.0
Locale: Chinese/China (zh_CN)
User avatar
onekk
Veteran
Posts: 2407
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: rotation operators

Post by onekk »

I think it is a Vector Math problem in the past @edwilliams16 has solved similar problems when I've had, so probably it is the "expert" to consult.

he has written also this page, in the meantime see if it could be useful.

https://wiki.freecadweb.org/Sandbox:Edwilliams16

Maybe also this discussion could be helpful:

https://forum.freecadweb.org/viewtopic. ... 2&start=10


Let's see if poking him a little will solve also your problem, due to timezone problem it may need some hours to obtain an answer:
edwilliams16 wrote:
Sorry for poking, Could you have some hints about this problem?

Regards

Carlo D.
My English and Italian Scripting Guide https://github.com/onekk/freecad-doc.
My Blog: https://onekk-maker.blogspot.com/

To help development see on GitHub Page

For enquiry about customized FC Scripting job PM me.
marioalexis
Posts: 92
Joined: Wed Jun 19, 2019 7:44 pm

Re: rotation operators

Post by marioalexis »

Code: Select all

objA.Placement.Rotation = ContainerA.Placement.Rotation.inverted() * containerB.Placement.Rotation * objB.Placement.Rotation
To concatenate rotations (or placements) you must mutiply the matrix, not add them.
The matrix mutiplication are not conmmutative, so the order in the operations is important.
To understand the sequence of rotations on the object you must read the expression from right to left.
The transformations in the containers are performed recursively, so to concatenate a new transformation, you must multiply to the left on the current transformation matrix
edwilliams16
Veteran
Posts: 1168
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: rotation operators

Post by edwilliams16 »

onekk wrote: Thu Jun 23, 2022 12:14 pm
Let's see if poking him a little will solve also your problem, due to timezone problem it may need some hours to obtain an answer:
edwilliams16 wrote:
To expand on @marioalexis reply, how would you figure this out for yourself. There are are some simple rules to apply. You do not need to know the details of the implementation - matrices, quaternions and the like.
  • Every object lives in its own local coordinate system (LCS)
  • In the 3D view, the objects are shown in the the global coordinate system (GCS)
  • You move objects around with Placements
  • A Placement rotates the object by Placement.Rotation then translates it by Placement.Base
  • The effect of a Placement on any coordinate vector is given by

    Code: Select all

    transformed_vector = Placement.multVec(vector)
    or

    Code: Select all

    transformed_vector = Placement * vector
  • Placements are compounded if objects sit in nested containers e.g.
    Screen Shot 2022-06-23 at 7.40.38 AM.png
    Screen Shot 2022-06-23 at 7.40.38 AM.png (22.74 KiB) Viewed 193 times
    Here Body001 sits inside Part002 and Body is inside Part001 inside Part
  • Compounded placements are multiplied. This is not the multiplication of numbers, but has many properties in common with ordinary multiplication.

    Code: Select all

    global_placement_of_Body001 = Placement_of_Part002 * Placement_of_Body001 # or Placement_of_Part002.multiply(Placement_of_Body001)
    global_placement_of_Body = Placement_of_Part * Placement_of_Part001 * Placement_of_Body
  • The order of multiplication matters. Container placements go the left of their contents.
  • Every Placement has an inverse, that will undo the operation.
Now we are ready to tackle the algebra of placements. First lets compact the the notation

Code: Select all

gBody = global_placement_of Body
pPart = Placement_of_Part
etc.

We know

Code: Select all

gBody = pPart * pPart001 * pBody
gBody001 = pPart002 * pBody001 
Suppose we want to find a new pBody (call it pBody' )that makes gBody = gBody001
That gives us the equation

Code: Select all

gBody = pPart * pPart001 * pBody' = gBody001 = pPart002 * pBody001
or

Code: Select all

pPart * pPart001 * pBody' = pPart002 * pBody001
which we want to solve for pBody' . Just as in ordinary algebra, we need to divide through by pPart. Since division is the inverse of multiplication, this means multiplying both sides by the inverse of pPart. Order matters, so we do it in the left.

Code: Select all

pPart_inverse * pPart * pPart001 * pBody' = pPart_inverse * pPart002 * pBody001
pPart001 * pBody' = pPart_inverse * pPart002 * pBody001
since the effect of pPart_inverse * pPart is to do nothing - the identity transformation.
Now we repeat this multiplying each side by pPart001_inverse on the left, obtaining

Code: Select all

pBody' = pPart001_inverse * pPart_inverse * pPart002 * pBody001
Solving the for the placement we were looking for.

Try this for yourself. Suppose you wanted to change pPart001 so that gBody and gBody001 became equal. What would you change it to?
Vasten
Posts: 21
Joined: Wed May 18, 2022 9:00 pm

Re: rotation operators

Post by Vasten »

Thank you so much

multiplying by inverted rotation is just what i needed.. thank you so much :)

edwilliams16 wrote: Thu Jun 23, 2022 6:36 pm
onekk wrote: Thu Jun 23, 2022 12:14 pm
Let's see if poking him a little will solve also your problem, due to timezone problem it may need some hours to obtain an answer:
edwilliams16 wrote:
To expand on @marioalexis reply, how would you figure this out for yourself. There are are some simple rules to apply. You do not need to know the details of the implementation - matrices, quaternions and the like.
  • Every object lives in its own local coordinate system (LCS)
  • In the 3D view, the objects are shown in the the global coordinate system (GCS)
  • You move objects around with Placements
  • A Placement rotates the object by Placement.Rotation then translates it by Placement.Base
  • The effect of a Placement on any coordinate vector is given by

    Code: Select all

    transformed_vector = Placement.multVec(vector)
    or

    Code: Select all

    transformed_vector = Placement * vector
  • Placements are compounded if objects sit in nested containers e.g.
    Screen Shot 2022-06-23 at 7.40.38 AM.png
    Here Body001 sits inside Part002 and Body is inside Part001 inside Part
  • Compounded placements are multiplied. This is not the multiplication of numbers, but has many properties in common with ordinary multiplication.

    Code: Select all

    global_placement_of_Body001 = Placement_of_Part002 * Placement_of_Body001 # or Placement_of_Part002.multiply(Placement_of_Body001)
    global_placement_of_Body = Placement_of_Part * Placement_of_Part001 * Placement_of_Body
  • The order of multiplication matters. Container placements go the left of their contents.
  • Every Placement has an inverse, that will undo the operation.
Now we are ready to tackle the algebra of placements. First lets compact the the notation

Code: Select all

gBody = global_placement_of Body
pPart = Placement_of_Part
etc.

We know

Code: Select all

gBody = pPart * pPart001 * pBody
gBody001 = pPart002 * pBody001 
Suppose we want to find a new pBody (call it pBody' )that makes gBody = gBody001
That gives us the equation

Code: Select all

gBody = pPart * pPart001 * pBody' = gBody001 = pPart002 * pBody001
or

Code: Select all

pPart * pPart001 * pBody' = pPart002 * pBody001
which we want to solve for pBody' . Just as in ordinary algebra, we need to divide through by pPart. Since division is the inverse of multiplication, this means multiplying both sides by the inverse of pPart. Order matters, so we do it in the left.

Code: Select all

pPart_inverse * pPart * pPart001 * pBody' = pPart_inverse * pPart002 * pBody001
pPart001 * pBody' = pPart_inverse * pPart002 * pBody001
since the effect of pPart_inverse * pPart is to do nothing - the identity transformation.
Now we repeat this multiplying each side by pPart001_inverse on the left, obtaining

Code: Select all

pBody' = pPart001_inverse * pPart_inverse * pPart002 * pBody001
Solving the for the placement we were looking for.

Try this for yourself. Suppose you wanted to change pPart001 so that gBody and gBody001 became equal. What would you change it to?
Post Reply