Background
I’m trying to understand matrix transformations. (Developing plugins for SketchUp using it’s Ruby API)
I’ve been setting up small experiments to split up the learning in small chunks so I can see what happens when I apply the various transformations and generally it’s been going well. I’m seeing how things work and I can take the rather abstract description of transformation matrices and translate them into what actually happens.
Question
But here something I’ve become stomped:
(We’re using 4×4 matrices here.)
I would like to scale a set of point along a given vector (or local coordinate system).
Say we have a square, offset [20,10] from the global origin, rotated 30 degrees. I would like to scale this square to be 2x in the X direction.
So we have a local scaling transformation:
local_scale = Geom::Transformation.scaling( 2, 1, 1 )
What I tried, and worked:
- Transform the points into the local coordinate system.
- Apply local scale transformation.
- Transform the points back into the global coordinate system.
I have tried this, and it works. However, I’m not happy with it. It requires me to iterate and transform my set of point three times. Doesn’t seem efficient. Remember I’m using a Ruby based API – things are slow and I am dealing with data sets of many thousands of points.
Can this be done?
Is there a way I can iterate and transform each point only once and get the correct result?
What I tried, and failed:
I tried combining the inverse transformation to the local co-ordinate with the local scaling, but that failed. (There clearly is something here about combining transformations I need to read up on – again.)
I thought that maybe this would work:
( local_coords_transformation.inverse * scaling ) * local_coords_transformation )
I thought this would transform my local scaling transformation into a transformation that worked in the global coordinate system. It didn’t – and I expect there’s a few of you shaking your heads right now.
Let me know if my explanation was unclear or if more background information is needed.
Ah! Got it working! 😀
local_coords_transformation * scaling * local_coords_transformation.inverseI got it wrong the first time because I didn’t realise the order of the transformation was reversed from how you’d describe it in English. When reading this Wikipeadia article I realised what was going wrong:
http://en.wikipedia.org/wiki/Transformation_matrix#Composing_and_inverting_transformations
Duh!