見出し画像

ランダム・ウォークの愉悦

みんな大好き!ランダム・ウォーク!🙂
シフマン先生の名著 The Nature of Code でも一番最初に出てくるランダム・ウォーク。

このランダム・ウォークで遊んでみましょう。

こちらの企画は 20/04/19 で終了させていただきました。ご協力ありがとうございました。🙂

本記事は「Processing Community Japan」のご協力をいただき、クリエイティブ・コーディング等のオンラインイベントの企画として『ブログを基に文字ベースでの双方向のコミュニケーション』が企画として成り立つかを確認することを一つの目的として書かせていただきました。

本記事へのご意見、ご感想、叱咤、「コードのここがわからない」、「こんなの作ってみた」、「もっと巧い方法あるよ」などなど Processing Community Japan Discord の『作者と語ろう』チャンネルにお寄せください。
私 deconbatch が力の限りお応えいたします。💪

『🗣️作者と語ろう』チャンネル
https://discordapp.com/channels/693060873312534579/694478240588365884

お寄せいただいたご意見等はブログ、Twitter 等で公開させていただく場合がございますので、ご了承ください。🙇‍♀️

画像1

そもそもランダム・ウォークってどんなもの?

ランダム・ウォークの数学的定義などはこちらを参照ください。

クリエイティブ・コーディングでランダム・ウォークを実現させる際の要点はこれだけ!

x += random(-1.0, 1.0);
y += random(-1.0, 1.0);

画像8

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);

画像9

これを放射状に施してみると?

画像10

これが

画像11

こんな風になります。

これを発展させるとこんなのができます。

画像12

Dreaming While You Sleep.

画像13

Electric Eye.

こんな感じでちょいと工夫するとランダム・ウォークでいろいろ楽しく遊べます。

画像2

ランダムじゃなくてノイズを使ってみる

パーリン・ノイズを使うと、滑らかに変化するランダム・ウォークを作れます。

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() を変化させるための変数で、少しずつ増加させるといいでしょう。

上手く調整するとこのように生き物の動きや手書きに似た動きを出せます。

画像14

画像15


画像3

マス目にそって動かしてみる

移動距離を固定値にして、一度に 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;
}

画像16

マス目を 3D にしてみるのも面白いです。


画像4

表示の仕方を工夫してみる

ここまでランダム・ウォークの動きにひと工夫を加えてみました。
今度はウォーカーの表示の仕方を変えてみましょう。

先程のマス目にそって動かすパターンで、ウォーカーを白黒で塗り分けてみると…

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);
}

画像17

fill() を 2つ加えただけでぐっと面白くなりました。


その他、ウォーカーの軌跡に線を引いてみるというのも面白いです。


画像5

ランダム・ウォークの作例

画像18

ウォーカーを白黒で塗り分けた例を、 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 上でもご覧いただけます。


画像6

Twitter で拝見した印象的な作品

印象的だった他の方々のランダム・ウォークをいくつかご紹介。

vertex() を使う!なるほど!というヒントをいただきました。

この動き魅力的!真似してみようと思いましたがとても難しかったです。

ストンーと落ちていく様が気持ちええ…

ウォーカーが別のウォーカーを生み出す!この発想は無かったです!

その他にも面白い作品たくさんあります。PCD @ Tokyo の Twitter アカウントで色んな方の作品流れてくるのでチェックするとよいですよ。

画像7

その他の作例コード

その他の作例とそのコードがこちらからもご覧いただけます。


Processing の作例

画像19

白黒で塗り分けたものをコマ送りをゆっくりにしたアニメーションにしてみたら、なんだか未知のボードゲームを遊んでるように見えたので作品にしてみました。

画像20

これは「Twitter で拝見した印象的な作品」のおかずさんの作品に触発されて作ったものです。

p5js の作例

画像21

文中で紹介した白黒塗り分けのアニメーション作例です。

画像22

nasana さんの作品を拝見して、私もウォーカーの軌跡を curveVertex() で描いてみたら、なんだか方向音痴の人がさまよっているように見えて… 涙なしには見られない…

画像23

変更履歴

Processing Community Japan Discord の『作者と語ろう』チャンネルへの書き込みをもとに、ランダム・ウォークの定義を追記しました。(20/04/19)



この記事が面白かったらサポートしていただけませんか? ぜんざい好きな私に、ぜんざいをお腹いっぱい食べさせてほしい。あなたのことを想いながら食べるから、ぜんざいサポートお願いね 💕