【Javascript】Canvasに多角形で「花」を描いてみる

Youtubeでもレブル250/グラディウス400/GN125の情報を発信してます! (登録してもらえると超喜びます!!)

花弁って幾何学的ですよね

ある日、植物園で見たお花が、四角形を組み合わせたような形だったんですよ。

エクメア ファスキアタ

この写真の中心の部分、なんだか四角形とか、五角形とか…の組合せで描画できそうじゃないか…!
ということで、JavascriptでCanvasに多角形を組み合わせたお花風の何かを書くようなコード書いてみました。

Canvasの使い方を学んでたけど…なんかいい練習問題無いかな、って探している人にも丁度いいかなと思います。

デモページ

デモページはこちら

4, 5, 6角形が一番お花っぽく見えます。

ソースコード

コードは下記の通りです。

[javascript] <html>
<head>
<title></title>
<meta charset="UTF-8">
</head>
<body>
<script>
class BloomPolygon{
constructor(default_ctx, default_num, default_size, default_depth_limit, default_rate){
this.ctx = default_ctx || {};
this.num = default_num || 3;
this.size = default_size || 128;
this.depth_limit = default_depth_limit || 32;
this.scale_rate = default_rate || 0.92;

this.fib_a = 1;
this.fib_b = 1;
}
// calc fibonacci
_fib(){
var res = this.fib_a + this.fib_b;
this.fib_a = this.fib_b;
this.fib_b = res;
return res;
}
// draw polygon
_drawPolygon(ctx, num, x, y, size){
ctx.beginPath();
ctx.moveTo(x + size * Math.cos(0), y + size * Math.sin(0));

for (var side = 0; side <= num; side++)
ctx.lineTo(x + size * Math.cos(side * 2 * Math.PI / num), y + size * Math.sin(side * 2 * Math.PI / num));

ctx.stroke();
ctx.closePath();
}
// recursively drawing polygons
_recursiveDraw(ctx, num, size, depth){
if(depth < 0) return;

ctx.rotate(this._fib() * Math.PI / 180.0);
//ctx.rotate(this._pri() * Math.PI / 180.0);
this._drawPolygon(ctx, num, 0, 0, size);

this._recursiveDraw(ctx, num, size * this.scale_rate, –depth);
}
// MAIN function!!
// can change context and figure type
bloom(ctx, num, size, depth_limit, scale_rate) {
// update if value set
this.ctx = ctx || this.ctx;
this.num = num || this.num;
this.depth_limit = depth_limit || this.depth_limit;
this.scale_rate = scale_rate || this.scale_rate;

// draw exec
this.ctx.strokeStyle = "#eeaadd"
this.ctx.beginPath();
this.ctx.translate(128, 128);
this._recursiveDraw(this.ctx, this.num, size || this.default_size, this.depth_limit);
this.ctx.closePath();
}
}

var bloomer = new BloomPolygon();

// draw flower with triangle ~ octagon
[3, 4, 5, 6, 7, 8] .forEach((v)=>{
document.body.appendChild((function(v){
var el = document.createElement("canvas");
el.id = "canvas-" + v;
el.setAttribute("width", 256);
el.setAttribute("height", 256);
bloomer.bloom(el.getContext("2d"), v, 96, 32, 0.92);
return el;
})(v));
});
</script>
</body>
</html>
[/javascript]

大ざっぱな解説としては、お花描画用のクラスが大きく1つ。
最後のほうにそのクラスをインスタンス化して、3角形~8角形まで描画メソッドをコールしている感じです。

描画の中身は、再帰してx角形をフィボナッチ数列の度数だけ回転させて描画しているだけです。

フィボナッチ数を選んだのは、花弁の枚数とか結構フィボナッチ数を踏むらしかったのと、回転角が固定されるより変化した方がいいかなと思ったからです。
素数を回転角にして試してもみたんですが、いまいち綺麗に描けなかったのでやめました。

 

 

 

 

Youtubeでもレブル250/グラディウス400/GN125の情報を発信してます! (登録してもらえると超喜びます!!)
最新情報をチェックしよう!