トロコイドを使ってクリエイティブコーディングをしてみた。
さて、まずはトロコイドは何?というところですが、困ったときのWikipediaですね。
トロコイド (trochoid) とは、円をある曲線(円や直線はその特殊な場合)にそってすべらないように転がしたとき、その円の内部または外部の定点が描く曲線。
とのことです。Wikipediaのページにgifアニもついてるので、わかりやすいかと思います。
そして、今回作ったものはこちら。
2D Line drawing by trochoid (2d branch)
3D Line drawing by trochoid (master branch)
ソースコードは以下。
今回は、外トロコイド(epitrochoid)または内トロコイド(hypotrochoid)上の任意の2点を結ぶ線分をたくさん描画する、という手法です。その際、いろんなパラメータを変化させることで、トロコイドの形が変化します。
トロコイドの式の説明です。まずは外トロコイド(epitrochoid)。
(gif animation by Sam Derbyshire at the English Wikipedia)
定円の半径をrc、動円の半径をrm、回転角をθ、描画点の半径をrd とすると、外トロコイドの座標は、以下の式で表されます。
続いて内トロコイド。基本的には外トロコイドとあまり変わりません。
(gif animation by Sam Derbyshire at the English Wikipedia)
線分を描画するための任意の2点を決めるのに上記の式を使用しています。時間経過をシェーダに渡し、その値を使用してθを決定しています。まず、線分の端点の一方のθを決め、任意に位相をずらして他方の端点のθを決め、線分の2点を決定しています。そして線分ごとに位置がずれるように、線分ごとにも位相差を設けています。
float t = mod(time * 0.00003 + position.x * i + instanceIndex * 0.01, PI * 2.0);
上がシェーダのコードの抜粋です。tが上の式で言うθです。timeがuniformで渡される時間経過の値、iが線分の端点の位相差、instanceIndexは線分ごとに振られるインデックス番号です。こんな感じでたくさんある線分の端点の位置を算出するためのパラメータθの値を決定しています。
定円の半径rcが、動円の半径rmの整数倍になっていると、θを0から2πで動かしながら描画した際に、描画点の始点と終点がきれいに繋がります。
今回のプログラムは2秒に1回自動でパラメータが変わるようになっています。その歳にrcがrmの整数倍になるようにしています。
↑外トロコイドを使用したもの
↑内トロコイドを使用したもの
以上をふまえて、以下2Dの方のdat.GUIのパラメータの説明です。
・rc … 定円の半径
・rm … 動円の半径
・rd … 描画点の半径
・i … 線分の端点の位相差の係数
・scale … 描画する大きさ
・noiseFactor … ※後述
・isOuter … 外トロコイドかどうか
・autoPlay … 2秒に1度の自動パラメータ変化をするかどうか
・random … クリックすると、パラメータをランダムで変化させる
rc, rm, rdは上記の式のとおりです。
iは線分の端点の位相のズレの係数です。この値が小さくなると、2点の距離が小さくなります。この値が0に近いほど、トロコイドの形がはっきりわかります。
noiseFactorは、各端点のz座標をnoise関数でずらすことができます。その際の係数です。実はこのプログラム、ドラッグでぐりぐりするとカメラの位置が変わります (もともとは3Dに拡張したとき用に用意したもの)。
noiseFactorを0より大きくしてドラッグすると、各点のz座標がずれているのが確認できると思います。
zがずれると、秩序がありながらも少し面白い形になったりします。
↑noiseFactorを加味した外トロコイド
↑noiseFactorを加味した内トロコイド
さて続いて3Dバージョンです。
3Dバージョンは、以下のサイトによると次のような式で表されるようです。(このページ、よく参考にさせていただいております。。)
3次元の場合は多面体の時と同じように、平面のx,yの媒介変数によるトロコイドの関数をそれぞれhcyc(t), hcys(t)と置くと、
このようになります (なるらしいです)。あとは2Dのやつをちょっと拡張するだけですね。こんな感じになりました。個人的には2Dのほうが美しい図形ができていたように思えます。
3Dにしたことによって、ドラッググリグリ機能が活かされました。
↓ついでにbloomエフェクト的なものをつけてみました。
dat.GUIのeffectのところでON/OFFの切り替えができます。
・・・
個人的に、けっこうこのような数学的に美しい図形が好きなので、ほかにもいろいろ試してみたいなと思っています。
今回も長い割には情報量が少ないですが、ここまで読んでいただきありがとうございます。
サポートいただければ、レッドブルを飲んでより頑張れると思います。翼を授けてください。