Shortest rotation to angle - speed test
Test the speed of the 4 functions (0 - is my written by me ":D).
Tested on my device : fastest : No.2
Results (650 arrows):
1st - No.2 [21fps ~ 48-52 MS]
2nd - No.0 [20fps ~ 49-53 MS]
3rd - No.1 [13fps ~76-83 MS]
Last - No.3 [12fps ~ 86-90 MS]
/**
* Copyright WLAD ( http://wonderfl.net/user/WLAD )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/6QOT
*/
package {
import flash.events.MouseEvent;
import flash.display.Sprite;
import com.bit101.components.PushButton;
import net.hires.debug.Stats;
public class ShortestRotationSpeedTest extends Sprite {
private var functions:Vector.<Function>;
private var btnsArwCount:Vector.<PushButton>;
private var btnsFunc:Vector.<PushButton>;
private var btn:PushButton;
private var arrowsLayer:Sprite;
private var arrows:RotatingArrows;
private var selected:uint = 0;
public function ShortestRotationSpeedTest()
{
functions = new Vector.<Function>();
btnsArwCount = new Vector.<PushButton>();
btnsFunc = new Vector.<PushButton>();
graphics.beginFill(0xFEE285);
graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
graphics.endFill();
//*****************
//FUNCTIONS TO TEST
functions.push(myRotFunc);
functions.push(rotFunc1);
functions.push(rotFunc2);
functions.push(getShortestRotationAngle);
//*****************
//Bottom of the display list
arrowsLayer = new Sprite();
addChild(arrowsLayer);
var st:Stats = new Stats();
addChild(st);
st.scaleX = st.scaleY = 1.4;
st.alpha = .9;
st.x = stage.stageWidth - st.width;
stage.frameRate = 240;
btn = new PushButton();
for(var i:int = 0; i < functions.length; ++i)
{
btn = new PushButton(this,
i * (btn.width + 5) + 5, stage.stageHeight - btn.height - 5,
"Method " + i.toString(), swapFunction
);
btn.toggle = true;
btnsFunc.push(btn);
}
btn = new PushButton();
btn.width = 70;
for(i = 5; i >= 0; --i)
{
btn = new PushButton(this,
i * (btn.width + 5) + 5, stage.stageHeight - (btn.height + 5) * 2,
"Count: " + (i * 100 + 150).toString(), changeCount
);
btn.width = 70;
btn.toggle = true;
btnsArwCount.push(btn);
}
selectFunc(selected);
}
private function swapFunction(e:MouseEvent):void
{
btn = (e.target as PushButton);
var s:String = (btn.label as String);
selected = int(s.charAt(s.length - 1));
selectFunc(selected);
}
private function changeCount(e:MouseEvent):void
{
btn = (e.target as PushButton);
var s:String = (btn.label as String);
s = s.substring(s.indexOf(":") + 1);
numOfArrows = int(s);
selectFunc(selected);
}
private function selectFunc(index:int):void
{
for(var i:int = btnsFunc.length - 1; i >= 0; --i)
{
btn = btnsFunc[i];
btn.selected = (i == index);
btn.enabled = !btn.selected;
}
var s:String;
for(i = btnsArwCount.length - 1; i >= 0; --i)
{
btn = btnsArwCount[i];
//s = (btn.label as String);
//btn.label = s.indexOf(":").toString();
btn.selected =
(int(btn.label.substring(btn.label.indexOf(":") + 1)) == numOfArrows);
btn.enabled = !btn.selected;
}
if(arrows) arrows.dispose();
arrows = new RotatingArrows( functions[index] );
arrowsLayer.addChild(arrows);
}
}
}
import flash.events.Event;
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.display.Shape;
///-------------------------
/// GLOBAL VARIABLES |
///-------------------------
// 5 degrees per frame.
const speed:Number = 5;
// amount of arrows to display on screen
var numOfArrows:uint = 150;
//Arrows color
var arrowColor:uint = 0x0;
///-----------------------
/// TEST FUNCTIONS |
///-----------------------
//http://board.flashkit.com/board/showthread.php?766397-AS3-Finding-shortest-distance-to-angle-(ccw-or-cw)
function rotFunc1(alpha:Number,beta:Number):Number
{
if(arrowColor != 0xF22207) arrowColor = 0xF22207;
// convert the difference between the two angles to radians
var diff:Number = (beta-alpha)*(Math.PI/180);
// find the rotation of the vector created by the sin and cos of the difference
var rotationDifference:Number = Math.atan2(Math.sin(diff),Math.cos(diff));
// return the rotation delta
return Math.max(Math.min((180/Math.PI)*rotationDifference,speed),-speed);
}
//http://www.kongregate.com/forums/4/topics/99824
function rotFunc2(alpha:Number, beta:Number):Number
{
if(arrowColor != 0x68F516) arrowColor = 0x68F516;
var deltaAngle:int = (beta - alpha) % 360;
if (deltaAngle)
{
if (deltaAngle < -180) deltaAngle += 360;
else if (deltaAngle > 180) deltaAngle -= 360;
if (deltaAngle < 0) return -speed; else return speed;
}
return 0;
}
// My function - Turn turrent
///r - rotation = alpha, t = target rotation = beta.
function myRotFunc(r:int, t:int):int
{
//var _turrentTurnSpeed:Number = 360 / (_period * _container.stage.frameRate);
if(arrowColor != 0x166FF5) arrowColor = 0x166FF5;
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;
}
//_turrent.rotation += speed * dir;
if(m <= speed)
{
//_turningTurrent = false;
//_turrent.rotation = _turentRotationTarget;
//_hull.rotation = _turentRotationTarget;
return 0;
}
return speed * dir;
}
//http://snipplr.com/view/66272/
function getShortestRotationAngle(from : Number, to : Number) : Number
{
if(arrowColor != 0xD916F5) arrowColor = 0xD916F5;
var currRotation : Number = from;
var newCourse : Number = to;
var pi2:Number = Math.PI / 180;
var shortestAngle : Number = currRotation * pi2;
var curCos:Number = Math.cos( shortestAngle );
var curSin:Number = Math.sin( shortestAngle );
shortestAngle = newCourse * pi2;
var newCos:Number = Math.cos( shortestAngle );
var newSin:Number = Math.sin( shortestAngle );
shortestAngle = (180 / Math.PI) * Math.atan2(
(
curCos * newSin - curSin * newCos
) ,
(
Math.sin( currRotation * pi2 ) * Math.sin(newCourse * pi2) +
Math.cos(currRotation * pi2) * Math.cos(newCourse * pi2)
)
);
return Math.max(Math.min( shortestAngle ,speed),-speed);
}
///--------------------------------
/// ARROW & ARROW CONTAINER |
///--------------------------------
// ..
// ....... ..
// . ..
// . ..
// . ..
// ....... ..
// ..
class RotatingArrows extends Sprite
{
private var arrws:Vector.<Arrow>;
private var rotFunc:Function;
private var arw:Arrow;
public function RotatingArrows(func:Function):void
{
rotFunc = func;
//Refresh arrow color.
func(0,0);
arrws = new Vector.<Arrow>;
this.addEventListener(Event.ADDED_TO_STAGE,init);
}
private function init(e:Event):void
{
this.removeEventListener(Event.ADDED_TO_STAGE,init);
initArrows();
intiEvents();
}
private function initArrows():void
{
var count:uint = uint(Math.sqrt(numOfArrows));
var sw:Number = stage.stageWidth;
var sh:Number = stage.stageHeight;
arw = new Arrow();
var scale:Number = 400 / Math.max(400,numOfArrows);
for(var i:int = count - 1; i >= 0; --i)
{
for(var j:int = count - 1; j >= 0; --j)
{
arw = new Arrow();
arw.x = 20 + sw * (j / count);
arw.y = 20 + sh * (i / count);
addChild(arw);
arrws.push(arw);
arw.scaleX = arw.scaleY = scale;
}
}
}
private function intiEvents():void
{
this.addEventListener(Event.ENTER_FRAME, onFrame);
}
private function onFrame(e:Event):void
{
var r:Number;
for(var i:int = arrws.length - 1; i >= 0; --i)
{
arw = (arrws[i] as Arrow);
r = getMouse(arw);
for(var j:int = 200; j >= 0; --j)
rotFunc( arw.rotation , r )
arw.rotation += rotFunc( arw.rotation , r );
}
}
private function getMouse(d:DisplayObject):Number
{
return Math.atan2(stage.mouseY - d.y, stage.mouseX - d.x) * 180 / Math.PI;
}
public function dispose():void
{
rotFunc = null;
removeEventListener(Event.ENTER_FRAME, onFrame);
if(parent)
parent.removeChild(this);
while(numChildren > 0)
removeChildAt(arrws.pop());
}
}
class Arrow extends Shape
{
public function Arrow()
{
graphics.lineStyle(4,0x0);
graphics.beginFill( arrowColor );
// (3).
// (1)...(2) ..
// . ..
// . (4)
// . ..
// (7)...(6) ..
// (5).
graphics.moveTo(-10,-7); // (1)
graphics.lineTo(2,-7); // (2)
graphics.lineTo(2,-15); // (3)
graphics.lineTo(15,0); // (4)
graphics.lineTo(2,15); // (5)
graphics.lineTo(2,7); // (6)
graphics.lineTo(-10,7); //(7)
graphics.lineTo(-10,-7); // (1)
graphics.endFill();
}
}