Rotating an arbitrary object around an edge.

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Rotating an arbitrary object around an edge.

Post by onekk »

Hello, following this topic:

https://forum.freecadweb.org/viewtopic.php?f=22&t=72362

and Thanks to @mario52 invaluable help:

https://forum.freecadweb.org/viewtopic. ... 02#p631002

I have elaborated some more the topic:

Code: Select all

import FreeCAD
from FreeCAD import Placement, Rotation, Vector
import Part

ROT0 = Rotation(0,0,0)
VEC0 = Vector(0,0,0)

DOC = FreeCAD.activeDocument

box = Part.makeBox(10,15,20)
box.Placement = Placement(Vector(10,10,10), Rotation(0, 10 ,10))

box_do = Part.show(box, "or_box")

# copy the Box.shape
box1_sh = box_do.Shape
# retain the original box placement
pl1 = box.Placement

# choose an edge to rotate from
# I know is a cheat, but...  
edge = box1_sh.Edges[3]

# obtain starting and ending point of the edge
# it should work even for a cruved edge
p1 = edge.valueAt(0)
p2 = edge.valueAt(1.0)

print(f"p1: {p1}, p2: {p2}")

axis = p2.sub(p1)
angle = 60
rot_p = Placement(VEC0, Rotation(axis, angle), p1)

print(f"axis: {axis}, angle: {angle}")

box_rot = Part.show(box1_sh, "rot_box")
# multiply the two placement
box_rot.Placement = rot_p.multiply(pl1)

Part.show(edge, "line")

Code should work even on "arbitrary shapes" other than a cube if you find a suitable way to obtain an edge and calculate a start and ending point. (It will not work as example for a cilynder, or a spehre, and probably not even for cones, torus and so on.)

Some caveats:
  • I have used a copy of the object, obtained using .Shape that will make a copy of the Shape alone

    Code: Select all

    box1_sh = box_do.Shape
    
  • I have "retained" the placement as it is not copied

    Code: Select all

    # retain the original box placement
    pl1 = box.Placement
    
  • To make the correct placement you have to multiply them but remember that the "order" is important

    Code: Select all

    # multiply the two placement
    box_rot.Placement = rot_p.multiply(pl1)
    
  • Rotation is done using the form (axis, angle) and specifing a center as third paramter of Placement.

    Code: Select all

    rot_p = Placement(VEC0, Rotation(axis, angle), p1)
    
  • Better to not make too much work on placement, and if you need further moves, use:

    Code: Select all

    pl2.multiply(pl1)
    
    Remember that order matters.

This is one of the most problematic things when dealing with FreeCAD, as there is behind some complicated "Vector Math", that is not easy to sort out if you are not a "vector math guy". (I'm "math impaired").

So take not of it and "keep under your cushion".

Hope it helps

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

Re: Rotating an arbitrary object around an edge.

Post by onekk »

Warning this post could contain wrong assumptions,

USE IT AT YOUR OWN RISK

Foreword, as I'm math impaired I want to say correct things, as the code seem to show the result is correct.

But the theory behind is black magic for me and from what I have seen from many users around.

@edwilliams16, @Chris_G, @chrisb Could you kindly revise my guesses?

This line is computing a difference from two vector, subtracting the first to the second point.

Code: Select all

axis = p2.sub(p1)

This is like to move the starting point of the line (that will become the axis of rotation) to the origin.


The placement below is the real rotation:

Code: Select all

angle = 60
rot_p = Placement(VEC0, Rotation(axis, angle), p1)
This is the real rotation around the axis, repositioned on the origin.

Code: Select all

Rotation(axis, angle)
But we have to reposition the Placement to the initial point so we add a rotation center p1

TIA and 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/
mario52
Veteran
Posts: 4673
Joined: Wed May 16, 2012 2:13 pm

Re: Rotating an arbitrary object around an edge.

Post by mario52 »

Hi
onekk wrote: Thu Oct 06, 2022 5:27 pm This line is computing a difference from two vector, subtracting the first to the second point.

Code: Select all

axis = p2.sub(p1)
this is not axis but Direction, if the result of substraction is (example) Vector(10, 10, 0) :

create one line points (0,0,0) to (10,10,0) and you visualise the Direction
onekk wrote: Thu Oct 06, 2022 5:27 pm The placement below is the real rotation:

Code: Select all

angle = 60
rot_p = Placement(VEC0, Rotation(axis, angle), p1)
here axis correspond of the direction

here angle = angle of rotation in degrees

here p1 (in my macro) is the first edge first point of the face selected or the edge selected first point

example:

create a cube and select one face run macro (1 selection),

select one edge run macro (1 selection)

or select the cube and one line (created or edge on other object) run macro (2 selections)

if you replace p1 by the center of masse, the cube rotate on itself

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

Re: Rotating an arbitrary object around an edge.

Post by onekk »

mario52 wrote: Thu Oct 06, 2022 6:17 pm Hi
...

Code: Select all

axis = p2.sub(p1)
this is not axis but Direction, if the result of substraction is (example) Vector(10, 10, 0) :
Hi, many thanks for replying.

Ok I have normalize it to transform in an axis?
EDIT: Seems that FreeCAD at least on 0.20.1 do it for us.

as a simple print will show something similar:

Code: Select all

Vector (0.030153689607045564, 0.984807753012209, 0.17101007166283466)
END EDIT

Do you have hints.

As this question is hanging around, probably some clear explanation will be useful for others. And as I'm math impaired, I'm a perfect test. :-D

Regards

Carlo D.

EDITED POST.
Last edited by onekk on Fri Oct 07, 2022 7:10 am, edited 2 times 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/
mario52
Veteran
Posts: 4673
Joined: Wed May 16, 2012 2:13 pm

Re: Rotating an arbitrary object around an edge.

Post by mario52 »

Hi

I think he is the direction is the path axis ... je ne sais pas !

Code: Select all

App.Rotation(App.Vector(direction), valeur)
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.
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Rotating an arbitrary object around an edge.

Post by onekk »

mario52 wrote: Thu Oct 06, 2022 8:03 pm ...
Ok, thanks a lot.

From what i have seen around in the many documents I've read, sadly most of them contains ugly Matrix explanations, so it is complicated to follow them with my math skills.

The procedure is almost clear as example :

https://www.cs.helsinki.fi/group/goa/ma ... 3drot.html
In the general case, rotation about an arbitrary axis is more complicated. First we must define the axis of Rotation by 2 points - P1, P2 then do the following:

1. Translate so that rotation axis passes through origin.
2. Rotate so that the rotation axis is aligned with one of the principle coordinate axes.
3. Perform rotation of object about coordinate axis.
4. Perform inverse rotation of 2.
5.Perform inverse translation of 1.
As it seems on FreeCAD with Rotation(axis, angle) only 1 and 5 are needed.


Side note your direction is already a Vector so using App.Vector(direction) is not strictly necessary.


Thanks again for the code and for replying, your Macros are always interesting and contains useful thing.

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/
Post Reply