ランダム・ウォークの愉悦
みんな大好き!ランダム・ウォーク!🙂
シフマン先生の名著 The Nature of Code でも一番最初に出てくるランダム・ウォーク。
このランダム・ウォークで遊んでみましょう。
こちらの企画は 20/04/19 で終了させていただきました。ご協力ありがとうございました。🙂
本記事は「Processing Community Japan」のご協力をいただき、クリエイティブ・コーディング等のオンラインイベントの企画として『ブログを基に文字ベースでの双方向のコミュニケーション』が企画として成り立つかを確認することを一つの目的として書かせていただきました。
本記事へのご意見、ご感想、叱咤、「コードのここがわからない」、「こんなの作ってみた」、「もっと巧い方法あるよ」などなど Processing Community Japan Discord の『作者と語ろう』チャンネルにお寄せください。
私 deconbatch が力の限りお応えいたします。💪
『🗣️作者と語ろう』チャンネル
https://discordapp.com/channels/693060873312534579/694478240588365884
お寄せいただいたご意見等はブログ、Twitter 等で公開させていただく場合がございますので、ご了承ください。🙇♀️
そもそもランダム・ウォークってどんなもの?
ランダム・ウォークの数学的定義などはこちらを参照ください。
クリエイティブ・コーディングでランダム・ウォークを実現させる際の要点はこれだけ!
x += random(-1.0, 1.0);
y += random(-1.0, 1.0);
Processing で書いてみるとこんな感じ。
/**
* Simple Random Walk.
*
* Processing 3.5.3
* @author @deconbatch
* @version 0.1
* CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
* created 0.1 2020.03.31
*/
float pSize;
float x;
float y;
void setup() {
size(480, 320);
background(255);
pSize = min(width, height) * 0.05;
x = 0;
y = 0;
// マス目を描いてます
strokeWeight(1.0);
stroke(0);
for (int w = 0; w < width; w += pSize) {
line(w, 0.0, w, height);
}
for (int h = 0; h < height; h += pSize) {
line(0.0, h, width, h);
}
}
void draw() {
translate(width * 0.5, height * 0.5);
// ウォーカーを描いて
stroke(255);
fill(0);
ellipse(x, y, pSize, pSize);
// ランダム・ウォーキング
x += random(-1.0, 1.0) * pSize;
y += random(-1.0, 1.0) * pSize;
}
これを y 軸方向だけランダムにしてみましょう。
x += 1.0;
y += random(-1.0, 1.0);
これを放射状に施してみると?
これが
こんな風になります。
これを発展させるとこんなのができます。
Dreaming While You Sleep.
Electric Eye.
こんな感じでちょいと工夫するとランダム・ウォークでいろいろ楽しく遊べます。
ランダムじゃなくてノイズを使ってみる
パーリン・ノイズを使うと、滑らかに変化するランダム・ウォークを作れます。
x += map(noise(a, t), 0.0, 1.0, -1.0, 1.0);
y += map(noise(b, t), 0.0, 1.0, -1.0, 1.0);
ここで a, b は a ≠ b の固定値として、2つの noise() が異なる変化をするようにしています。 t は noise() を変化させるための変数で、少しずつ増加させるといいでしょう。
上手く調整するとこのように生き物の動きや手書きに似た動きを出せます。
マス目にそって動かしてみる
移動距離を固定値にして、一度に x方向か y方向にしか動けないようにするとウォーカー(ランダム・ウォークするもの、ここだと黒丸のこと)はマス目上を移動することになります。
さらに移動距離をウォーカーの大きさと同じにするとぐっとマス目感が増します。
pSize がウォーカーの大きさです。
p5.js のコードからの抜粋です。
let direction = random(-1.0, 1.0);
direction = (direction == 0) ? 1.0 : direction / abs(direction);
if (random(1.0) < 0.5) {
x += direction * pSize;
} else {
y += direction * pSize;
}
マス目を 3D にしてみるのも面白いです。
表示の仕方を工夫してみる
ここまでランダム・ウォークの動きにひと工夫を加えてみました。
今度はウォーカーの表示の仕方を変えてみましょう。
先程のマス目にそって動かすパターンで、ウォーカーを白黒で塗り分けてみると…
let direction = random(-1.0, 1.0);
direction = (direction == 0) ? 1.0 : direction / abs(direction);
if (random(1.0) < 0.5) {
x += direction * pSize;
fill(255);
} else {
y += direction * pSize;
fill(0);
}
fill() を 2つ加えただけでぐっと面白くなりました。
その他、ウォーカーの軌跡に線を引いてみるというのも面白いです。
ランダム・ウォークの作例
ウォーカーを白黒で塗り分けた例を、 vertex() を使って軌跡を面にしてカラフルにしてみた作例です。
p5.js のコードはこちら。
// Licensed under Creative Commons Attribution ShareAlikehttps://creativecommons.org/licenses/by-sa/3.0https://creativecommons.org/licenses/GPL/2.0/
let pSize;
function setup() {
createCanvas(720, 480);
strokeWeight(2);
stroke(0);
frameRate(1);
pSize = min(width, height) / 9;
}
function draw() {
background(240);
translate(width * 0.5, height * 0.5);
let pNo = 20 + (frameCount * 2) % 200;
let pX = 0;
let pY = 0;
beginShape(TRIANGLE_STRIP);
for (let i = 0; i < pNo; i++) {
// random walk
let direction = random(-1.0, 1.0);
direction = direction == 0 ? 1.0 : direction / abs(direction);
if (random(1.0) > 0.45) {
pX += direction * pSize;
fill(255);
} else {
pY += direction * pSize;
fill(random(255), random(255), random(255));
}
// Don't go outside! Please don't go! Please! Please come back to me! Please...
if (abs(pX) > width * 0.5) {
pX -= direction * pSize;
}
if (abs(pY) > height * 0.5) {
pY -= direction * pSize;
}
vertex(pX, pY);
}
endShape();
// bonus
fill(255);
ellipse(pX, pY, 10.0, 10.0);
}
ライセンスは OpenProcessing のスケッチと合わせました。
OpenProcessing 上でもご覧いただけます。
Twitter で拝見した印象的な作品
印象的だった他の方々のランダム・ウォークをいくつかご紹介。
vertex() を使う!なるほど!というヒントをいただきました。
この動き魅力的!真似してみようと思いましたがとても難しかったです。
ストンーと落ちていく様が気持ちええ…
ウォーカーが別のウォーカーを生み出す!この発想は無かったです!
その他にも面白い作品たくさんあります。PCD @ Tokyo の Twitter アカウントで色んな方の作品流れてくるのでチェックするとよいですよ。
その他の作例コード
その他の作例とそのコードがこちらからもご覧いただけます。
Processing の作例
白黒で塗り分けたものをコマ送りをゆっくりにしたアニメーションにしてみたら、なんだか未知のボードゲームを遊んでるように見えたので作品にしてみました。
これは「Twitter で拝見した印象的な作品」のおかずさんの作品に触発されて作ったものです。
p5js の作例
文中で紹介した白黒塗り分けのアニメーション作例です。
nasana さんの作品を拝見して、私もウォーカーの軌跡を curveVertex() で描いてみたら、なんだか方向音痴の人がさまよっているように見えて… 涙なしには見られない…
変更履歴
Processing Community Japan Discord の『作者と語ろう』チャンネルへの書き込みをもとに、ランダム・ウォークの定義を追記しました。(20/04/19)
この記事が面白かったらサポートしていただけませんか? ぜんざい好きな私に、ぜんざいをお腹いっぱい食べさせてほしい。あなたのことを想いながら食べるから、ぜんざいサポートお願いね 💕