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