Maybe I’m missing something.
To rotate a group about its Z access, for example, I can query its zaxis to return its vector3D:
zvector3D = group1.transformation.zaxis
Then find it’s center point3d:
centerpoint3D = group1.bounds.center
Then create a transform that can be used to do the rotation directly:
t = Geom::Transformation.rotation centerpoint3D, zvector3D, angle
This works (I think) no matter how deeply nested the group is within arbitrarily transformed parent groups.
:
However, to Scale the same group, there is no option to scale along a vector. You can only scale along the global X, Y, or Z axes. So for scaling I first have to inverse the group’s (nested) transforms, then do the scaling, then reapply to nested transforms.
But maybe I’m missing something?
To scale along a vector, you can rotate the entity so that the “desired vector” is in the same direction as an arbitrarily chosen axis (for example the “.xaxis”). Then, apply a non-uniform scaling transform on the X axis (e.g. Y and Z scale factors are 1) about the center point. Finally, apply the inverse of the rotation so that it rotates the entity back to its original orientation. It could be done as follows:
entity.transform! rotation.inverse * scaling * rotation
The scaling transformation is simple, the rotation on the other hand will need to have the rotation vector obtained from a cross product, and the angle to rotate using the Vector3d class’s “angle_between” method. (As a side note, the entity’s resulting transformation will be a “skew”.).
I remember reading somewhere that the plugin “FredoScale” accomplishes scaling along a vector (as well as many other things), I haven’t tried it, and I’m unable to confirm that with an internet search.