塗りつぶしアルゴリズムのテスト実装

by tenasaku
2010年4月14日
アイコンエディタに「塗りつぶし」機能を実装するためのテストコード
マス目をクリックすると塗りつぶしを実行
塗り色は 乱数を使って決定する
ALTキー+クリックで最初の白黒画面を再生成します
♥0 | Line 138 | Modified 2010-04-14 20:46:32 | 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/cmzD
 */

// 2010年4月14日
// アイコンエディタに「塗りつぶし」機能を実装するためのテストコード
// 
// マス目をクリックすると塗りつぶしを実行
// 塗り色は 乱数を使って決定する
// ALTキー+クリックで最初の白黒画面を再生成します

package {
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	import flash.utils.*;
	public class FlashTest extends Sprite {
		private const GRID_SIZE:int = 8;
		private const GRID_COUNT:int = 58;
		private var screen:Bitmap;
		private var bmd:BitmapData;
		private var paintColor:uint;
		private function pSet(row:int,column:int,color:uint):void {
			if ( ( row < 0 )||( row >= GRID_COUNT ) ) return;
			if ( ( column < 0 )||( column >= GRID_COUNT ) ) return;
			bmd.fillRect(
				new Rectangle(
					row*GRID_SIZE+1,column*GRID_SIZE+1,
					GRID_SIZE-1,
					GRID_SIZE-1
				),
				color
			);
		}
		private function pGet(row:int,column:int):uint {
			if ( ( row < 0 )||( row >= GRID_COUNT ) ) return 0xffffffff;
			if ( ( column < 0 )||( column >= GRID_COUNT ) ) return 0xffffffff;
			return bmd.getPixel(row*GRID_SIZE+1,column*GRID_SIZE+1);
		}
		private function paintCan(X:int,Y:int,cc:uint):void {
			if ( ( X < 0 )||( X >= GRID_COUNT ) ) return;
			if ( ( Y < 0 )||( Y >= GRID_COUNT ) ) return;
			var regionColor:uint = pGet(X,Y);
			if ( cc == regionColor ) return;
			var pointStack:Array = [ new Point(X,Y) ];
			while ( pointStack.length > 0 ) {
				var p:Point = pointStack.pop();
				if ( pGet(p.x,p.y) == regionColor ) {
					pSet(p.x,p.y,cc);
					var xL:int = p.x;
					var xR:int = p.x;
					while ( pGet(xL-1,p.y) == regionColor ) {
						xL--;
						pSet(xL,p.y, cc);
					}
					while ( pGet(xR+1,p.y) == regionColor ) {
						xR++;
						pSet(xR,p.y, cc);
					}
					for each ( var k:int in [ -1 , +1 ] ) {
						var i:int,j:int;
						i = xL;
						j = xR;
						var dL:Boolean,dR:Boolean;
						dL = false;
						dR = false;
						while ( i <= j ) {
							if ( (!dL)&&( pGet(i,p.y+k) == regionColor ) ) {
								pointStack.push(new Point(i,p.y+k));
								dL = true;
							} else if ( dL&&( pGet(i,p.y+k) != regionColor ) ) {
								dL = false;
							}
							if ( (!dR)&&( pGet(j,p.y+k) == regionColor) ) {
								pointStack.push(new Point(j,p.y+k));
								dR = true;
							} else if ( dR&&( pGet(j,p.y+k) != regionColor ) ) {
								dR = false;
							}
							i++;
							j--;
						}
					}
				}
			}
		}
		private function onClick(e:MouseEvent):void {
			var row:int = Math.floor(e.stageX/GRID_SIZE);
			var column:int = Math.floor(e.stageY/GRID_SIZE);
			if ( ( row < 0 )||( row >= GRID_COUNT) ) return;
			if ( ( column < 0 )||( column >= GRID_COUNT) ) return;
			if ( e.altKey ) {
				screenInit();
				return;
			}
			var t:Number = Math.random()*2*Math.PI;
			var r:int = Math.floor((1+Math.cos(t))*127.9999);
			var g:int = Math.floor((1+Math.cos(t+Math.PI*2/3))*127.9999);
			var b:int = Math.floor((1+Math.cos(t-Math.PI*2/3))*127.9999);
			paintColor = 0xffffff&((r<<16)|(g<<8)|b);
			paintCan(row,column,paintColor);
		}
		private function screenInit():void {
			bmd.fillRect(
				new Rectangle(
					0,0,
					GRID_COUNT*GRID_SIZE+1,GRID_COUNT*GRID_SIZE+1
				),
				0xffffff
			);
			var i:int,j:int;
			for ( i = 0 ; i <= GRID_COUNT ; ++i )
			for ( j = 0 ; j <= GRID_COUNT*GRID_SIZE ; ++j ) {
				bmd.setPixel(i*GRID_SIZE,j,0x999999);
				bmd.setPixel(j,i*GRID_SIZE,0x999999);
			}
			for ( i = 0 ; i < GRID_COUNT ; ++i ) {
				var d:int = Math.floor(Math.random()*8191.9999);
				var b:int = 1;
				for ( j = 0 ; j < GRID_COUNT ; ++j ) {
					if ( (d&b) != 0 ) pSet(j,i,0x000000);
					b <<=1;
					if (b >= 8192) b = 1;
				}
			}
		}
		private function initialize(e:Event):void {
			this.removeEventListener(Event.ADDED_TO_STAGE, initialize);
			bmd = new BitmapData(
				GRID_SIZE*GRID_COUNT+1,
				GRID_SIZE*GRID_COUNT+1,
				false,
				0xffffff
			);
			screen = new Bitmap(bmd);
			screenInit();
			this.addChild(screen);
			paintColor = 0x0000ff;
			stage.addEventListener(MouseEvent.CLICK, onClick);
		}
		public function FlashTest() {
			if ( stage != null ) {
					initialize(null);
			} else {
					this.addEventListener(Event.ADDED_TO_STAGE, initialize);
			}
		}
	}
}