👉 Read this article in English.
'Processing' で書いたクリエイティブ・コーディングのアニメーションです。
Worley ノイズの変わった使い方ができないか?
Worley ノイズを使った描画は、距離を元に明度や色相を決定して描画するのが定石です。
Worley ノイズについて詳しくはこちらをどうぞ。
定石とは違う、ちょっと変わった使い方はないかな?と思い、今回は距離を角度に変換して移動するウォーカーを作り、その軌跡を描画してみました。
「こういう軌跡」という視点ではなく、「こういうウォーカー」を作ったらどういう軌跡になるかな?という視点で作成したものです。 その結果、割と面白い動きになったので、アニメーションにしてみました。
'Processing' のサンプルコード
GPL で公開します。GPL の条項に基づいて、どうぞご自由にお使いください。このコードを利用して何か作品を作ってもらえるととても嬉しいです。
本コードはスクリーン上には何も描画しません。描画の結果は画像ファイルとして保存されます。その画像ファイルを元にアニメーションの動画を作成できます。
/**
* Walk On By.
* I tried to use the distance value as the direction of the walker.
*
* Processing 3.5.3
* @author @deconbatch
* @version 0.1
* created 0.1 2021.09.12
*/
void setup() {
size(720, 720);
colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
smooth();
noLoop();
}
void draw() {
int frmMax = 30 * 6;
int cycleMax = 3;
float baseHue = random(360.0);
translate(width * 0.25, height * 0.25);
for (int cycleCnt = 0; cycleCnt < cycleMax; cycleCnt++) {
int nodeMax = 30;
float nodeGap = 0.05 * min(width, height);
float zigzag = random(12.0, 18.0); // walker path roughness
int plotMax = floor(20.0 * zigzag);
baseHue += 90.0;
// make randomly located nodes
ArrayList<PVector> nodes = plotNodes(randomAdds(nodeMax, width * 0.5, height * 0.5), nodeGap);
for (int frmCnt = 0; frmCnt < frmMax; frmCnt++) {
float easeRatio = InFourthPow(map(frmCnt, 0, frmMax, 0.0, 1.0));
background(baseHue % 360.0, 30.0, 80.0, 100.0);
drawWalker(nodes, plotMax, zigzag, easeRatio);
saveFrame("frames/" + String.format("%02d", cycleCnt) + String.format("%03d", frmCnt + 1) + ".png");
}
}
exit();
}
/**
* randomAdds : make random PVectors
*/
public ArrayList<PVector> randomAdds(float _rndsMax, float _width, float _height) {
ArrayList<PVector> rnds = new ArrayList<PVector>();
for (int rndsCnt = 0; rndsCnt < _rndsMax; rndsCnt++) {
rnds.add(new PVector(random(_width), random(_height)));
}
return rnds;
}
/**
* plotNodes : locate Nodes with some distance each other.
*/
public ArrayList<PVector> plotNodes(ArrayList<PVector> _adds, float _gap) {
ArrayList<PVector> nodes = new ArrayList<PVector>();
for (int i = 0; i < _adds.size(); i++) {
float fX = _adds.get(i).x;
float fY = _adds.get(i).y;
// collision?
boolean collision = false;
for (PVector f : nodes) {
if (dist(fX, fY, f.x, f.y) < _gap) {
collision = true;
break;
}
}
// add new node
if (!collision) {
int pixIndex = floor(fY * width + fX);
nodes.add(new PVector(fX, fY));
}
}
return nodes;
}
/**
* drawWalker : draw walker with Worley's noise method.
*/
public void drawWalker(ArrayList<PVector> _nodes, int _plotMax, float _zigzag, float _drawRatio) {
float range = max(width, height);
float step = floor(range * map(_drawRatio, 0.0, 1.0, 0.020, 0.015));
int plotMax = floor(map(_drawRatio * _drawRatio, 0.0, 1.0, 0.1, 1.0) * _plotMax);
PVector initNode = _nodes.get(0);
float x = initNode.x;
float y = initNode.y;
ArrayList<PVector> walker = new ArrayList<PVector>();
walker.add(new PVector(x, y));
// walk along the nearest node
int minIndx = 0;
for (int plotCnt = 0; plotCnt < plotMax; plotCnt++) {
float minDist = range;
for (int i = 0; i < _nodes.size(); i++) {
float d = dist(x, y, _nodes.get(i).x, _nodes.get(i).y);
if (minDist > d) {
minDist = d;
minIndx = i;
}
}
float r = _zigzag * PI * sin(PI * minDist / range);
x += step * cos(r);
y += step * sin(r);
walker.add(new PVector(x, y));
}
// draw walker path
noFill();
stroke(0.0, 0.0, 0.0, 100.0);
strokeWeight(1.0);
beginShape();
for (PVector w : walker) {
ellipse(w.x, w.y, 4.0, 4.0);
vertex(w.x, w.y);
}
endShape();
// draw nodes
noFill();
stroke(0.0, 0.0, 0.0, 100.0);
strokeWeight(1.0);
for (PVector n : _nodes) {
ellipse(n.x, n.y, 14.0, 14.0);
}
ellipse(_nodes.get(minIndx).x, _nodes.get(minIndx).y, 4.0, 4.0);
}
/**
* InFourthPow : easing function.
*/
private float InFourthPow(float _t) {
return 1.0 - pow(1.0 - _t, 4);
}
/*
Copyright (C) 2021- deconbatch
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/