Murayama blog.

プログラミングと、その次の話

オブジェクトの回転


今日は第10章の座標回転と角度に対する跳ね返りを勉強しました。
今まで「第9章」とか「第10章」とかブログに書いてきたけど、
正確には「Chapter 9」とか「Chapter 10」やねんな。


はい。


さて、この章(Chapter)1つ目のお題は、オブジェクトの回転。
実行結果はこういうので、この章に入るまでの知識でどうにかなるプログラムです。

サイズがびみょうなのは気にしない。


で、今まではこんなコード書いていました。
X = 半径 * cos(角度)、Y = 半径 * sin(角度)
角度(angle)が加算されていくことで、回転運動が発生するわけです。
コードの主要な部分だけ抜粋。

	private var radious:Number = 100;
	private var angle:Number = 0;
	private var vr:Number = 0.05;

	private function onEnterFrame(e:Event):void
	{
		var centerX:Number = 100;
		var centerY:Number = 100;
		// 中心 + cos sin * 半径
		ball.x = centerX + Math.cos(angle) * radious;
		ball.y = centerY + Math.sin(angle) * radious;
		angle += vr
	}


で、もちろんこのやり方でも全然いいのだけれど、
この章では、別の方法で回転運動を説明している。

	private var vr:Number = 0.05;
	private var cos:Number = Math.cos(vr);
	private var sin:Number = Math.sin(vr);

	private function onEnterFrame(e:Event):void
	{
		var centerX:Number = 100;
		var centerY:Number = 100;

		// 中心までの距離
		var x1:Number = ball.x - centerX;
		var y1:Number = ball.y - centerY;

		// 公式だと思って覚える
		var x2:Number = cos * x1 - sin * y1;
		var y2:Number = cos * y1 + sin * x1;

		ball.x = centerX + x2;
		ball.y = centerY + y2
	}


えぇ。正直、けっこう意味がわからなくなってきています。
Keith(著者)も正直、意味はわからん、的なことを書いています。覚えるべし、と。
とくに

		var x2:Number = cos * x1 - sin * y1;
		var y2:Number = cos * y1 + sin * x1;

の部分が重要な公式で、座標回転のために有効だそうです。
座標回転はこの次に習うテーマ。


このコードは、cosとsinという変数を使っていて、
変数の中のデータは変化しません。
結果的に、vr:Number = 0.05;のスピードで回転運動が発生します。
また、cosとsinの計算が1度だけで済むというのもポイントです。
当たり前だけど、無駄な計算を省くのはパフォーマンス向上につながります。
サンプルでは1つのオブジェクトを回転させているだけだけど、
複数のオブジェクトを回転させる場合には特に重要になってくるようです。


以下、コードです。

package
{	
import flash.display.*;
import flash.events.*;

public class Rotate2 extends Sprite
{
	private var ball:Ball;
	private var vr:Number = 0.05;
	private var cos:Number = Math.cos(vr);
	private var sin:Number = Math.sin(vr);	
	
	public function Rotate2()
	{
		init();
	}
	
	private function init():void
	{
		ball = new Ball();
		ball.x = 160
		ball.y = 160
		addChild(ball);
		addEventListener(Event.ENTER_FRAME, onEnterFrame)
	}

	
	private function onEnterFrame(e:Event):void
	{
		var centerX:Number = 100;
		var centerY:Number = 100;

		// 中心までの距離
		var x1:Number = ball.x - centerX;
		var y1:Number = ball.y - centerY;
		// 
		var x2:Number = cos * x1 - sin * y1;
		var y2:Number = cos * y1 + sin * x1;

		ball.x = centerX + x2;
		ball.y = centerY + y2
	}
}
}

import flash.display.*;

internal class Ball extends Sprite
{

	public function Ball()
	{
		init();
	}
	
	private function init():void
	{
		this.graphics.beginFill(0xFFFFFF)
		this.graphics.drawCircle(0,0, 20);
		this.graphics.endFill();
	}
}


おしまい。