開発環境 Apache Flex SDK 4.13.0
FlashDevelop 4.7.1.1
実行環境 Microsoft Windows 8.1 (64bit)
プロジェクトの種類 ActionScript 3/AS3 Project
プロジェクト名 orbit2


Main.as
package
{
	import flash.display.*;
	import flash.events.*;
	import flash.text.*;
 
	public class Main extends Sprite 
	{
		private const eps:Number = 1.0e-14;
		private var e:Number; // 離心率
		private var a:Number; // 軌道長半径
		private var b:Number; // 軌道短半径
		private var t:Number = 0; // 時間
		private var canvas:Sprite;
		private var btnArray:Vector.<TextField>;
 
		public function Main() 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(ev:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
 
			canvas = new Sprite;
			addChild(canvas);
			canvas.x = 400;
			canvas.y = 300;
 
			a = 200;
			btnArray = new Vector.<TextField>;
			createButton(10, 10, 100, 50, "0.0");
			createButton(10, 70, 100, 50, "0.0167");
			createButton(10, 130, 100, 50, "0.5");
			createButton(10, 190, 100, 50, "0.8");
			selectButton(2);
 
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
 
		private function onEnterFrame(ev:Event):void 
		{
			var rad:Number = t * Math.PI / 180;
			var E:Number = KeplersEquation(rad);
 
			t += 2;
			if (360 <= t) t -= 360;
 
			var g:Graphics = canvas.graphics;
			g.clear();
			g.lineStyle(1, 0x000000);
 
			// 円軌道
			g.drawCircle(0, 0, a);
			g.beginFill(0xff0000);
			g.drawCircle(0, 0, 15);
			g.drawCircle(a * Math.cos(rad), -a * Math.sin(rad), 10);
			g.endFill();
 
			// 楕円軌道
			g.drawEllipse(-a, -b, a * 2, b * 2);
			g.beginFill(0x0000ff);
			g.drawCircle(a * e, 0, 10);
			g.drawCircle(a * Math.cos(E), -b * Math.sin(E), 5);
			g.endFill();
		}
 
		// 漸化式によりケプラー方程式を解く
		// M 平均近点角(mean anomaly)
		// E 離心近点角(eccentric anomaly)
		// T 真近点角(true anomaly)
		private function KeplersEquation(M:Number):Number
		{
			var E:Number;
			var E0:Number = M; // 初項
			for (var i:int = 1; ; i++) 
			{
				E = M + e * Math.sin(E0);
				if ((E0 - eps < E) && (E < E0 + eps)) break;
				if (10 <= i)
				{
					// 計算打ち切り
					break;
				}
				E0 = E;
			}
//			var K:Number = Math.sqrt((1 + e) / (1 - e)); // ケプラー方程式の定数
//			var T:Number = Math.atan(K * Math.tan(E / 2)) * 2;
			return E;
		}
 
		private function createButton(x:Number, y:Number, width:Number, height:Number, text:String):void 
		{
			var tf:TextField = new TextField;
			tf.background = true;
			tf.border = true;
			tf.defaultTextFormat = new TextFormat(null, 20);
			tf.name = btnArray.length.toString();
			tf.selectable = false;
			tf.x = x;
			tf.y = y;
			tf.width = width;
			tf.height = height;
			tf.text = text;
			tf.addEventListener(MouseEvent.CLICK, onButtonClick);
			addChild(tf);
			btnArray.push(tf);
		}
 
		private function onButtonClick(e:MouseEvent):void 
		{
			var select:int = parseInt((e.target as TextField).name);
			selectButton(select);
		}
 
		private function selectButton(select:int):void 
		{
			for (var i:int = 0; i < btnArray.length; i++) 
			{
				var tf:TextField = btnArray[i];
				if (i == select)
				{
					tf.backgroundColor = 0xff7f00;
					e = parseFloat(tf.text);
				}
				else
				{
					tf.backgroundColor = 0xbfbfbf;
				}
			}
			b = a * Math.sqrt(1 - e * e);
		}
 
	}
 
}
 
最終更新:2015年01月22日 20:19