Dead Code Preservation :: Archived AS3 works from wonderfl.net

回転砲台のアルゴリズム

回転砲台のアルゴリズム
* どっちに回したほうが近いか、やり方をよく忘れるのでメモ
Get Adobe Flash player
by alumican_net 27 Apr 2010
/**
 * Copyright alumican_net ( http://wonderfl.net/user/alumican_net )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/t6u8
 */

/**
 * 回転砲台のアルゴリズム
 * どっちに回したほうが近いか、やり方をよく忘れるのでメモ
 */
package
{
    import flash.display.Graphics;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import com.bit101.components.*;
    
    public class RotationPath extends Sprite
    {
        /**
         * 右回りと左回りでどっちが近いか計算する
         * 
         * @param startAngle  開始角度(rad)
         * @param targetAngle 終了角度(rad)
         * return 差分の角度
         */
        public function calc(startAngle:Number, targetAngle:Number):Number
        {
            var angle0:Number = startAngle  % PI2;
            var angle1:Number = targetAngle % PI2;
            if (angle0 < 0) angle0 += PI2;
            if (angle1 < 0) angle1 += PI2;
            
            var d:Number = angle1 - angle0;
            if (d < 0 ) d += PI2;
            if (d > PI) d -= PI2;
            
            return d;
        }
        
        
        
        
        
        private const PI:Number        = Math.PI;
        private const PI2:Number       = PI * 2;
        private const TO_DEGREE:Number = 180 / PI;
        private const TO_RADIAN:Number = PI / 180;
        
        private var _canvas:Sprite;
        private var _center:Sprite;
        private var _handle_0:Handle;
        private var _handle_1:Handle;
        private var _label:Label;
        private var _title:String;
        
        public function RotationPath():void
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            
            _canvas = addChild( new Sprite() ) as Sprite;
            
            //中心点
            _center   = addChild( new Sprite() ) as Sprite;
            _center.x = stage.stageWidth  * 0.5;
            _center.y = stage.stageHeight * 0.5;
            _center.graphics.beginFill(0x0);
            _center.graphics.drawCircle(0, 0, 5);
            _center.graphics.endFill();
            
            //ハンドル
            _handle_0 = addChild( new Handle(stage, update, 0xff0000) ) as Handle;
            _handle_1 = addChild( new Handle(stage, update, 0x0000ff) ) as Handle;
            
            _title = "SHORTEST ANGULAR PATH FROM RED POINT TO BLUE POINT";
            _label = new Label(this, 10, 10, "");
            
            update();
        }
        
        public function update():void
        {
            var g:Graphics = _canvas.graphics;
            
            var cx:Number  = _center.x;
            var cy:Number  = _center.y;
            
            var x0:Number  = _handle_0.x;
            var y0:Number  = _handle_0.y;
            
            var x1:Number  = _handle_1.x;
            var y1:Number  = _handle_1.y;
            
            var angle0:Number = Math.atan2(y0 - cy, x0 - cx);
            var angle1:Number = Math.atan2(y1 - cy, x1 - cx);
            
            var angle:Number = calc(angle0, angle1);
            _label.text = _title + "\n\n"
                        + "START ANGLE : " + (angle0 * TO_DEGREE) + "\n"
                        + "TARGET ANGLE : " + (angle1 * TO_DEGREE) + "\n\n"
                        + "SHORTEST ANGULAR PATH : " + (angle  * TO_DEGREE);
            
            g.clear();
            g.lineStyle(0, 0xcccccc);
            g.moveTo(cx, cy);
            g.lineTo(x0, y0);
            g.moveTo(cx, cy);
            g.lineTo(x1, y1);
        }
    }
}

import flash.display.Sprite;
import flash.display.Stage;
import flash.events.MouseEvent;
import flash.geom.Rectangle;

internal class Handle extends Sprite
{
    private var _stage:Stage;
    private var _update:Function;
    
    public function Handle(stage:Stage, update:Function, color:uint):void
    {
        _stage = stage;
        _update = update;
        
        graphics.beginFill(0x0, 0);
        graphics.drawCircle(0, 0, 10);
        graphics.endFill();
        graphics.beginFill(color);
        graphics.drawCircle(0, 0, 5);
        graphics.endFill();
        
        var margin:Number = 30;
        x = margin + Math.random() * (stage.stageWidth  - margin * 2);
        y = margin + Math.random() * (stage.stageHeight - margin * 2);
        
        addEventListener(MouseEvent.MOUSE_DOWN, _mouseDownHandler);
        buttonMode = true;
    }
    
    private function _mouseDownHandler(e:MouseEvent):void
    {
        startDrag(false, new Rectangle(0, 0, _stage.stageWidth, _stage.stageHeight));
        stage.addEventListener(MouseEvent.MOUSE_UP, _mouseUpHandler);
        stage.addEventListener(MouseEvent.MOUSE_MOVE, _mouseMoveHandler);
    }
    
    private function _mouseUpHandler(e:MouseEvent):void
    {
        stopDrag();
        stage.removeEventListener(MouseEvent.MOUSE_UP, _mouseUpHandler);
        stage.removeEventListener(MouseEvent.MOUSE_MOVE, _mouseMoveHandler);
    }
    
    private function _mouseMoveHandler(e:MouseEvent):void
    {
        _update();
    }
}