flash on 2013-11-16
/**
* Copyright Masataka.Okihara ( http://wonderfl.net/user/Masataka.Okihara )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/ukAj
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import frocessing.color.ColorHSV;
public class Main extends Sprite
{
private var bd:BitmapData; // ハイトマップの値を入れるBitmapData
private var max:Number = 1.0; // 値の最大値
private var min:Number = 0.0; // 値の最小値
private var bsize:int = 256 * 1; // ハイトマップのサイズ
private var minSize:int = 2; // minSize未満のサイズになったら分割を終了させる
private var color:ColorHSV = new ColorHSV();
public function Main()
{
bd = new BitmapData(bsize, bsize, false);
addChild(new Bitmap(bd));
stage.addEventListener(MouseEvent.CLICK, onMouseClick);
onMouseClick();
}
private function onMouseClick(event:MouseEvent = null):void
{
generateHeightmap(0, 0, bsize, Math.random(), Math.random(), Math.random(), Math.random());
//generateHeightmap(0, 0, size, 100 + Math.random(), 100 + Math.random(), 100 + Math.random(), 100 + Math.random());
//generateHeightmap(0, 0, size, 180,100,100,100);
}
// x, y = 左上座標
// size = 現在のサイズ(幅, 高さ)
// tl = 左上の値, tr = 右上の値, bl = 左下の値, br = 右下の値
public function generateHeightmap(x:int, y:int, size:int, tl:Number, tr:Number, bl:Number, br:Number):void
{
var depth:int = bsize / size;
// 四隅から見て中央にあるピクセルに平均値 + 変位させるランダムな値を入れる
var midPoint:Number = (tl + tr + bl + br) / 4 + getRandomHeight(size) * (0.75^depth);
// minSizeintサイズになったら分割を終了させる
if (size < minSize)
{
// 平均値を出す
var value:Number = (tl + tr + bl + br) / 4;
// RGB(value, value, value)にしてグレイ色に
var th:int = 128;
if (value * 256 < th) {
color.gray(0);
} else {
color.gray(value * 256);
}
// (x, y)~(x + minSize, y + minSize)分だけ塗る
//bd.fillRect(new Rectangle(x, y, x + minSize, y + minSize), color.value);
bd.setPixel(x, y, color.value);
}
else
{
// min~max(0.0~1.0)までの値に収まるように調整
if (midPoint < min) midPoint = min;
if (max < midPoint) midPoint = max;
// 中央から見て上下左右にあるピクセルにも平均値を入れる
var top:Number = (tl + tr) / 2; // 上 = 左上と右上の平均値
var bottom:Number = (bl + br) / 2; // 下 = 左下と右下の平均値
var left:Number = (tl + bl) / 2; // 左 = 左上と左下の平均値
var right:Number = (tr + br) / 2; // 右 = 右上と右下の平均値
// 2*2に分割するのでサイズ(幅, 高さ)を半分にする
size /= 2;
// 左上
generateHeightmap(x, y, size, tl, top, left, midPoint);
// 右上
generateHeightmap(x + size, y, size, top, tr, midPoint, right);
// 左下
generateHeightmap(x, y + size, size, left, midPoint, bl, bottom);
// 右下
generateHeightmap(x + size, y + size, size, midPoint, right, bottom, br);
}
}
public function getRandomHeight(value:Number):Number
{
// -0.5~0.5 -> -0.25~0.25 -> -0.125~0.125
return (Math.random() - 0.5);
}
}
}