クリックで円を配置
多角形の内部のユークリッド距離変換
・辺に近いほど暗くなる。
・頂点に近いほど暗くなる。
赤い線の外側は適当に塗り潰して考えてください。
// forked from nabe's 壁までの距離を検知
// forked from nabe's 低速ユークリッド距離変換のソース整理
// forked from nabe's 低速ユークリッド距離変換
// forked from nabe's 低速ユークリッド距離変換の作りかけ(LINEAR)
// forked from nabe's 低速ユークリッド距離変換の作りかけ
// forked from nabe's ランダムな形をビットマップに描く
// forked from nabe's PerlinNoise勉強中
// 多角形の内部のユークリッド距離変換
// ・辺に近いほど暗くなる。
// ・頂点に近いほど暗くなる。
// 赤い線の外側は適当に塗り潰して考えてください。
package {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
[SWF(width="500", height="500", backgroundColor="0xFFFFFF", frameRate="1")]
public class Test extends Sprite {
private var bitmapData_:BitmapData = null;
private var foreData_:BitmapData = null;
private var cursor_:Sprite;
public function Test () {
//1)コンストラクタで初期化処理の呼び出しを仕込む。
addEventListener(Event.ADDED_TO_STAGE, initialize_);
}
private function initialize_ (event_:Event):void {
//2)初期化処理の中で仕込みを解除する。
//どうしてコンストラクタで初期化してはいけないのだろう?
//コンストラクタ自体は極力軽量化させるべきなのだろうか?
if (event_.target == this) {
removeEventListener(event_.type, arguments.callee);
}
//3)ステージいっぱいのサイズで、ビットマップを貼り付ける。
bitmapData_ = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0x000000 /*黒*/);
addChild(new Bitmap(bitmapData_));
foreData_ = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x000000 /*黒*/);
addChild(new Bitmap(foreData_));
//4)カーソルを追加。
cursor_ = new Sprite();
var graphics_:Graphics = cursor_.graphics;
graphics_.clear();
graphics_.lineStyle(0, 0x00FF00);
graphics_.drawCircle(0, 0, 1);
addChild(cursor_);
//5)カーソルをマウスに追従させる。
stage.addEventListener(MouseEvent.MOUSE_MOVE, update_);
//6)クリック処理を仕込む。
stage.addEventListener(MouseEvent.MOUSE_DOWN,
function (event_:MouseEvent):void {
var fire_:Shape = new Shape();
var graphics_:Graphics = fire_.graphics;
var matrix_:Matrix = new Matrix();
//1)半径を求める。
var size_:int = getValue_() ;
//2)原点を中心とした放射状グラデーションを用意する。
matrix_.createGradientBox(
(size_ + 256) * 2 - 1,
(size_ + 256) * 2 - 1,
0,
- (size_ + 256),
- (size_ + 256)
);
//3)原点を中心とした円を描く。
graphics_.clear();
graphics_.lineStyle(0,0,0);
graphics_.beginGradientFill(GradientType.RADIAL,
[0x000000, 0xFFFFFF],
[100, 100],
[size_ * 256/(size_ + 256), 255],
matrix_,
SpreadMethod.PAD,
InterpolationMethod.RGB,
0
);
graphics_.drawCircle(0,0,size_+256);
graphics_.endFill();
//4)ビットマップにコピーする。
matrix_.createBox(1,1);
matrix_.translate(mouseX, mouseY);
bitmapData_.draw(fire_, matrix_, null, BlendMode.DARKEN);
//5)原点を中心とした円を描く。
graphics_.clear();
graphics_.beginFill(0xFF3030);
graphics_.drawCircle(0, 0, size_);
graphics_.endFill();
//6)前面にコピーする。
foreData_.draw(fire_, matrix_, null, BlendMode.NORMAL);
});
//7)描画処理を呼び出す。
//addEventListener(Event.ENTER_FRAME, drawSample);
drawSample(null);
}
private function getValue_ () : int {
return bitmapData_.getPixel(mouseX, mouseY) & 0xFF;
}
private function update_ (event_:MouseEvent) : void {
cursor_.x = mouseX;
cursor_.y = mouseY;
var size_:int = getValue_() ;
cursor_.scaleX = size_;
cursor_.scaleY = size_;
if (event_ != null) event_.updateAfterEvent();
};
private function drawSample(event_:Event):void {
//5)主な定数
const num_:int = 16;
//6)使いまわし変数
var i_:int;
var item_:Point;
var item2:Point;
var matrix_:Matrix = new Matrix();
var graphics_:Graphics;
//7)適当に座標を作る。
var points_:Array = [];
for (i_ = 0; i_<num_; i_++) {
item_ = Point.polar(
200 * (i_ + 1) * (Math.random() + 1) / (num_ + 1),
//200 * (i_ + 2) / 16,
//200,
Math.PI * 2 * (i_ / num_)
);
item_.offset(250, 250);
points_[i_] = item_;
}
points_[num_] = points_[0];
//8)線状グラデーション塗りを準備する。
var linear_:Shape = new Shape();
graphics_ = linear_.graphics;
graphics_.clear();
matrix_.createGradientBox(255,255,0,0,0);
graphics_.beginGradientFill(GradientType.LINEAR,
[0x000000, 0xFFFFFF],
[100, 100],
[0, 255],
matrix_,
SpreadMethod.REFLECT,
InterpolationMethod.RGB,
0
);
graphics_.drawRect(0,0,256,100);
graphics_.drawRect(-255,0,256,100);
graphics_.endFill();
graphics_ = null;
//9)放射状グラデーション塗りを準備する。
var radial_:Shape = new Shape();
graphics_ = radial_.graphics;
graphics_.clear();
matrix_.createGradientBox(511,511,0,0,0);
graphics_.beginGradientFill(GradientType.RADIAL,
[0x000000, 0xFFFFFF],
[100, 100],
[0, 255],
matrix_,
SpreadMethod.PAD,
InterpolationMethod.RGB,
0
);
graphics_.drawCircle(255,255,256);
graphics_.endFill();
graphics_ = null;
//10)初期状態として白で塗り潰す。
bitmapData_.fillRect(new Rectangle(0, 0, 500, 500), 0x00FFFFFF);
//11)各辺から色を塗る。
for (i_ = 0; i_ < num_; i_++) {
item_ = points_[i_]; //辺の始点
item2 = points_[i_ + 1]; //辺の終点
var dir_:Point = item2.subtract(item_);
//差を求める。
var rotation_:Number = Math.atan2(dir_.x, -dir_.y);
//グラデーションの伸びる角度を求める。
matrix_.createBox(1, dir_.length / 100);
//辺の長さに合わせてグラデーションを変形する。
matrix_.rotate(rotation_);
matrix_.translate(item2.x, item2.y);
bitmapData_.draw(linear_, matrix_, null, BlendMode.DARKEN);
//位置と向きを合わせて描画する。
//塗り潰す際、地の色の方が暗かったら、そちらを優先する。
}
//12)各頂点から色を塗る。
for (i_ = 0; i_ < num_; i_++) {
item_ = points_[i_];
matrix_.createBox(1, 1, 0, item_.x - 255, item_.y - 255);
bitmapData_.draw(radial_, matrix_, null, BlendMode.DARKEN);
//位置を合わせて描画する。
//塗り潰す際、地の色の方が暗かったら、そちらを優先する。
}
//13)線を引く。
foreData_.fillRect(new Rectangle(0, 0, 500, 500), 0x00000000);
var shape_:Shape = new Shape();
graphics_ = shape_.graphics;
graphics_.clear();
graphics_.lineStyle(1, 0xFF0000);
drawLines_();
graphics_.endFill();
foreData_.draw(shape_);
function drawLines_():void {
item_ = points_[num_ - 1];
graphics_.moveTo(item_.x, item_.y);
for (i_ = 0; i_<num_; i_++) {
item_ = points_[i_];
graphics_.lineTo(item_.x, item_.y);
}
}
//14)カーソルを追従させる。
update_(null);
} //drawSample
} //class
} //package