Determine scale factors for rotated groups


#1

If a group is not rotated I can compare bounds to local_bounds to see if user has scaled the group and by how much in x, y and z. ( I can do similar for component instances.)
This doesn’t work if the group has been rotated. How can I tell xscale, yscale and zscale for a rotated group?

Barry Milliken


#2
tr=group.transformation.to_a
xscale = Math::sqrt(tr[0]*tr[0]+tr[1]*tr[1]+tr[2]*tr[2])
yscale = Math::sqrt(tr[4]*tr[4]+tr[5]*tr[5]+tr[6]*tr[6])
zscale = Math::sqrt(tr[8]*tr[8]+tr[9]*tr[9]+tr[10]*tr[10])

Add dimensions in sketchup using ruby
#3

Thanks, I’ll try it out.


#4

Wonderful! Now I want to apply new scale factors.in the group’s local x y and/or z direction.
PLAN A: steps

  1. transform the group by its inverse transform,
  2. use bounds to calculate pt at center of local XY bound.
  3. transform about center pt using new scale factors as ratios of the existing ones.
  4. apply original transform to get back to original position and rotation.
    PLAN B
    Use Pythagoras and trig to transform the group in place.

Which would you do?


#5

Suggest PLAN A:
You don’t need to take the inverse if you use the following:

center = group.local_bounds.center
scaling = Geom::Transformation.scaling(center, xscale, yscale, zscale)
group.transformation = group.transformation * scaling

The “transformation=” assigns a rigid transformation. With the “scaling” variable last in the multiplication, the center position is in the group’s transformation’s local or intrinsic coordinates.
Note: If you really meant a Sketchup component instance, then the bounding box’s center is would be accessed through “entity.definition.bounds.center”.

Your inverse suggestion would work with an affine transformation:

group.transform! group.transformation * scaling * group.transformation.inverse

After the transformation update, Edit…Undo will undo the simple scaling, and Edit…Redo re-apply it. Since the “transformation=” and “transform!” append Sketchup’s “Edit…Undo” menu option, recommended practice is to wrap them with start and commit operations:

Sketchup.active_model.start_operation("Barry's Scaling")
. . . code that affects undo operations
Sketchup.active_model.commit_operation

That would set the menu undo option to “Undo Barry’s Scaling”. Additional recommended practice is to include exception handling that calls “.abort_operation” if an error is raised.

The few statements of code do the Pythagoras and trig for you without any trig, as it just involves matrix multiplication.