ヴェルナー・パントンの Geometri 風パターン
ヴェルナー・パントンの Geometri 風パターンを再帰で生成
ステージクリックで再描画
コードの元ネタ:http://www.openprocessing.org/visuals/?visualID=5673
@author Aquioux(Yoshida, Akio)
/**
* Copyright Aquioux ( http://wonderfl.net/user/Aquioux )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/do5S
*/
package {
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.MouseEvent;
[SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#FFFFFF")]
/**
* ヴェルナー・パントンの Geometri 風パターンを再帰で生成
* ステージクリックで再描画
* コードの元ネタ:http://www.openprocessing.org/visuals/?visualID=5673
* @author Aquioux(Yoshida, Akio)
*/
public class Main extends Sprite {
private var _color1:uint;
private var _color2:uint;
private var _isDivide:Boolean;
private var _canvas:Sprite;
private const SIZE_OF_MAXIMUM:uint = stage.stageWidth / Math.pow(2, 1);
private const SIZE_OF_MINIMUM:uint = stage.stageWidth / Math.pow(2, 4);
public function Main():void {
_canvas = this;
initialize(null);
stage.addEventListener(MouseEvent.CLICK, initialize);
}
private function initialize(event:MouseEvent):void {
var h1:Number = Math.random() * 360;
var h2:Number = h1 + 135;
var s1:Number = randomInt(10, 8) / 10;
var s2:Number = randomInt(10, 8) / 10;
var v1:Number = randomInt(10, 8) / 10;
var v2:Number = randomInt(10, 8) / 10;
_color1 = hsvToRgb(h1, s1, v1);
_color2 = hsvToRgb(h2, s2, v2);
_canvas.graphics.clear();
divideOrDraw(0, 0, stage.stageWidth, _color1, _color2);
}
// 再帰処理
private function divideOrDraw(x:Number, y:Number, size:Number, c1:uint, c2:uint):void {
_isDivide = true; // _isDivide をリセット
if (Math.random() < 0.5) { // 1/2 の確立で分割を中止し、描画
_isDivide = false;
}
if (size <= SIZE_OF_MINIMUM) { // 分割最小値より小さい場合、強制的に分割を中止し、描画
_isDivide = false;
}
if (size >= SIZE_OF_MAXIMUM) { // 分割最大値より大きい場合、強制的に分割
_isDivide = true;
}
_isDivide ? divide(x, y, size * 0.5) : draw(x, y, size, c1, c2);
}
// 分割
private function divide(x:Number, y:Number, size:Number):void {
divideOrDraw(x, y, size, _color1, _color2);
divideOrDraw(x + size, y, size, _color2, _color1);
divideOrDraw(x, y + size, size, _color2, _color1);
divideOrDraw(x + size, y + size, size, _color1, _color2);
}
// 描画
private function draw(x:Number, y:Number, size:Number, c1:uint, c2:uint):void {
var g:Graphics = _canvas.graphics;
// 地(正方形)描画
g.beginFill(c1);
g.drawRect(x, y, size, size);
g.endFill();
// 紋(円)描画
g.beginFill(c2);
g.drawCircle(x + size * 0.5, y + size * 0.5, size * 0.4);
g.endFill();
}
private function hsvToRgb(h:Number = 0.0, s:Number = 1.0, v:Number = 1.0):uint {
// h : 0.0 - 360.0
// s : 0.0 - 1.0
// v : 0.0 - 1.0
var r:uint = 0;
var g:uint = 0;
var b:uint = 0;
// 各引数を許可範囲に収める
h %= 360;
if (h < 0)
h += 360;
h /= 60;
s = Math.max(0, Math.min(s, 1.0));
v = Math.max(0, Math.min(v, 1.0));
v *= 0xFF;
if (s == 0) {
r = g = b = v;
} else {
var hi:uint = Math.floor(h % 6);
var f:Number = h - hi;
var p:Number = v * (1 - s);
var q:Number = v * (1 - s * f);
var t:Number = v * (1 - s * (1 - f));
switch(hi) {
case 0: {
r = v;
g = t;
b = p;
break;
}
case 1: {
r = q;
g = v;
b = p;
break;
}
case 2: {
r = p;
g = v;
b = t;
break;
}
case 3: {
r = p;
g = q;
b = v;
break;
}
case 4: {
r = t;
g = p;
b = v;
break;
}
case 5: {
r = v;
g = p;
b = q;
break;
}
}
}
return r << 16 | g << 8 | b;
}
private function randomInt(max:int, min:int = 0):int {
return min + Math.floor(Math.random() * (max - min + 1));
}
}
}