To find center or axis of component to be rotated

Sketchup reference states:

Class: Geom::Transformation.rotation(point, vector, angle) ⇒ Geom::Transformation

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.

no, it’s internally radians, you need to convert angle = 45.degrees to use degrees…

john

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:

  rotation_transform = Geom::Transformation.rotation( center_point, face.normal, 10.degrees )

The constructor takes the angle in radians, but I converted 10 degrees into radians.

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…

I am working on script which will copy tube/circle/polygon and then it will rescale the duplicate by 0.98, 0.98,1 and then I will rotate it by 30°.

test.skp (88.9 KB)
file

I placed axis into the component to define it’s center. Now I would like to rotate the component about blue axis.

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.

OK, but how can I get the position of the axis in the component? There should be some method for that?

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.

Do you mean in the local coordinate system within the component? That is just Z_AXIS constant (or Geom::Vector3d.new(0, 0, 1) to define it anew).

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

That was very clear!

Your centre line is defined by the bounding box.

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).

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.