Honey, I Shrunk The Rect: Scaling

Scaling operations are dead simple. Since we’ve already used the preTranslate method earlier, let’s just go ahead and a method to scale the rect by 20%.

contentTransformMatrix.preScale(1.2F, 1.2F);

And that’s it! Scaling is done, right? Er, not quite…

The rect HAS become bigger, but it has also moved! Why would that happen? The reason is because we have not provided a reference point to the Matrix around which to perform the scale. The point is referred to as the Pivot. This point remains unchanged after performing matrix operations (except translations).

Let’s go ahead and select the top-left corner of the rect as the pivot for the scale operation. When the scale operation is applied, what we expect is that the top-left corner remains coinciding with the centre marker, but the rect itself is 20% larger.

We could use the left and top properties of the content rect, but keep in mind that we have already applied translations on the matrix. The pivot point we provide has to take into account the current transformation on the matrix.

So what we need to get is the left and top properties of the rectangle AFTER the translation is applied, but BEFORE the scale is applied. We have already used this method earlier to apply the matrix to the content rect. Let’s use it now and get the left and top properties to use as the pivot.

contentTransformMatrix.mapRect(mappedContent, content);

contentTransformMatrix.preScale(1.2F, 1.2F, mappedContent.left, mappedContent.top);

Let’s run this and see what we get!

Close, but not yet! Why does the top-left corner not coincide with the centre marker?

The reason is quite simple; We have translated the rect by half its width and height along X and Y, but after scaling, the actual width and height of the rect are 20% larger than they were before scaling, so obviously the translation values do not take the updated scale into account. What are our options to fix this?

Well, we could translate it again, but that is pretty cumbersome. Let’s look at another option. Remember earlier, when we talked about how pre and post operations are done with respect to the matrix’s current transformation? This is when this comes in handy.

We have used a preScale operation which will perform the scaling first, and then apply the translation values which the matrix has. Instead of using preScale , if we use the postScale operation instead, the translation will also be scaled appropriately and we should end up with the correct result. Let’s make the change and see what we get!

contentTransformMatrix.postScale(1.2F, 1.2F, mappedContent.left, mappedContent.top);

Phew! We finally got what we expected!

Before we move on to the third and final operation, let’s take a note of the important points about this section.

Whenever you do matrix operations, ALWAYS consider the pivot. Selecting the right pivot is crucial, and is something that often trips up people who begin working with matrixes

consider the pivot. Selecting the right pivot is crucial, and is something that often trips up people who begin working with matrixes Pivots need to take the current transformation of the matrix into account. Using one of the map functions of the Matrix class can be very helpful in calculating pivot points when chaining operations

functions of the class can be very helpful in calculating pivot points when chaining operations Choosing pre or post methods to perform operations can affect the final matrix. If your transformation doesn’t come out as expected, recheck the operations you’re using and confirm that the operations are selected correctly

Done? Let’s move on to the last and final part!