p5.jsでランダムウォークを実装する

クリエイティブコーディング、ジェネラティブアート...呼び方はさまざmですが、今回は有名な表現方法であり比較的簡単な「ランダムウォーク」をp5.jsで作ってみようと思います。

こんな感じ
https://editor.p5js.org/mtoutside/sketches/ZdmmhEN9i
![wip_p5js_210115.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241879/6bac00eb-455b-181d-212f-79016f44d4c8.gif)

## ランダムウォークとは

[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%B3%E3%83%80%E3%83%A0%E3%82%A6%E3%82%A9%E3%83%BC%E3%82%AF)には

>ランダムウォーク（英: random walk）は、次に現れる位置が確率的に無作為（ランダム）に決定される運動である。日本語の別名は酔歩（すいほ）、乱歩（らんぽ）である。グラフなどで視覚的に測定することで観測可能な現象で、このとき運動の様子は一見して不規則なものになる。

と書いてありました。オブジェクトが無作為の方向に進んでいく、**ランダム**に**ウォーキング**するからランダムウォークといいます。そのままですね。

## ランダムウォーク実装の考え方
ロジックとしては、

1.  各方向を定義
1.  `random`関数を使用して、進む方向を決定
1. 進む
1. 2~を繰り返し

だいたいこんな感じの考え方です。

### 開発環境
[p5.js](https://p5js.jp/)はJavaScriptのライブラリなので、基本ブラウザとテキストエディタがあれば動きます。手っ取り早く触ってみたかったら

https://editor.p5js.org/

がおすすめです。なんの用意も要らずブラウザから動かせて便利です。

## コード
先に全体のコードを載せます。

```randomWalk.js
const NORTH = 0;     // 上
const NORTHEAST = 1; // 右上
const EAST = 2;      // 右
const SOUTHEAST = 3; // 右下
const SOUTH = 4;     // 下
const SOUTHWEST = 5; // 左下
const WEST = 6;      // 左
const NORTHWEST = 7; // 左上
let direction;

const stepSize = 1;
let diameter = 1;

let posX, posY;

function setup() {
  createCanvas(windowWidth, windowHeight);
  noStroke();
  fill(0, 40);
  
  posX = width / 2;
  posY = height / 2;
}

function draw() {
 background(255, 5);
  for(let i = 0; i <= mouseX; i++) {
    direction = int(random(0, 8));
    diameter = random(1, 3);
    
    if(direction === NORTH) {
      posY += stepSize;
    } else if(direction === NORTHEAST) {
      posX += stepSize;
      posY += stepSize;
    } else if(direction === EAST) {
      posX += stepSize;
    } else if(direction === SOUTHEAST) {
      posX += stepSize;
      posY -= stepSize;
    } else if(direction === SOUTH) {
      posY -= stepSize;
    } else if(direction === SOUTHWEST) {
      posX -= stepSize;
      posY -= stepSize;
    } else if(direction === WEST) {
      posX -= stepSize;
    } else if(direction === NORTHWEST) {
      posX -= stepSize;
      posY += stepSize;
    }
    
    // 画面の端まで到達したら反対側の端へ移動
    if(posX > width)  posX = 0;
    if(posX < 0)      posX = width;
    if(posY < 0)      posY = height;
    if(posY > height) posY = 0;    

    // 円を描く
    ellipse(posX + stepSize / 2, posY + stepSize / 2, diameter, diameter);
  }
}

function keyReleased() {
  if(keyCode === DELETE || keyCode === BACKSPACE) clear();
}
```

以下ポイントを解説していきます。

### 方向を定義
ランダムで進む方向をここで定義しています。全部で8方向です。

```js
const NORTH = 0;     // 上
const NORTHEAST = 1; // 右上
const EAST = 2;      // 右
const SOUTHEAST = 3; // 右下
const SOUTH = 4;     // 下
const SOUTHWEST = 5; // 左下
const WEST = 6;      // 左
const NORTHWEST = 7; // 左上
```

### `random`関数で進む方向を決定

```js
for(let i = 0; i <= mouseX; i++) {
    direction = int(random(0, 8));    
    // 省略
  }
```

全8方向のなかからランダムで方向を決定するので、
`direction = int(random(0, 8));`
のようにして進む方向を決めます。あとは`if文`で各方向へ進む処理を書いていきます。

今回はマウスのX座標に応じて進むスピードを変えています。画面（描画エリア）の右に行くほどスピードが速くなります。

```js
for(let i = 0; i <= mouseX; i++) { // iの終了条件をマウスのx座標にしている
```

## まとめ
というわけでランダムウォークを実装してみました。クリエイティブコーディング系の本とかにもだいたい載っている有名な表現です。ロジックもシンプルなので簡単に実装できるかと思います。