forked from: Wheel Count

by kawamura forked from Wheel Count (diff: 130)
さらに内積とか外積使って見ました。
左側が旧来の計算方法。
右側が内積、外積使った方法。
丸め誤差とか出て修正しないといけなかったりと、あんまりコードが綺麗になりませんでした。うーん。
♥0 | Line 221 | Modified 2013-08-01 20:44:41 | MIT License
play

ActionScript3 source code

/**
 * Copyright kawamura ( http://wonderfl.net/user/kawamura )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ocJ0
 */

package 
{
    import flash.display.Sprite;
    import flash.events.Event;
    
    /**
     * ...
     * @author Jaiko
     */
    public class Main extends Sprite 
    {
        
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            layout();
        }
        
        private function layout():void 
        {
            var wheel:Wheel = new Wheel();
            addChild(wheel);
            wheel.x = stage.stageWidth * (1/4);
            wheel.y = stage.stageHeight * 0.5;
            
            var crossProductWheel:CrossProductWheel = new CrossProductWheel();
            addChild(crossProductWheel);
            crossProductWheel.x = stage.stageWidth *(3/4);
            crossProductWheel.y = stage.stageHeight *0.5;
        } 
    }
}


import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;

/**
 * ...
 * @author Jaiko
 */
class Wheel extends Sprite 
{
    private var wheel:Sprite;
    private var theta:Number;
    private var vw:Number = 0;
    private var preTheta:Number;
    private var tf:TextField;
    private var isDown:Boolean = false;
    
    public function Wheel() 
    {
        if (stage) init();
        addEventListener(Event.ADDED_TO_STAGE, init);
    }
    
    private function init(e:Event = null):void 
    {
        removeEventListener(Event.ADDED_TO_STAGE, init);
        //
        layout();
    }
    
    private function layout():void 
    {
        var g:Graphics;
        wheel = new Sprite();
        addChild(wheel);
        g = wheel.graphics;
        g.beginFill(0xFF0000);
        g.drawCircle(0, 0, 100);
        var point:Sprite = new Sprite();
        wheel.addChild(point);
        g = point.graphics;
        g.beginFill(0xFFFFFF);
        g.drawCircle(0, 0, 10);
        point.y = -80;
        
        point = new Sprite();
        wheel.addChild(point);
        g = point.graphics;
        g.beginFill(0);
        g.drawCircle(0, 0, 1);
        //
        tf = new TextField();
        addChild(tf);
        tf.text = "0"
        tf.selectable = false;
        tf.mouseEnabled = false;
        theta = 0;
        wheel.buttonMode = true;
        wheel.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownListener);
        //
        addEventListener(Event.ENTER_FRAME, enterFrameListener);
    }
    
    private function mouseDownListener(e:MouseEvent):void 
    {
        isDown = true;
        preTheta = Math.atan2(this.mouseY, this.mouseX);
        stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpListener);
    }
    
    private function mouseUpListener(e:MouseEvent):void 
    {
        isDown = false;
        stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpListener);
    }
    
    private function enterFrameListener(e:Event):void 
    {
        if (isDown)
        {
            var currentTheta:Number = Math.atan2(this.mouseY, this.mouseX);
            var dw:Number = (currentTheta - preTheta);
            if (dw > Math.PI)
            {
                dw -= 2 * Math.PI;
            }
            else if (dw < -Math.PI)
            {
                dw += 2 * Math.PI;
            }
            vw = dw;
            theta += dw ;
            preTheta = currentTheta;
        }
        else
        {
            vw *= 0.98;
            theta += vw ;
        }
        wheel.rotation = (theta*(180/Math.PI))%360;
        
        tf.text = String(Math.floor(theta / (2*Math.PI)));
    }
}

class CrossProductWheel extends Sprite{
    private var wheel:Sprite;
    private var theta:Number;
    private var vw:Number = 0;
    private var preX:Number;
    private var preY:Number;
    private var tf:TextField;
    private var isDown:Boolean = false;
    public function CrossProductWheel()
    {
        if (stage) init();
        addEventListener(Event.ADDED_TO_STAGE, init);
    }
    
    private function init(e:Event = null):void 
    {
        removeEventListener(Event.ADDED_TO_STAGE, init);
        //
        layout();
    }
    
    private function layout():void
    {
        var i:uint;
        var n:uint;
        var g:Graphics;
        wheel = new Sprite();
        addChild(wheel);
        g = wheel.graphics;
        g.beginFill(0xFF0000);
        //g.drawCircle(0, 0, 100);
        g.moveTo(100*Math.cos(theta),100*Math.sin(theta));
        n = 360;
        for(i=0;i<= n;i++)
        {
            theta = 2*Math.PI *(i/n);
            g.lineTo(100*Math.cos(theta),100*Math.sin(theta));
            
        }
        var point:Sprite = new Sprite();
        wheel.addChild(point);
        g = point.graphics;
        g.beginFill(0xFFFFFF);
        g.drawCircle(0, 0, 10);
        point.y = -80;    
        
        point = new Sprite();
        wheel.addChild(point);
        g = point.graphics;
        g.beginFill(0);
        g.drawCircle(0, 0, 1);
        //
        tf = new TextField();
        addChild(tf);
        tf.text = "0"
        tf.selectable = false;
        tf.mouseEnabled = false;
        theta = 0;
        preX = this.mouseX;
        preY = this.mouseY;
        wheel.buttonMode = true;
        wheel.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownListener);
        //
        addEventListener(Event.ENTER_FRAME, enterFrameListener);
    }
    
    private function mouseDownListener(e:MouseEvent):void 
    {
        isDown = true;
        stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpListener);
    }
    
    private function mouseUpListener(e:MouseEvent):void 
    {
        isDown = false;
        stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpListener);
    }
    
    private function enterFrameListener(e:Event):void 
    {
        var ans:Number;
        var cos:Number
        var dTheta:Number = 0;
        //
        if (isDown)
        {
            //2つのベクトルのコサイン値
            cos = (this.mouseX * preX + this.mouseY * preY) / (Math.sqrt((this.mouseX * this.mouseX) + (this.mouseY * this.mouseY)) * Math.sqrt((preX * preX) + (preY * preY)));
            //なんだか止まってると2つのベクトルのコサン値が1以上になってしまうので。
            //-1以下にはどうもならないっぽい。
            if (cos > 1)
            {
                cos = 1;
            }
            vw = Math.acos(cos);
            //外積使って右回転か左回転かを判定
            ans = preX * this.mouseY - preY * this.mouseX;
            if(ans>0)
            {
                vw *= 1;
            }
            else if(ans<0)
            {
                vw *= -1;
            }
            theta += vw;
        }
        else
        {
            vw *= 0.98;
            theta += vw ;
        }
        wheel.rotation = (theta * (180 / Math.PI)) % 360;
        tf.text = String(Math.floor(theta / (2*Math.PI)));
        preX = this.mouseX;
        preY = this.mouseY;
    }
}