I've seen a lot of questions about rotation in AS3 lately so I thought I'd post a quick writeup. It's a deceptively simple formula but there are a couple snags that can trip you up if you aren't aware of them.
First off - Flash uses a fairly confusing rotational layout. A DisplayObject's rotation is measured in degrees from 0, which is at 3 O'Clock. Degrees extend clockwise to 9 O'Clock (180°) where an odd thing happens. Flash converts any number you pass in to the closest possible value to zero, so 181° gets recorded as -179°. This is still technically correct, but it can wreak havoc on your code if you're not expecting it.
Here's a quick method to get the positive angle back:
spinner.rotation = 181;
trace(spinner.rotation); // -179
var angle:Number = spinner.rotation; // -179
angle = (angle + 360) % 360 // 181
Alright - what people really want to know is how to calculate the angle between an object and the mouse, or another object. The solution is to take the arc-tangent of the offset in y, divided by the offset in x, which, if you remember your trig from highschool, would be the two perpendicular sides of your right triangle. Here's what the code looks like:
package {
/*
* Flash 10.0 ? ActionScript 3.0
* www.calypso88.com
*/
//--------------------------------------
// PACKAGES
//--------------------------------------
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.geom.Point;
import flash.events.Event;
public final class Arrow extends Sprite {
//--------------------------------------
// CONSTRUCTOR
//--------------------------------------
public function Arrow(){
super();
addEventListener(Event.ENTER_FRAME, enterFrame);
}
//--------------------------------------
// EVENT HANDLERS
//--------------------------------------
private function enterFrame(e:Event):void{
var p1:Point = new Point(this.x, this.y);
var p2:Point = new Point(stage.mouseX, stage.mouseY);
this.rotation = angleBetween(p2, p1);
}
//--------------------------------------
// PRIVATE & PROTECTED INSTANCE METHODS
//--------------------------------------
private function angleBetween(p1:Point, p2:Point):Number{
var deltaX:Number = p1.x - p2.x;
var deltaY:Number = p1.y - p2.y;
var angle:Number = Math.atan2(deltaY, deltaX); // in radians
return radiansToDegrees(angle);
}
private function radiansToDegrees(r:Number):Number{
return(r * (180 / Math.PI));
}
private function degreesToRadians(d:Number):Number{
return(d * (Math.PI / 180));
}
}
}
The last surprise is that the arc-tangent comes back in radians (π radians = 180° degrees) so you'll need to convert back to degrees before you set the rotation. Here is the final result applied to a few dozen arrows.
April 28th, 2010 at 2:51 am
[...] This post was mentioned on Twitter by net.art GIANT FUNNEL. net.art GIANT FUNNEL said: ? [from bitless] Calypso88 » Blog Archive » Rotating objects toward a point http://bit.ly/9YEhRk [...]
September 5th, 2010 at 12:52 am
Buy:Lipothin.SleepWell.Advair.Acomplia.Ventolin.Lipitor.Zocor.Prozac.Amoxicillin.Aricept.Lasix.Female Pink Viagra.Female Cialis.Benicar.Buspar.Seroquel.Nymphomax.Cozaar.Zetia.Wellbutrin SR….
September 6th, 2010 at 4:03 pm
Buy:100% Pure Okinawan Coral Calcium.Zyban.Accutane.Lumigan.Prednisolone.Actos.Zovirax.Prevacid.Nexium.Mega Hoodia.Human Growth Hormone.Retin-A.Valtrex.Synthroid.Arimidex.Petcam (Metacam) Oral Suspension….