先週から毎週THE GUILDにて開催されることとなった、
社員研修的な勉強会のレポートです。
第一回目のテーマは「乱数」です。
わたしは勉強会に1時間くらいしか参加できなかったのですが、
その中で「星の瞬き」というテーマでProcessingを用いたアニメーションスケッチを作成したので、それができるまでの過程を記録も兼ねてまとめます。
前置き
これまでにもjsで何度かMath.random()
を使っていたので
0から1の間のランダムな数を返してくれる関数
という認識はありましたが、
- ランダムに要素の色を変える
- ランダムにテキストをピックアップする
など非常に直接的「ランダム」な使い方しかしていませんでした。
勉強会の内容
fladdictさんのブログにまとめてあるレジュメをいただいて、
ピザをつまみながら、まず「乱数」の概要について教わりました。
その後は各自自分のレベルに合ったものを演習しつつ
わからないところがあれば聞く、といった感じで勉強会は進んでいました。
ひと通りレジュメの内容を理解したところで、早速、
課題:またたき
乱数を使って星空のようなまたたきを作る。
星には一等星もあれば五等星もある。さまざまな星をシンプルな乱数で実現する。
に挑戦することにしました。
1. ランダムな位置にランダムな大きさの星を配置してみる
まずは、ランダムな位置に、ランダムな大きさの星を配置してみました。
ランダム関数を、
- 星のx座標(0〜canvasのwidthの間)
- 星のy座標(0〜canvasのheightの間)
- 星の直径(1〜6px)
に使っています。
あまり星空っぽくないです。
少し直径の値のrandom値をいじってみました。
星の直径を1〜3pxのランダムにしています。
2. 星をバラバラに光らせる
まずは、それぞれの星の背景を単純なランダムで指定してみました。
これでは、あまりにもチカチカしているので、
それをおさえるために、正規分布を使ってみました。
下記、fladdictさんブログより。
4: 正規分布
下記2つの乱数は意味が大きく違う。
1 float val = random(100);
1 float val = (random(100) + random(100) + random(100) + random(100) + random(100) + random(100)) / 6;前者は均一な乱数。後者は中央(50周辺)に、偏った乱数になる。
サイコロを想像するとイメージしやすい。サイコロと2つふった場合、1ゾロは36分の1だが、7の目は1-6, 2-5, 3-4など複数存在する。
正規分布は自然の乱数では多くみられるため、こちらを採用するほうがオーガニックな感触にしやすい。
Processingのグレースケールで100から200のランダムな数6つの正規分布を使っています。
ちなみに、以前制作させていただいたこちらでも、正規分布を使用して光のゆらぎを表現しました。
あれこれ試行錯誤してだんだん近づいてきた感じはありますが、
“瞬いてる”よりも“ピカピカ光っている”ように見えてしまいます。
ここで、「星によってよく光る星もあれば、光らない星もあるよね」というヒントをもらったので、
星によって、ランダムを求める範囲を広げたり狭めたりするような変数をランダムに設定し、
それぞれの星がその固有の変数の間での正規分布を使って色が変わるようにしてみました。
だいぶ瞬いてるように見えてきた気がします。
3. 星の大きさによって、数を調整してみる
最後に、「大きいサイズの星ほど少なく、小さなサイズの星ほどたくさんあるようにしてみたら?」という大ヒントをもらって、実際の星空へと近づけてみました。
このような星のサイズの計算にはいろんな方法があるということでしたが、今回は
1 + abs(cos(radians(random(360))))
を使ってみました。
ランダムを角度にとったcos(コサイン)の絶対値を使うことで、
0付近が多く、1付近は少ない、という結果が得られるため、
それに1をプラスして星が直径1px〜2pxとなるようにしています。
パラメータをいじりつつ、ひとまず完成です!
まとめ
冒頭でも書いたようにこれまで、ランダム関数を
- ある図形のサイズ
- 無作為な文字の抽出
など、あるものに対して直接的に使うということしかしてきませんでした。
しかし今回、最終的にはランダム関数を
- 星の位置
- 星の大きさを出すためのcosの角度
- 個々の星がどのくらいの範囲から色を選べるかという変数
- 個々の星が瞬間瞬間で何色になるか
といったものに使用することで、自然現象に近いものへと近づけることができました。
cos,sinなど既存の関数の変数としてのランダムを使ってみたり、
さらに関数から変数を自然現象に近い形でランダムにとってくるための変数にランダム関数を使う、といったように、ランダムを間接的に使用することで表現の幅がとても広がることがわかりました。
同じ勉強会を受講していたcocoponさんの作品はこちらです。
このくらいモニョモニョ動かせるようになれるよう、
日々精進していきたいと思います。
勉強会とは別に、10月頭頃からProcessingをちまちま学んでいるのですが、
深津さんにおすすめしていただいた『Nature of Code -Processingではじめる自然現象のシミュレーション-』にも今回のようなヒントがたくさん詰まっていて、とってもオススメです。