//Character-Encoding: UTF-8 // プロジェクト名: flash20100331a // ファイル: Main.as /* ------- 2010年3月31日水曜日 非線形離散力学系の不変集合 少しずつプロットされていきますので気長に見てください -------- 以下は、数学的内容の解説 --- 平面の自己同相写像 new X = f(X) - ALPHA*Y new Y = BETA*X ... ただし (1) ALPHA, BETA は定数で, ALPHA*BETA = -1 となるもの 今回は ALPHA = 1, BETA = -1 (2) f(X) は任意の可微分函数だけど, ここでは f(X) = 4*X*(1-X) の不動点での挙動 (不動点の微小近傍の軌道) を図示 赤い図形は原点の微小近傍がこの写像の反復で引き伸ばされてできる図形 (不安定多様体) 青い図形は同じく原点の微小近傍が逆写像の反復で引き伸ばされてできる図形 (安定多様体) いずれも(究極的には)一本の線が複雑に折りたたまれた形状になります -------- */ package { import flash.display.*; import flash.events.*; public class Main extends Sprite { private static const ALPHA:Number = 1; private static const BETA:Number = -1/ALPHA; private var screen:Bitmap; private function F(u:Number):Number { return 4*u*(1-u); } private function atEveryFrame(e:Event):void { const COUNTMAX:int = 100; const EPSILON:Number = 2.0e-02; var p0:Number,q0:Number; // 順方向へ移動する点 var p1:Number,q1:Number; // 逆方向へ移動する点 var i:int; p0 = p1 = (Math.random()*2-1)*EPSILON; // 初期値(X座標) q0 = q1 = (Math.random()*2-1)*EPSILON; // 初期値(Y座標) screen.bitmapData.lock(); for ( i = 0 ; i < COUNTMAX ; ++i ) { var p2:Number = F(p0) - ALPHA*q0; // 順方向(X座標) var q2:Number = BETA*p0; // 順方向(Y座標) var p3:Number = q1/BETA; // 逆方向(X座標) var q3:Number = (F(q1/BETA)-p1)/ALPHA; // 逆方向(Y座標) plot(p2,q2,0xff0000); // 不安定多様体を赤でプロット plot(p3,q3,0x0000ff); // 安定多様体を青でプロット p0 = p2; q0 = q2; p1 = p3; q1 = q3; } screen.bitmapData.unlock(); } private function plot(u:Number,v:Number,c:uint):void { const P0:Number = 232.5; const Q0:Number = 120.0; const Pu:Number = 100.00; const Qv:Number = -Pu; var P:int = Math.floor(0.5+P0+Pu*u); var Q:int = Math.floor(0.5+Q0+Qv*v); if ((P>=0)&&(Q>=0)&&(P<465)&&(Q<465)) { screen.bitmapData.setPixel32(P,Q,0xa0000000|(0x00ffffff&c)); } } private function initialize(e:Event):void { this.removeEventListener(Event.ADDED_TO_STAGE, initialize); stage.frameRate = 20; stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; screen = new Bitmap(); screen.bitmapData = new BitmapData(465,465,true,0xff000000); screen.x = screen.y = 0; this.addChild(screen); stage.addEventListener(Event.ENTER_FRAME, atEveryFrame); } // The Main constructor simply calles initialize() function. public function Main():void { if ( stage != null ) { initialize(null); } else { this.addEventListener(Event.ADDED_TO_STAGE, initialize); } } } // end of class Main } // end of package