はじめに
前回、フーリエ変換について詳しく見てきましたが、「いまいちピンとこない」と言う方も多かったのではないでしょうか。
そんな方に、「なんとしてでもフーリエ変換の面白さを伝えたい!!」ということで作ったプログラムを今回の記事で説明していきたいと思います。
フーリエ変換でピーポくん書くやつの進化版!?作った
— 甲陽學院髙等學挍 物理部 (@koyobutsuri) 2018年8月26日
ペンの軌跡をXY方向でそれぞれに離散フーリエ変換(DFT)かけて、円の回転に置き換えるというもの
ソースコードは、じきに公開するつもり pic.twitter.com/4buibaN8Ri
上の動画を見ていただければわかるように、複数の円がグルグル回っていたのがわかると思います。とても複雑な動きをしているように見えますが、実は円の回転速度や大きさは一定でただ単純に円の周りを円が回っているだけです。ニョロニョロとして気持ち悪いですが、どんな絵でも円の回転運動で描画することができます。
どのような仕組みなのか順番にご説明したいと思います。
仕組み
大まかな流れとしては
- ペンの移動をXY方向で別々にサンプリング
- 波形をフーリエ変換でsinとcosの成分に分割
- sinとcosを合成して、sinだけの関数に直す
- それらを元に円を描画
sinとcosはそもそも単位円周上を回る点のXY方向の座標を表すものであるため、円運動に変換することができます。
プログラム解説
説明が必要とされると思われる箇所を解説していきたいと思います。
波形の表示
現在のピクセル情報をloadPixels()関数で読み取り、それを左と上に順に配列をシフトし、updatePixels()で更新することで、まるでオシロスコープのように波形を移動させています。
離散フーリエ変換(DFT)
引数として渡された波形データを下の数式を元に離散フーリエ変換を行い、配列に代入します。realは実数部分をimagは虚数部分の配列です。渡されるimagのデータは全て0であるため、計算の際は使用していません。
&=&\frac{1}{N}\sum_{k=0}^{N-1} f_k\Bigl(\cos(\frac{2n\pi}{N}k)-i\sin(\frac{2n\pi}{N}k)\Bigl) \end{eqnarray}
円の座標に変換
DFT関数でsinとcosの係数を求めることができましたが、sinとcosの和をsin単体にまとめることができれば、円の運動として表すことができるようになります。そのために使うのが三角関数の合成公式です。
$$a\sin\theta+b\cos\theta=\sqrt{a^2+b^2}\sin(\theta+\alpha)$$
$$\tan\alpha=\frac{b}{a}$$
問題はどうやって$\alpha$を求めるかということですが、processingには便利な関数が用意されています。
それはatan2関数です。これは$\tan$の逆関数で、aとbを代入することでαの値を求めることができます。
お待ちかねの全プログラム公開!
processingで書いたコードですので、ご自身のパソコンにprocessingをインストールして、お試しください。
コードに関しては「動けばいいやん」という精神で記述しているので、見にくいところもあると思いますが、お許し下さい。
ここの箇所はご自身の環境に合わせて調節して見て下さい。