Compound Transformation
-
I've been reading the thread "A way to avoid that ?" in order to stop a long script I'm writing to cause Sketchup to "not respond" and I'm starting by speeding up my script by following thomthom's advice here :http://forums.sketchucation.com/viewtopic.php?f=180&t=34205&hilit=not+responding&start=0#p301004
I was wondering if it was possible to apply one transform to another. For example, I have trans = Geom::Transformation.translation(vect1) and rot = Geom::Transformation.rotation(vect2) (these arguments may not make sense but it's not what's important), and I want to do something like trans.transform!(rot) so that both transformations are in one, which I can then apply to entities.
Thanks.
-
@thedro said:
I've been reading the thread "A way to avoid that ?" in order to stop a long script I'm writing to cause Sketchup to "not respond" and I'm starting by speeding up my script by following thomthom's advice here :http://forums.sketchucation.com/viewtopic.php?f=180&t=34205&hilit=not+responding&start=0#p301004
I was wondering if it was possible to apply one transform to another. For example, I have trans = Geom::Transformation.translation(vect1) and rot = Geom::Transformation.rotation(vect2) (these arguments may not make sense but it's not what's important), and I want to do something like trans.transform!(rot) so that both transformations are in one, which I can then apply to entities.
Thanks.You CAN apply a combination of transformations using ''.
tr = tr3 * tr2 * tr1
NOTE that the first transformation [tr1] should be last in the '' as the order of application is right to left... it is not 'commutative', so changing the order of the transformations will change the result.
The order in which many types of transformations is done is important as results will vary - just the same as if you were to manually rotate something about a point and then move it would give a different result from first moving and then rotating it about the same point... -
Thanks, TIG. So is this missing from the API docs? The * method for transformations only shows its use with a Point3d as an input argument.
-
@thedro said:
Thanks, TIG. So is this missing from the API docs? The * method for transformations only shows its use with a Point3d as an input argument.
Not really... it just doesn't have any decent examples...
It does say, "The * method is used to do matrix multiplication ..."
A transformation is a 16 element matrix, so to combine two transformations you do
m = m2 * m1 where m is the combined [multiplied] matrix - or as 'tr' if they are 'transformation' objects... -
@tig said:
@thedro said:
Thanks, TIG. So is this missing from the API docs? The * method for transformations only shows its use with a Point3d as an input argument.
Not really... it just doesn't have any decent examples...
It does say, "The * method is used to do matrix multiplication ..."
A transformation is a 16 element matrix, so to combine two transformations you do
m = m2 * m1 where m is the combined [multiplied] matrix - or as 'tr' if they are 'transformation' objects...NB The VERY important feature of multiply with matrices is that it is "non-commutative".
So whereas with regulars numbers,
a * b
is the same result asb * a
, with matrices it is not. If you're struggling to get your head around that, imagine the difference between turning to your left (rotation) then walking forward 10 steps (translation) compared to walking forward 10 steps (translation) followed by turning to your left (rotation).Other than that, as TIG says, you can build any transformation you like by multiply each simple stage of it together.
Adam
-
Ya I got it to work, thanks. Do you know if it's possible to separate the scaling part of a transformation from the translation and rotation parts?
-
@thedro said:
Ya I got it to work, thanks. Do you know if it's possible to separate the scaling part of a transformation from the translation and rotation parts?
That's a weird question ?
You just asked how to join them together ??
As explained the order of the transformations is very important as that affects the result.
You CAN do each transformation in turn, quite separately.
You can join then end to end [as explained] with the first one on the right hand end...
If you want to do a scaling that's separate from the rest then just specify the scaling transformation separately and ensure that it works after all of the other adjustments that have been done before it -
Tig, Thanks for the lesson.
-
Sorry, I realize how unclear that was since wanting to separate isn't related to the same situation as combining them. In one part of a script I've written, I want to combine two transformations but elsewhere in the script, I would like to get the transformation of a group for example and separate the scaling part of it from the rest. I hope this makes more sense.
-
@thedro said:
Sorry, I realize how unclear that was since wanting to separate isn't related to the same situation as combining them. In one part of a script I've written, I want to combine two transformations but elsewhere in the script, I would like to get the transformation of a group for example and separate the scaling part of it from the rest. I hope this makes more sense.
Aaah...
That is the most complex part look at this... http://forums.sketchucation.com/viewtopic.php?p=190874#p190874 it's various ways of extracting, cloning and inserting aspects of transformations.......... -
@thedro said:
Sorry, I realize how unclear that was since wanting to separate isn't related to the same situation as combining them.
How very true. In the math world this is generally called matrix decomposition, and there are various schemes to do so depending on what information you're looking to extract. Some information is really easy to find, others are very hard.
Scaling isn't to bad however. If you use the transforms .to_a method you'll get a 16 number array. It's best to think of this array as a 4x4 grid, with each group of four entries being one column of the matrix. The reason for this is that you can then interpret each column meaningfully by looking at your axis will change with respect to the transformation. If you think of your coordinate system as an x, y and z-axis together with an origin, then the first column is your x-axis, the second your y-axis, and the third your z-axis and the last column the origin. The only trouble here is that all of the columns have four entries while each of those vectors should only have three. This is pretty easy to resolve however since the last entry of the first three columns will always be 0, and the last entry of the final column will almost always be 1.
I say almost always because there is one important exception, which is that if you use use the Transformation.scaling method, then this entry will be the reciprocal of the scaling factor. So for example Geom::Transformation.scaling(2).to_a[-1] will return 0.5, which is 1/2. This somewhat complicates finding the scale factor in that you can't just look at the length of the x-axis in the transformation to find the x-axis scaling, but you can however divide by the this value to achieve the full scaling in that direction. In general you can always take a transformation's array and divide each entry by the value in that last column to "normalize" the last value to 1 without actually changing how the transformation works. I won't bore you with the logic behind why they use this scheme, just know that it simplifies the math behind a number of common operations in computer graphics so they aren't just trying to invoke your wrath.
Advertisement