Catch the rotate point and angle from Rotate Tool

Hi!
Do anybody have idea how to catch ‘the point’ and ‘rotation angle’ in the code?

I tried the Sketchup::ToolsObserver, but it invoke only at the begin of using tool (or at the end).
I am interested in catching information about the rotation.


As the ‘rescue solution’ I thought about comparing translations before and after the rotation and try to get information from there

This information isn’t exposed in our APIs. It’s difficult to build API that expose very much of the internal workings of the tool, as that could prevent the tools from being reworked in the future without breaking extensions.

Typically I’d either extract information from the matrices or build a new tool from scratch tailored for my needs. What is your higher level use case?

thanks for answer,

What is your higher level use case?

in the plugin I need to develop ‘connection’ between elements.
So for example ‘Wall 1’ and ‘Wall 2’ are connected.

Idea is to have that connection with sketchup tools.
For moving tool it was relative easy. I compared states of transformation before and after usage of standard ‘move tool’. So get move vector and used it for all connected elements.

For rotation it is more complex ;/

Live example:
move tool
GIF 16-Jan-24 2-22-27 PM

I want to do this for rotation tool
So it would be like this: (but without manual rotation rest of elements :P)

GIF 16-Jan-24 2-23-57 PM

For this I think I’d add EntityObservers to the wall objects and react to them changing, regardless of tool. That should work with Move, Rotate, Scale, Flip and even custom Ruby tools from other extensions and tools not yet developed.

When the walls are drawn you can save a copy of their transformation to their attributes (as an array) when they are altered you can compare that transformation with the current one to see the change. Then redraw and update the copy of the attribute.

I’ve used a similar pattern in a few of my extensions.

1 Like

I had stopped using EntityObservers, because it was crashing the sketchup :stuck_out_tongue: (like in the note in the documentation)

I already have translation ‘before’ and ‘after’ the rotation tool. (I save translation during the selection tool)
ok, I will compare these translations to get all information that I need.

wonder how to do it. I managed to get the angle rotation difference, but how to find a point… Maybe I should check where the axis from transformation intersect with each other?
not sure

Extracting the rotation center is not trivial. But is it needed? Maybe just knowing how the position changed and how the wall relates to other walls are enough.

maybe maybe,
I’m still looking for a solution ; )

Here’s a little Ruby code and a model to try it on. I don’t know what special conditions might restrict this approach to the problem. In the example I’m assuming we are rotating around the Z axis, but I don’t think that’s a limitatiaon.

Follow this link to see a dicussion of this method

The model
find center of rotation.skp (85.8 KB)

model = Sketchup.active_model
ents = model.active_entities

model.start_operation('Find Center of Rotation', true)

  # Start with a container with two groups representing the initial transformaton and the final transformation
    grps = ents.grep(Sketchup::Group)  
    grp_initial = grps[0]
    grp_final = grps[1]
    
    # Find two (wisely selected) corresponding points from each group
    #  ( in your case you need to record the initial locations and tansformation of the initial group)
    
    grp_initial_edge = grp_initial.entities.grep(Sketchup::Edge)[0]
    pt_initial_start = grp_initial_edge.start.position
    pt_initial_end = grp_initial_edge.end.position
    
    grp_final_edge = grp_final.entities.grep(Sketchup::Edge)[0]
    pt_final_start = grp_initial_edge.start.position
    pt_final_end = grp_initial_edge.end.position
    
    # transform to outer container
    pt_initial_start.transform!(grp_initial.transformation)
    pt_initial_end.transform!(grp_initial.transformation)
    pt_final_start.transform!(grp_final.transformation)
    pt_final_end.transform!(grp_final.transformation)
     
    ents.add_cpoint(pt_initial_start)
    ents.add_cpoint(pt_initial_end)
    ents.add_cpoint(pt_final_start)
    ents.add_cpoint(pt_final_end)
  
  
  
  # https://mammothmemory.net/maths/geometry/manipulating-shapes/how-do-you-find-the-centre-of-rotation.html
  # 1. Draw a line between the corresponding points
    
    ents.add_cline(pt_initial_start, pt_final_start)
    ents.add_cline(pt_initial_end, pt_final_end)
  
  # 2. Construct the perpendicular bisect of these points
  
    # vector from initial to final for start points
    vect_start_pts = pt_initial_start.vector_to(pt_final_start)
    vect_start_pts.length = vect_start_pts.length / 2
    pt_initial_start_bisect_pt = pt_initial_start + vect_start_pts
    ents.add_cpoint(pt_initial_start_bisect_pt)
    
    # add construction line
    vect_start_cross = vect_start_pts.cross(Z_AXIS)
    ents.add_cline(pt_initial_start_bisect_pt, vect_start_cross )
    
  
    # vector from initial to final for end points
    vect_end_pts = pt_initial_end.vector_to(pt_final_end)
    vect_end_pts.length = vect_end_pts.length / 2
    pt_initial_end_bisect_pt = pt_initial_end + vect_end_pts
    ents.add_cpoint(pt_initial_end_bisect_pt)
    
    # add construction line
    vect_end_cross = vect_end_pts.cross(Z_AXIS)
    ents.add_cline(pt_initial_end_bisect_pt, vect_end_cross )

  # 3. Do this for each point until they cross
    line_start_perpendicular = [pt_initial_start_bisect_pt, vect_start_cross]
    line_end_perpendicular = [pt_initial_end_bisect_pt, vect_end_cross]
  
  # 4. That is your centre of rotation
    center_of_rotation = Geom.intersect_line_line(line_start_perpendicular, line_end_perpendicular)
    ents.add_cpoint(center_of_rotation)
    ents.add_text("Calculated Center of Rotation", center_of_rotation, [2.5,-1, 0])
  

model.commit_operation

nil

Find Center of Rotation.rb (3.0 KB)

thanks @sWilliams for it, unfortunately I need solution for all axis

I took @ene_su advice and used the relationships.

  1. After rotation I have reference to all objects and 2 transformation (before and after rotation)
  2. I calculate vector between ‘before transformation’ and element to rotate
  3. I create new group and pass that vector (with the inversed translation)
  4. I translate new group using ‘after transformation’
  5. I take the new vector positions which are rotated.

In this way I have good move vector and I set xaxis/yaxis/zaxis to ‘after transformation’.

End result:

GIF 17-Jan-24 2-27-06 PM