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.
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?
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
I want to do this for rotation tool
So it would be like this: (but without manual rotation rest of elements :P)
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.
I had stopped using EntityObservers, because it was crashing the sketchup (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.
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
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