// forked from cpu_t's perlinNoise遊び // resetをクリックでリセット。 // // HSVに変換して遊ぶ // (H:色相, S:彩度, V:明度) // Hが角度 // S*V*465*0.5が距離 // // チェックボックスで // perlinNoise()のfractalNoiseをtrueにするかどうか // 距離の算出でS,Vをかけるかどうか // を設定できます // package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.MouseEvent; import flash.text.TextField; [SWF(width = 465, height = 465)]; public class FlashTest extends Sprite { public function FlashTest() { cbFractalNoise = new CCheckBox(stage, 10, 10, "fractalNoise"); cbFractalNoise.selected = false; cbUseS = new CCheckBox(stage, 10, 40, "S"); cbUseS.selected = true; cbUseV = new CCheckBox(stage, 60, 40, "V"); cbUseV.selected = true; vectormap = new BitmapData(465, 465); bmpdata = new BitmapData(465, 465, false, 0); addChild(new Bitmap(bmpdata)); var btnReset:Sprite = new Sprite(); addChild(btnReset); btnReset.x = 10; btnReset.y = 80; var tf:TextField = new TextField(); tf.text = "reset"; tf.autoSize = "left"; tf.background = true; tf.backgroundColor = 0xE0E0E0; tf.selectable = false; btnReset.addChild(tf); btnReset.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):void { reset(); }); reset(); } private var vectormap:BitmapData; private var bmpdata:BitmapData; private var cbFractalNoise:CCheckBox; private var cbUseS:CCheckBox; private var cbUseV:CCheckBox; private function reset():void { vectormap.perlinNoise(465 * .5, 465 * .5, 3, Math.random() * 0xFFFFFFFF, false, cbFractalNoise.selected); bmpdata.lock(); // bmpdataをクリア bmpdata.fillRect(bmpdata.rect, 0); // vectormapの全ピクセルに対してループ for (var y:int = 0; y < vectormap.height; y++) { for (var x:int = 0; x < vectormap.width; x++) { // HSVを算出 var px:uint = vectormap.getPixel(x, y); var HSV:Object = toHSV(px); var d:Number = 465 * .5; // SVがチェックされていたらdにかける if (cbUseS.selected) d *= HSV.S; if (cbUseV.selected) d *= HSV.V; // Hを角度、dを距離として、中央の座標に加算 var tx:int = 465 * .5 + Math.cos(HSV.H * Math.PI / 180) * d; var ty:int = 465 * .5 + Math.sin(HSV.H * Math.PI / 180) * d; // bmpdataの範囲外になってしまったらcontinue if (ty<0 || ty>=bmpdata.height || tx<0 || tx>=bmpdata.width) continue; // rgb要素を取得 var r:int = px >> 16 & 0xFF; var g:int = px >> 8 & 0xFF; var b:int = px & 0xFF; // 色を足す var col:uint = bmpdata.getPixel(tx, ty); r = (int)(r * .2) + (col >> 16 & 0xFF); g = (int)(g * .2) + (col >> 8 & 0xFF); b = (int)(b * .2) + (col & 0xFF); if (r > 0xFF) r = 0xFF; if (g > 0xFF) g = 0xFF; if (b > 0xFF) b = 0xFF; col = (r << 16) + (g << 8) + b; if (col > 0xFFFFFF) col = 0xFFFFFF; bmpdata.setPixel(tx, ty, col); } } bmpdata.unlock(); } // 0xRRGGBBからHSVを計算してHSVを持つオブジェクトを返す private function toHSV(color:uint):Object { var obj:Object = { H:Number, S:Number, V:Number }; var r:Number = (color >> 16 & 0xFF) / 0xFF; var g:Number = (color >> 8 & 0xFF) / 0xFF; var b:Number = (color & 0xFF) / 0xFF; var max:Number; var min:Number = (r <= g && r <= b) ? r : (g <= b ? g : b); // H算出 if (r == g && r == b) { max = r; obj.H = 0; } else if (r >= g && r >= b) { max = r; obj.H = 60 * (g - b) / (max - min); } else if (g >= b) { max = g; obj.H = 60 * (b - r) / (max - min) + 120; } else { max = b; obj.H = 60 * (r - g) / (max - min) + 240; } if (obj.H < 0) obj.H += 360; // S算出 if (max == 0) { obj.S = 0; } else { obj.S = (max - min) / max; } // V算出 obj.V = max; return obj; } } } import flash.display.DisplayObjectContainer; import flash.display.Graphics; import flash.display.Sprite; import flash.events.MouseEvent; import flash.text.TextField; class CCheckBox extends Sprite { private var _selected:Boolean = false; private var back:Sprite; private var tf:TextField; private var check:Sprite; public function CCheckBox(parent:DisplayObjectContainer, x:int = 0, y:int = 0, label:String = "") { parent.addChild(this); this.x = x; this.y = y; addChild(back = new Sprite()); var g:Graphics = back.graphics; g.beginFill(0x808080); g.drawRect(0, 0, 20, 20); g.endFill(); back.addChild(check = new Sprite()); g = check.graphics; g.beginFill(0xFFFFFF); g.drawRect(4, 4, 12, 12); g.endFill(); check.visible = _selected; addChild(tf = new TextField()); tf.x = 20; tf.autoSize = "left"; tf.background = true; tf.backgroundColor = 0xFFFFFF; tf.text = label; tf.selectable = false; this.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):void { _selected = !_selected; check.visible = _selected; }); } public function get selected():Boolean { return _selected; } public function set selected(value:Boolean):void { _selected = value; check.visible = _selected; } } perlinNoise遊び2 HSVを使う