The rotation method is used to create a transformation that does rotation about an axis.
Well, my problem is how to find the axis. I have a polygon which is in component and I want to rotate the component about it’s center. To be more exact, it is cylinder so 2 polygons having 24 faces, in fact.
So suppose I have selected the polygon now I need just to find the axis to rotate it. How to do it?
Note:
As the reference does not state if we should use radians or degrees, I expect the rotation will be in degrees.
Use Radians.
As Sketchup cannot determine what is the axis of rotation - it has infinite choices, the method I use is to draw a single line within the component or group. Then the script can search for that line by looking at all edges not connected to a face, and that line defines the axis of rotation.
So the problem is not related to the rotation transformation (since you would be free to provide an axis of your choice), but how to find the center of an extruded cylinder. In SketchUp, entities are not so parametric that they know they form a cylinder, so either we need to carefully test the geometry or we can rely on assumptions.
If you know the component contains exactly one cylinder and it has a defined orientation in the component (like extruded in z direction), you can obtain the center from the component instance’s bounds.
If you know the component contains exactly one cylinder with more than four sides, the two faces with maximum number of vertices are the bottom and top face.
If the circle/polygon is intact (not exploded), you can use arccurve.center and normal.
If the top face has an even number of sides (C2 symmetry), the center coincides with face.bounds.center. For an uneven number of sides, it is the average of all of the face’s vertex positions.
You can’t blackmail the API, it won’t suddenly change to what you expect. Like almost all program code it uses radians.
Would it be simpler if there would be axis placed inside of the component in the center of the polygon? Then maybe we could ask for position of the axis?
It sounds like your polygon has multiple faces. You want to rotate around the normal to one of the faces. If that face is referenced in Ruby with “face”, you can use “face.normal”. That normal is a Sketchup Vector3d object. An example would be:
It would be clearer if you could provide an image or better a SketchUp model illustrating what you want to accomplish. The posts above all seem to be making guesses…
You can define the point as compoennt_instance.transformation.origin and the axis as component_instance.transformation.zaxis. The the component will be rotated around it’s blue axis.
If the axis defines the centre of the component already, then the axis is simply [0,0,1], transformed by the components transformation.
If the axis is defined by an edge, I find the edge this way…
c = 0
foundEdge = nil
group.entities.each { |e|
if e.class == Sketchup::Edge
edge = e
if edge.faces.length == 0
c = c + 1
foundEdge = edge
puts "Edge found"
end
end
}
if c != 1
UI.messagebox "This rubie requires a solitary edge within the group to define the axis of rotation",MB_OK
return 1
end
@centreOfRotation = foundEdge.start.position
@axisOfRotation = foundEdge.start.position.vector_to(foundEdge.end.position)
Note that depending on which way the edge was drawn, you may need a negative rotation angle.
In a model with one component only we have two coordinate systems. One is in the global scope and one is in the local system in the component. When we open the component then the coordinates are 0,0,1 (that make sense).
When I close the component and am watching the component from outer (global) scope, then the origin must be located somewhere.
Example with a cube
If I create a cube in global scope, 5m away from the origin:
ss = Sketchup.active_model.selection
ss.grep(Sketchup::ComponentInstance)
puts ss[0].transformation.origin
(0m, 5m, 0m)
So the origin is 0, 5, 0.
So the first argument should be 0, 5, 0 + 2.5, 2.5, 2.5 = 2.5, 7.5, 2.5
if group.class == Sketchup::Group
box = group.local_bounds
end
if group.class == Sketchup::ComponentInstance
box = group.definition.bounds
end
min = box.min
max = box.max
centreMin = [min.x+max.x)/2,(min.y+max.y)/2,min.z]
centreMax = [min.x+max.x)/2,(min.y+max.y)/2,max.z]
So centreMin, centreMax defines your centre line within the group, but these points will still need to be transformed by the group (or component) transformation.
I see. There is more ways how to calculate it. This math is very simple.
I did realized how easy it is when I have taken the cube and tried the ruby command to find position of the cube.
The risk of bounding box is, that there must not be any element which would extend the box (So expectation that there is only the polygon in the box makes it correct).