p5.jsのcurveVertex()で曲線描いていたら渦巻きになった


2018年05月04日
With
p5.jsのcurveVertex()で曲線描いていたら渦巻きになった はコメントを受け付けていません

せっかくの連休なので、じっくり腰を据えて面白いスケッチのひとつでも描いてみたいところなのですが、今年もありがたいことに「連休前取材、連休明け納品」なスケジュールでいくつか書き仕事を承っておりまして、そのへんコチャコチャやりつつ、煮詰まったら気分転換にTwitterを眺めるという、あまり普段と代わり映えのしない日常を過ごしております。

p5.jsをはじめてから、Twitterでもクリエイティブコーダーのみなさんを何人かフォローさせていただくようになったのですが、ここ最近、にわかに界隈の活動が活発になっているようでもあり、コーディングはじめて1年ほどのド文系野郎である僕も、大変良い刺激を受けています。たとえば、この連休中にも、クリエイティブコーダーの梶田悠さんが、noteにこんなエントリを書いていらっしゃいました。

●なめらかな多角形から始まるジェネラティブアート#1|梶田悠|note

このエントリでは、Processingの「curveVertex()」を使って、曲線的な三角形を描く手順をとても分かりやすく解説してくださっています。

p5.jsにも同じように使える「curveVertex()」メソッドがあります。

・p5.js | curveVertex() – Reference

そういえば以前、ベジェ曲線を描くための「bezierVertex()」を使ったことは何度かあったのですが、「curveVertex()」はまだ試していませんでした。

・p5.js | bezierVertex() – Reference

・Noise Stream for p5.js
・p5.jsで「パーリンノイズ」のスゴさを思い知る

いい機会なので「curveVertex()」の挙動を確かめてみようと、リファレンスを見ながらポチポチ点を打ち、思いつくままに頂点を増やしてnoiseで変化を付けていたら…なんかキモくなりました(笑)。

●curveVertex()の練習(クリックすると別タブが開きます)

↑の図形、角が丸い星形が多重で重なっているように見えると思うのですが、よーく見ると、実際には「渦巻き」になっています。…いや、本当は多重に重ねるつもりで書いてたんですけどね…。なんでだろう?

(※追記:↑こちらの件、コードをよく見るとわかりますが、単に「beginShape()」「endShape()」の位置がマズいだけでした…。お恥ずかしい。次のエントリで、閉じた図形を複数重ねるスケッチを描きました

「curveVertex()」は、「vertex()」や「bezierVertex()」などと同じように「beginShape()」と「endShape()」の間に挟んで書きます。すると、書いた座標の間を順番に、スムーズにつなぐように線を引いてくれます。

ちょっと独特なのは、「最初の座標と2番目の座標」「最後の座標と最後の1つ前の座標」との間にはstrokeが書かれないところでしょうか。最初と最後の座標は、strokeの始点、終点まわりの「曲がり具合」を指定するための制御点になるようです。つまり、滑らかな曲線でくるりと囲んだ閉図形を描きたいときは、最初の座標の前に「終点の座標」、最後の座標の後に「始点の座標」を入れておいてやるとよいようです。

(※追記:↑こちらの件、正しくは「先頭と終端で、同じ座標の点を『3点』重ねて指定してやる」ということだったようです。次のエントリでは、その方法で角の丸い星形六角形を描きました

ま、細かい仕様は実際に使いたくなったら改めて検証することにして、今回はこのくらいで。コードはこんな感じになっています。

var repnum = 45;
var startRad = 5;
var starStrkWeight = .1;
var xnoiseCord = Math.random(2000) - 1000, ynoiseCord = Math.random(2000) - 1000;
function setup() {
	createCanvas(600, 600);
	noFill();
}
function draw() {
	background(255);
	translate(width / 2, height / 2);
	rotate(frameCount / 100);
	var peaks = [];
	for (var h = 0; h < repnum; h++) {
		for (var i = 0; i < 360; i += 36) {
			var j;
			if (i % 72 != 0) {
				j = startRad + ((starStrkWeight + 4) * h) + (noise(xnoiseCord) * 800 - 500);
			} else {
				j = ((startRad + ((starStrkWeight + 4) * h)) + (noise(ynoiseCord) * 800 - 500)) * .65;
			}
			peaks.push(createVector(sin(radians(i)) * j, cos(radians(i)) * j));
		}
		stroke(96, 100);
		strokeWeight(starStrkWeight);
		beginShape();
		peaks.forEach(peak => {
			curveVertex(peak.x, peak.y);
		});
		endShape();
	}
	xnoiseCord += .005;
	ynoiseCord += .005;
}

余談ですが、最近、Shiffman先生の「The Coding Train」で、JSON形式でのデータ読み込みや、node.jsとWebSocketによるリアルタイム通信などを使ったp5.jsスケッチを見て、ちょっとそういったこともやってみたいと思うようになりました。ジェネラティブアートに限らず、「こういうの作りたい」と思いついたら、すぐにp5.jsでプロトタイプ化できるくらいのコーディングスキルを身につけるというのを、今年後半の目標にしてみたいと思います。まだ5月ですが。