In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

# FF: Rotate to angle, optimized and removed error

```Calculate shortest distance to target angle / rotation given the specific velocity

-------------------------------------------------------------------------------
function rotateAngle( currentAngle:Number, targetAngle:Number, angularVelocity:Number = 1 ):Number
{
angleMin = currentAngle < targetAngle ? currentAngle : targetAngle;
angleMax = currentAngle > targetAngle ? currentAngle : targetAngle;
// angular difference
distance = angleMax - angleMin;

// distance from inverted unit circle
inverse = 360 - distance;

// calc native direction
direction = currentAngle > targetAngle ? (+1) : (-1) ;

// when distance is less then inverted distance, the direction will become inverted.
return distance <= angularVelocity ? 0 : angularVelocity * direction * ( distance < inverse ? -1 : 1 );
}
-------------------------------------------------------------------------------

// controls : click to pause, right-click to update on pause```
```/**
*/

/// @mxmlc -swf-version 15
// forked from WLAD's Shortest rotation to angle - speed test
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.geom.Point;
[SWF(width="465", height="465")]
public class MXMLC extends Sprite {

private var angleMin:Number;
private var angleMax:Number;
private var distance:Number;
private var inverse:Number;
private var direction:int;

///---------------------------
///    ORIGINAL FUNCTION     |
///---------------------------
/*
source : http://wonderfl.net/c/6QOT

/// r - rotation = alpha, t = target rotation = beta.
private function myRotFunc(r:int, t:int, spd:Number = 1 ):Number
{
var trMx:int = t > r ? t : r;
var trMn:int = t < r ? t : r;
var m:int = trMx - trMn;
var s:int = 360 - trMx + trMn;
//var dir:int = (r > t ? 1 : -1) * (m > s ? 1 : -1);
//m = m < s ? m : s;
var dir:int = (r > t ? 1 : -1);
if(m > s)
{ m = m; }
else
{ m = s; dir = -dir; }
return m <= spd ? 0 : spd * dir;
}
*/
///-----------------------
///    NEW FUNCTION      |
///-----------------------
private function rotateAngle( currentAngle:Number, targetAngle:Number, angularVelocity:Number = 1 ):Number
{
angleMin = currentAngle < targetAngle ? currentAngle : targetAngle;
angleMax = currentAngle > targetAngle ? currentAngle : targetAngle;
// angular difference
distance = angleMax - angleMin;

// distance from inverted unit circle
inverse = 360 - distance;

// calc native direction
direction = currentAngle > targetAngle ? (+1) : (-1) ;

// when distance is less then inverted distance, the direction will become inverted.
return distance <= angularVelocity ? 0 : angularVelocity * direction * ( distance < inverse ? -1 : 1 );
}
///---------------
///    UPDATE    |
///---------------
private function update(e:*=null):void
{
var mouseAngle:Number = Math.atan2( stage.mouseY - arrow.y, stage.mouseX - arrow.x );

var a:Number = arrow.rotation;
var b:Number = mouseAngle * 180 / Math.PI;

var delta:Number = rotateAngle( a, b, 5.33333  );

if( delta == 0 ) arrow.rotation = b;

else arrow.rotation += delta;

debugDraw();
};

///-----------------------
///    DISPLAY           |
///-----------------------
private var w:int;
private var h:int;
private var tx:TextField;
private var arrow:Sprite;
private var canvas:Sprite;
private var run:Boolean;

public function MXMLC ()
{
// init stage
stage.align = 'tl';
stage.scaleMode = 'noScale';
stage.frameRate = 40;
w = stage.stageWidth;
h = stage.stageHeight;
graphics.beginFill(0x26274A);
graphics.drawRect(0,0,w,h*0.4);
graphics.endFill();
graphics.beginFill(0xFEE285);
graphics.drawRect(0,h*0.4,w,h);
graphics.endFill();

// text
var ft:TextFormat = new TextFormat();
ft.size = 22;
ft.color = 0xD6E2D6;
ft.leftMargin = 30;
ft.letterSpacing = 4;
ft.tabStops = [232];
tx = new TextField();
tx.textColor = 0xFFFFFF;
tx.mouseEnabled = false;
tx.defaultTextFormat = ft;
tx.setTextFormat( ft );
tx.y = 20;
tx.width = ( w );
tx.height = ( h * 0.4 );

///---------------
///    ARROW     |
///---------------
arrow = new Sprite();
arrow.scaleX = arrow.scaleY = 4;
arrow.x = w >> 1;
arrow.y = h * 0.7;
arrow.graphics.lineStyle(2,0x0);
arrow.graphics.beginFill( 0xC6F327 );
//       (3).
// (1)...(2) ..
// .           ..
// .             (4)
// .           ..
// (7)...(6) ..
//       (5).
arrow.graphics.moveTo(-15,-7); // (1)
arrow.graphics.lineTo(2,-7); // (2)
arrow.graphics.lineTo(2,-15); // (3)
arrow.graphics.lineTo(15,0); // (4)
arrow.graphics.lineTo(2,15); // (5)
arrow.graphics.lineTo(2,7); // (6)
arrow.graphics.lineTo(-15,7); //(7)
arrow.graphics.lineTo(-15,-7); // (1)
arrow.graphics.endFill();
arrow.graphics.lineStyle(1,0x0);
arrow.graphics.drawCircle( 0, 0, 2 ); // pivot

// canvas
canvas = new Sprite();
canvas.x = arrow.x;
canvas.y = arrow.y;

// stage events
run = true;
stage.addEventListener('enterFrame', function(e:*):void {if (!run) return; update(); });
} // constractor
private function debugDraw():void
{
// Trace data
tx.text = "angleMin\t" + angleMin.toFixed(2) +
"\n" +      "angleMax\t" + angleMax.toFixed(2) +
"\n" +      "distance\t" + distance.toFixed(2) +
"\n" +      "inverse\t" + inverse.toFixed(2) +
"\n" +      "direction\t" + direction.toFixed(2);
// Draw data
canvas.graphics.clear();
canvas.graphics.lineStyle( 2, 0xFFFFFF );
canvas.graphics.drawCircle( 0,0,120 );
// Draw data - mouse angle
var p:Point = Point.polar( 10, Math.atan2( stage.mouseY - arrow.y, stage.mouseX - arrow.x ));
canvas.graphics.lineStyle( 4, 0xFF0000 );
p.normalize( 100 );
canvas.graphics.moveTo(p.x, p.y);
p.normalize( 150 );
canvas.graphics.lineTo(p.x, p.y);
} // debugDraw
} // class
} // package```