p5.jsでライフゲーム

p5.jsでライフゲームを作成しました。

剰余による回り込み

二次元配列のboard[0][0]の場合は、近傍(neighbor)を調べるときに、board[-1][-1]のようになりエラーになってしまいます。このような場合は、(カラム数+現在のカラム-1%カラム数) のように書くと、カラム数が20だったらboard[19]となってくれます。一次元配列でもこの剰余のテクニックを使うと、配列をリングに見立てることができるので、非常に便利です。

ライフゲーム自体の実装は、着実に進めていけば簡単です。

 

p5.jsで一次元セルオートマトン

p5.jsで一次元セルオートマトンを作ってみました。ルール関数を作成し、0-255でルールを生成できるようにしました。ルール生成関数は、ビット演算とシフト演算んでもっと綺麗な実装にできそうです。

剰余による回り込みの実装

また、(配列の長さ+現在のインデックス)%配列の長さ というテクニックを使い、配列の0番目で、左端の値の場合は、配列の最後である右端の値を取得するようにしました。

 

 

 

簡単にvscodeでp5jsの入力補完をする方法

はじめてプログラミングをしてみた人でも設定できるp5jsの入力補完の方法です。マイクロソフトが無料で開発しているvscode(=Visual Studio Code)エディターを使うとp5jsの補完が簡単にできます。

tsファイルをダウンロード

以下のリンクから、p5.d.tsファイルとp5.global-mode.d.tsファイルをダウンロードして、プロジェクトのフォルダーに配置します。

https://github.com/LujunWeng/demos-p5js/tree/master/typings/p5js

tsファイルをダウンロードしたところ

コメント行を書く

sketch.jsのはじめの行に上記のコメントを書きます。あとは、createなどを書くと入力補完ができるようになります。

入力補完ができた!

vscodeの入力補完は優秀で、引数の値を入力すると、その細かい内容まで以下のように表示してくれます。

技術的な話

tsファイルはTypeScriptの型定義ファイルで通常TypeScriptで使われますが、TypeScriptはJavaScriptのスーパーセットなので、.jsファイルも混在可能です。そのためふぃあるのコメント行で型定義ファイルを指定すると補完が可能になります。このファイルの英語を日本語に直せば単純に変更できます。github上でTypeScriptの補完に関しても議論されているようです。現状、npm の@typesでこの型定義ファイルがダウンロードできないので、今後p5.js団体が管理してくれるとありがたいです。

まとめ

すべて手入力は面倒なので、簡単に補完する方法をまとめました。単純にファイルをダウンロードして、コメント行を追加するだけなので、プログラマーでない人でも簡単に導入できると思います。

 

p5.jsで2Dパーリンノイズを動かすにはコツがいります。

書籍Nature of Codeを買ったので最初の章をp5.jsで試してみました。2Dパーリンノイズを作ってみる課題があったのですが、書籍の書き方ではうまくいきませんでした。githubのサンプルコード(https://github.com/shiffman/The-Nature-of-Code-Examples-p5.js/tree/master/chp00_introduction)にも、サンプルはありませんが、Youtube動画でコーディングしていました。

See the Pen 2D perlin noise p5.js by dev001hajipro (@dev001hajipro) on CodePen.0

考え方

1.単純な二次元配列の要素の取得を考える。

横幅(width)を100px、縦幅(height)を100pxで考えると、2重のfor文で二次元配列の座標(X,Y)を求める事ができます。これはよくある実装方法なので難しくないです。

2.一行はRGBAが並んでいる事を考慮する

p5.jsのpixels配列は、1つの要素にRGBAがオブジェクトとして含まれるのではなく、R、G、B、A、がpixels配列の要素で連続で並んでいます。例えば、横幅5pixelで、縦幅2pixelの場合は、以下のような感じです。

このため、ピクセル単位で処理をしたい場合は、4単位で移動させるように、for文のステップ数を変更します。

3.画像は通常一次元配列

私たちはXY座標で操作するほうが簡単ですが、画像データは一次元配列でpixels配列も同様です。そのため、(1行の幅 * 行数) で現在行までの要素数を求めて、そこに現在のX座標を足します。

(1行の幅 * 行数) + 現在のX

p5jsが予約しているwidthグローバル変数はキャンバスの横幅、heightグローバル変数はキャンバスの縦幅を取得できます。これはちょうどcreateCanvasで指定した値です。また、今回の一行はRGBARGBARGBAのようになっているため4倍にする必要があります。

此処までで、各pixels要素であるRGBAにアクセスし、直接色を指定できるようになりました。以下はRGBA(255,0,0,255)を指定して、全てのピクセルを赤で染めるサンプルです。

4.Densityを考慮する

Retinaディスプレイや携帯電話の場合、より綺麗な画像を表示するためにPiexl per Inch(https://ja.wikipedia.org/wiki/Ppi)、所謂、画素密度が異なります。そのためpixelDensityで値を取得して、縦幅、横幅に掛けます。1行は、width*4*dになります。よって、(width*4*d)*yで、現在行数の要素数を求めて、それにxを加えることで、現在のピクセル位置が求まります。ゆっくり考えれば問題ありませんが、(width*4*d)*y*dみたいにしないように注意してください。

此処までで、高解像度ディスプレイの場合でも各RGBAを修正することができるようになりました。

5.横のノイズをリセットする

p5.jsでは、noise(x,y)を設定すると二次元のパーリンノイズを使うことができます。y=1の固定にして以下のコードを書きました。注意してほしいのは、noise(xoff)を1行単位でリセットすることです。つまり3行目のlet xoff = 0;のように書きます。

二重ループの前にxoffの変数定義をすると、パーリンノイズ関数は、xがずっと続いていると判断するため、意図したノイズになりません。

xoffが正しくない例

yoffも定義する

ここまでくればもう理解できたと思います。あとは、yoffを指定するだけです。

 

まとめ

p5.jsでのピクセル操作と2Dパーリンノイズを実装することができました。まずは、RGBA単位のピクセル操作をできるようにして、そのあとに高解像度を考慮して、最後に2Dパーリンノイズを実装しました。いちどにすべてをやろうとすると、どこが原因で表示できないのかが分からなくなるので、このような実装は、段階的にやったほうが良いようです。

意外と簡単!Node Gardenを作ってみましょう!

 

node_garden

 

Node Gerdenは、白丸を線で繋いだアニメーションです。白丸をTwitterのアイコンにしたり、Youtubeのお気に入り画像を表示すれば、関係性を視覚化できたりします。複雑なようで実は簡単なのでProcessingで作ってみましょう。

以下ソースコードがたくさん書かれているように感じますが、修正前と修正後のソースコードをすべて貼り付けているためです。実際はコメントを含めて100行ぐらいで、簡単なので挑戦してみてください。

 

大まかな作り方を把握

  1. ノード(白丸)をランダムに表示します。
  2. 白丸が移動できるようにします。
  3. すべての白丸を線でつなぎます。
  4. ある一定の距離だけ線でつなぐように修正します。
  5. (応用)線をばね(スプリング)と考え、白丸の速度に変化を加えます。

ノードをランダムに表示します。

 

白丸が移動移動できるようにします。

ノードクラスに速度を表すxv(X座標のVelocity)とyvを用意して、描画毎にxy座標に足すことで移動します。また画面外に移動した場合は、反対側から出てくるようにします。例えば白丸が右側に進んで画面外になったら、左側からでてくるようにします。

 

すべての白丸を線でつなぎます。

node_garden02

ある一定の距離だけ線でつなぐように修正します。

node_garden03

ここまででほぼ完成しました。冷静に考えると2点の丸を好きな場所に表示して、それを移動するようにして、線でつなげるだけです。

(応用)線をばね(スプリング)と考え、白丸の速度に変化を加えます。

node_garden04

線を表示した場合は、少しだけ速度を変化させるようにしました。例えばx座標の距離dxが100ピクセルなら、係数0.0001を掛けて、0.001速度を加えます。値はかなり小さいのですが、1/60秒毎にこのメソッドが呼ばれているためかなりの効果があります。いろいろ係数を調整してみてください。

また、ノード間の距離が長くなると線が薄く表示されるようにアルファチャンネルを修正しました。

 

このコードでは、ばね効果でどんどんノードの速度が速くなってしまいます。vx,vyがある一定速度になったら、0.5に戻すなどの処置をすると綺麗になります。

応用

基礎のため白色の丸でしたが、別に画像ファイルでも問題ありません。そのため、TwitterアイコンやYoutubeのサムネイルでノードを作成して、関連が強いものは引き合うアルゴリズムなどを作ってみるとおもしろそうです。またノードの追加、削除、ノードをクリックしたときのエフェクトや、任意のノード間の最短経路など様々応用が可能です。

まとめ

インターネット上では日本語でもNode Gardenのサンプルはあるのですが解説が少ないので、ProcessingでNode Gardenを作ってその解説をしてみました。作る前はすごく大変そうと思っていたのですが、100行足らずで作成できたので拍子抜けでした。

ProcessingでNode Gardenを作成

 

node_garden

ProcessingでNode Gardenを作成してみました。