forked from: Wheel Count
forked from Wheel Count (diff: 130)
さらに内積とか外積使って見ました。 左側が旧来の計算方法。 右側が内積、外積使った方法。 丸め誤差とか出て修正しないといけなかったりと、あんまりコードが綺麗になりませんでした。うーん。
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;
}
}
