Flex Rotation Around A Point Using a Matrix

Development, Flash, Flex January 21st, 2008

Earlier I posted Flex Rotation Around a Point which demonstrated an easy way to make sure an object is rotated around its center point whenever a rotation is applied.

Since then I received a comment about a method MatrixTransformer.rotateAroundInternalPoint that will rotate any object around one of its internal points. The only problem is unless you have flash CS3 and you want to import the library then you can’t use it.

So I decided to post my own methods that will rotate an object around an arbitrary point.

The code for rotateAroundInternalPoint is straight forward. First we start off with a method rotateAroundExternalPoint that modifies a matrix to rotate around a point in the objects parent coordinate space:

package com.joelconnett.geom
{
	import flash.geom.Matrix;
 
	public class FlexMatrixTransformer
	{
		public static function rotateAroundExternalPoint(m:Matrix, x:Number, y:Number, angleDegrees:Number):void
		{
			m.translate(-x, -y);
			m.rotate(angleDegrees*(Math.PI/180));
			m.translate(x, y);
		}
	}
}

The method is pretty simple. It translates the object to the origin offset by the distance to the point it is rotating around. Then it rotates the object and translates it back.

Now that we can rotate around an external point, rotating around an internal point is very simple.

package com.joelconnett.geom
{
	import flash.geom.Matrix;
	import flash.geom.Point;
 
	public class FlexMatrixTransformer
	{
		public static function rotateAroundInternalPoint(m:Matrix, x:Number, y:Number, angleDegrees:Number):void
		{		
			var p:Point = m.transformPoint(new Point(x, y));
			rotateAroundExternalPoint(m, p.x, p.y, angleDegrees);
		}
 
		public static function rotateAroundExternalPoint(m:Matrix, x:Number, y:Number, angleDegrees:Number):void
		{
			m.translate(-x, -y);
			m.rotate(angleDegrees*(Math.PI/180));
			m.translate(x, y);
		}
	}
}

Most of the work is being done in rotateExternalPoint. The only addition is first we are translating the internal point to the external coordinate space by calling transformPoint. Then we pass the transformed point to rotateAroundExternalPoint

So if we want to rotate and object around its center point it would look like this:

import com.joelconnett.geom;
 
var m:Matrix = objectToRotate.transform.matrix;
FlexMatrixTransformer.rotateAroundInternalPoint(m, objectToRotate.width / 2, objectToRotate.height / 2, 5);
objectToRotate.transform.matrix = m;

Click here for source

10 Responses to “Flex Rotation Around A Point Using a Matrix”

  1. In|Vent » Rotate On Center in Adobe Flex / ChadUpton.com Says:

    [...] you want to rotate around any point using a MatrixTransformer: Joel Connett has a great post on it here. I quite like that method, but I was looking for a more simple solution for center [...]

  2. ilya boyandin Says:

    It seems there is something wrong with this method. If you let it rotate for a long time (like few minutes) you’ll notice that the left square is moving towards the top left corner of the outer box.

  3. Joel Says:
    Yeah, I noticed that as well. I think it is probably due to floating point rounding errors. When I get a minute I’ll take a look at it.
  4. Joel Says:
    I updated the example to fix the drifting. I grabbed a snapshot of the objects matrix and used it to do the rotation. Seems to have fixed the problem.
  5. Kyle Says:

    Very sweet!

  6. Aral Balkan Says:

    Thanks, Joel, I’m using your class in an upcoming update to The GAE SWF Project and it’s been very useful! :)

  7. Joel Says:
    Aral,

    Glad to hear it! Now if Google would just let more developers in so I could play around with it!

  8. Picture this! at Aral Balkan Says:

    [...] also made use of Joel Connect’s FlexMatrixTransformer class (thanks, [...]

  9. Jay Says:

    Wow, you rocked my world! Rock on!

  10. Terry Says:

    Thanks, it’s great …
    But how to implement this to a control like Button, because the text/label was not drawn properly unless the rotation degree is 0. Say something like i want to make a button that the text/label is drawn horizontally but the button it self drawn vertically to 90 degrees. I found that it works great only for image and container and container that the children also a container.
    But if i look in the documentation (http://livedocs.adobe.com/flex/3/langref/mx/effects/Rotate.html#includeExamplesSummary) i found that i have to embed the font, and that’s already solve my problem for a while.

Leave a Reply