縮小自己写像系によるフラクタルの生成

by tenasaku
2010年3月30日
今朝ポストしたコード
http://wonderfl.net/code/96fa3bd49639b0411dc81a22af4e7c73d104728c
の焼き直しです。
縮小自己写像系によってシルピンスキ・ガスケットを生成します
♥0 | Line 111 | Modified 2010-03-30 20:20:23 | MIT License
play

ActionScript3 source code

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

// 2010年3月30日
// 今朝ポストしたコード
//   http://wonderfl.net/code/96fa3bd49639b0411dc81a22af4e7c73d104728c
// の焼き直しです。
// 縮小自己写像系によってシルピンスキ・ガスケットを生成します

package {

	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;

	public class Main extends Sprite {

		private const SQRT3:Number = Math.sqrt(3);
		private const A:Number = 465;
		private const B:Number = A*SQRT3/2;
		private const P1:Point = new Point((1/4)*A, 0);
		private const P2:Point = new Point((9/8)*A,(-SQRT3/8)*A+B);
		private const P3:Point = new Point((1/8)*A,( SQRT3/8)*A+B);
		private const FRAME_RECYCLE:int = 20;
		private const GENERATION_RECYCLE:int = 40;
		private const contractionMatrix:Matrix = new Matrix(1/2,0,0,1/2,0,0);

		private var bm1:Bitmap;
		private var bm2:Bitmap;
		private var bm3:Bitmap;
		private var bmD:BitmapData; // BitmapData を 三つの Bitmap が共有する
		private var frameCount:int;
		private var generation:int;

		private function atEveryFrame(e:Event):void {
			if ( (frameCount%FRAME_RECYCLE) == 0 ) {
				if ( generation != 0 ) {
					// 背景を段階的に暗くして 消え残る図形を際立たせる
					var u:Number = ( 1 - generation/(GENERATION_RECYCLE-1) );
					var marginColor:uint = Math.floor(u*255)*0x010000;
					var prevBMD:BitmapData = new BitmapData(A,B,false,marginColor);
					prevBMD.draw(this);
					this.graphics.clear();
					this.graphics.beginFill(0x000000);
					this.graphics.drawRect(0,B,A,stage.stageHeight-B);
					this.graphics.endFill();
					this.graphics.beginFill(marginColor);
					this.graphics.drawRect(0,0,A,B);
					this.graphics.endFill();
					bmD.draw(prevBMD,contractionMatrix);
					bm1.visible = true;
					bm2.visible = true;
					bm3.visible = true;
				} else {
					drawRootImage();
				}
				++generation;
				generation %= GENERATION_RECYCLE;
			}
			++frameCount;
			frameCount %= FRAME_RECYCLE;
		}

		// 初期画像はあいかわらずの クマ
		// シルピンスキの顔写真を使おうかとも思ったのですが
		// 俺がシルピンスキだったら 使われたくないなあ と思って
		// やめにしました
		private function drawRootImage():void {
			const _Cx:Number = A/2;
			const _Cy:Number = B/2;
			const _U:Number = A/27;
			const _FACE_COLOR:uint = 0xcc6600;
			bm1.visible = false;
			bm2.visible = false;
			bm3.visible = false;
			this.graphics.clear();
			this.graphics.beginFill(0x00ff00);
			this.graphics.drawRect(0,0,A,B);
			this.graphics.endFill();
			this.graphics.beginFill(_FACE_COLOR);
			this.graphics.drawEllipse(_Cx-_U*10,_Cy-_U*11.5,_U*7,_U*8);
			this.graphics.endFill();
			this.graphics.beginFill(_FACE_COLOR);
			this.graphics.drawEllipse(_Cx+_U*10,_Cy-_U*11.5,_U*(-7),_U*8);
			this.graphics.endFill();
			this.graphics.beginFill(_FACE_COLOR);
			this.graphics.drawEllipse(A/20,B/20,A/10*9,B/10*9);
			this.graphics.endFill();
			this.graphics.beginFill(0xffffff);
			this.graphics.drawEllipse(_Cx-_U*6,_Cy,_U*12,_U*9);
			this.graphics.endFill();
			this.graphics.beginFill(0x000000);
			this.graphics.drawEllipse(_Cx+_U*6,_Cy-_U*3,_U*1,_U*1.5);
			this.graphics.endFill();
			this.graphics.beginFill(0x000000);
			this.graphics.drawEllipse(_Cx-_U*6,_Cy-_U*3,_U*(-1),_U*1.5);
			this.graphics.endFill();
			this.graphics.beginFill(0x000000);
			this.graphics.drawEllipse(_Cx-_U,_Cy+_U*2,_U*2,_U*1.2);
			this.graphics.endFill();
			this.graphics.lineStyle(0.5*_U,0x000000);
			this.graphics.moveTo(_Cx-_U*3,_Cy+_U*7);
			this.graphics.curveTo(_Cx,_Cy+_U*6,_Cx,_Cy+_U*4);
			this.graphics.curveTo(_Cx,_Cy+_U*6,_Cx+_U*3,_Cy+_U*7);
		}

		private function initialize(e:Event):void {
			this.removeEventListener(Event.ADDED_TO_STAGE, initialize);
		//	stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			// ビットマップ・オブジェクトの初期化と配置
			bmD = new BitmapData((1/2)*A,(1/2)*B,false,0xffffff00);
			bm1 = new Bitmap(bmD); // 同じデータを三者が共有する
			bm2 = new Bitmap(bmD);
			bm3 = new Bitmap(bmD);
			bm1.x = P1.x;	bm1.y = P1.y;	bm1.rotation = 0;
			bm2.x = P2.x;	bm2.y = P2.y;	bm2.rotation = 120;
			bm3.x = P3.x;	bm3.y = P3.y;	bm3.rotation = -120;
			addChild(bm1);
			addChild(bm2);
			addChild(bm3);
			// 制御変数の初期化
			frameCount = 0;
			generation = 0;
			// フレームごとの処理の登録
			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