ねこでじ(Nekodigi)

Nekodigi’s diary

学習中の気づきをまとめています。応援よろしくお願いします

【Processing】薄明光線を再現する。

成果物

www.youtube.com
散歩をしていると、薄明光線を見つけたので、Processingでできないかと思って実装してみました。

仕組み

BlendModeをAddに変更したうえで、Perlinノイズで線の透明度を変化させるとこのようになります。
今回のアルゴリズムは、Wikipediaの画像を参考にして考えました。
薄明光線 - Wikipedia

コード

gist.github.com

【Processing】線を描画するアルゴリズム

成果物

f:id:Nekodigi:20200624200629p:plain
線状にサンプリングする時に、自力で計算しないといけないと思って作ってみました。ただ、コンピューターで線を引くには少し工夫が必要です。今までやったことがなかったのでやってみました。

仕組み

始点と終点の差計算しておき、xの位置に応じてyを計算するという仕組みです。ただ、この方法は非効率なので、別の方法も存在しています。
Line drawing algorithm - Wikipedia

コード

gist.github.com

【Processing】Perlinノイズ、Perlinノイズの渦、勾配、を使って画像を変形させる。

成果物

前回、Perlinノイズの勾配を使ってPerlinノイズの渦を作りました。この渦には一か所に集中しないという特性があり、このことが画像変形に役立つのではないと思って作ってみました。試していくと、他のベクトル場でも画像変形出来たので、紹介していきます。

Perlinノイズ

www.youtube.com
Perlinノイズをベクトルの角度としてベクトルを求め、そのベクトル場にそって画像のサンプルをとる位置をずらすとこのようになります。Perticleを使ってベクトル場の様子を観察するとわかる通り、つままれたような変形の仕方をします。

Perlinノイズの勾配

www.youtube.com
このベクトル場は一点に集中するような形になっているのが特徴です。上手くいくか不安だったのですが、このベクトル場の特性が見事に拡大、縮小の効果となって表れています。

Perlinノイズの渦

www.youtube.com
このベクトル場は、特定の箇所に集中せず、ぐるぐると同じ軌道を回り続けるようになっているのが特徴です。画像でもねじれが見事に表れています。

仕組み

画像の補完を行うために、毎度恒例となりつつあるBicubic補完を利用しています。詳しくはこちらをご覧ください。
nekodigi.hatenablog.com
画面上の位置を画像上の位置に対応させればよいので、画面上の位置から出発して、ベクトル場にそって数回に分けて移動させたあとに、map()関数を使って、画面上の位置と画像上の位置を対応させています。

コード

Image_Perlin*という名前で追加しています。
github.com

【Processing】Perlinノイズの勾配を90°回転させて、渦のパターンを作る

成果物

固定版

www.youtube.com
Perlinノイズの勾配を前回作ったのですが、これを90°回せば、同じ軌道をずっと回り続けるのではないかということでやってみました。

変動版

www.youtube.com
Perlinノイズを入力として与えるので、そのままのパラメーターが使用できます。

仕組み

Perlinノイズの勾配のコードなどはこちらの記事を参考にしてください。
nekodigi.hatenablog.com
今回のコードは、得られた勾配ベクトルを、そのまま90°回転させたものです。

コード

Perlin Vortex with Gradientといいう名前で追加しています。
github.com

【Processing】Midiデータを再生して、押されているキーを表示する。

成果物

www.youtube.com
ProcessingでどうやってMidiファイルを扱うのかが長年の謎だったのですが、標準ライブラリを使ってMidiデータが扱えることがわかりました。再生速度などをいちいち考慮しないといけないと思っていたのですが、Sequencerを使って簡単に再生出来ることが分かったので、一旦投稿します。機能を盛り込もうかと思いましたが、既出のネタだったので、分かりやすさ重視でコンパクトに収めておきます。

仕組み

今回のプログラムは、こちらのプログラムの最重要部分を抽出したものです。詳細を知りたい方はこちらをご覧ください。
github.com
まず。Sequencerを作成し、
Sequencer sequencer = MidiSystem.getSequencer();
midiFileを指定します。
sequencer.setSequence(MidiSystem.getSequence(midiFile));
Sequencerをアクセス可能にします。
sequencer.open();
どのキーが押されたか取得するために独自でReceiverを拡張したクラスを作成します。そして、Transmitterを使って、Receiverに転送します。
Receiver receiver = new myListener();
Transmitter transmitter = sequencer.getTransmitter();
transmitter.setReceiver(receiver);
あとは、再生するだけです。
sequencer.start();
曲が終わったあとは、stop() close()を行う必要があります。詳しくはコードをご覧ください。

コード

Simple_Midi_File_Testという名前で追加しています。
github.com
Public Domainですが、一応音源のリンクを張っておきます。
Music Listing - without preview images

【Processing】L Systemで空間充填曲線などを描く(Hilbert,Peano,Dragon,Levy,Gosper)

成果物

Peano曲線がL-Systemを使って描けることが分かったので、調べてみると非常に多くの空間充填曲線があることが分かったので実装してみました。今回は、線に色を付けることで、描画方法の特徴がわかるようにしました。単位正方形全体を含む曲線を空間充填曲線というようなのですが、今回は、隙間なく並んでいる曲線なども含めて紹介していきます。
空間充填曲線 - Wikipedia

Hilbert Curve

www.youtube.com
Blenderレンダリングでも使われている、有名な空間充填曲線です。

Peano Curve

www.youtube.com
Hilbertが使われることが多いですが、Peano曲線も有名な空間充填曲線の一つです。

Triangle Fractal

www.youtube.com
L-Systemで空間を埋める三角形のフラクタルが書けるようです。私が昔作った三角形のフラクタルとは違いますが、こちらも綺麗です。

Dragon Curve

www.youtube.com
複雑な図形ができるですが、実はタイルのように並べることが可能です。

Quadratic Gosper

www.youtube.com
Hilbert曲線などと同じく、正方形になりますが、かなり複雑な形状をしています。

Hexagonal Gosper

www.youtube.com
先ほどの六角形バージョンです、回転するように成長するのが特徴です。

Levy Curve(おまけ)

www.youtube.com
おまけとして、スカスカのフラクタルも紹介しておきます。こちらのフラクタルも色々なところで使われています。

仕組み

L-Systemのルールを以下のように変更すると、空間充填曲線を描くことができます。線の長さは、それぞれ違った調整を行わなければなりません。どんな数で割ればいいのか、generate(x)というように例を示しておきますが、詳しくはソースコードを参照してください。
L-Systemのルールはこちらのサイトを参考にしています。
L-System manual

Hilbert Curve

axiom = X
X -> -YF+XFX+FY-
Y -> +XF-YFY-FX+
angle = 90
generate(1);
generate((1.*2+1)/1);
generate((3.*2+1)/3);

Peano Curve

axiom = X
X -> XFYFX+F+YFXFY-F-XFYFX
Y -> YFXFY-F-XFYFX+F+YFXFY
angle = 90
generate(2);
generate((2*3+2)/2.);
generate((8*3+2)/8.);

Triangle Fractal

axiom = F+F+F
F -> F-F+F
angle = 120
generate(1);
generate(1.7);(不明)

Dragon Curve

axiom = FX
X -> X+YF+
Y -> -FX-Y
angle = 90
generate(1);
generate(1.43);(不明)

Quadratic Gosper

axiom = -YF
X -> XFX-YF-YF+FX+FX-YF-YFFX+YF+FXFXYF-FX+YF+FXFX+YF-FXYF-YF-FX+FX+YFYF-
Y -> +FXFX-YF-YF+FX+FXYF+FX-YFYF-FX-YF+FXYFYF-FX-YFFX+FX+YF-YF-FX+FX+YFY
angle = 90
generate(5);
generate(5);

Hexagonal Gosper

axiom = XF
X -> X+YF++YF-FX--FXFX-YF+
Y -> -FX+YFYF++YF+FX--FX-Y
angle = 60
generate(2.8);
generate(2.8);(不明)

Levy Curve(おまけ)

axiom = F
F -> -F++F-
angle = 45
generate(1.43);
generate(1.43);(不明)

コード

L-System*という名前で追加しています。
github.com

【Processing】プリズムの分光

成果物

f:id:Nekodigi:20200620222346p:plain
どうして分光できるのかと思って調べてみたら、波長によって屈折率が変わるということがわかりました。狙った波長のデータが見つからなかったので、残念ながら物理的に正確なシュミレーションは出来ませんでしたが、近い見た目のものができました。

仕組み

波長によって屈折率が変わるということを再現するために、光線自体に屈折率情報を持たせておき、それを使ってスネルの法則で屈折の計算を行っています。
Snell's law - Wikipedia
狙った波長ではなかったので今回は使いませんでしたが、屈折率と波長の関係のデータはこちらから取得することができます。
https://www.global-optosigma.com/jp/category/opt_d/opt_d01.html

コード

RayCast_Prismという名前で追加しています。
github.com

【Processing】フィボナッチ数列でらせんを描く

成果物

www.youtube.com
今回はフィボナッチ数列の辺の長さの正方形を敷き詰め、円弧でつなげてみました。

仕組み

フィボナッチ数列は、1,1,2,3,5,8,13,21というようになっている数列です。どう並べるか悩んだのですが、素直に動かす方向ごとに、処理を変えることで対応しています。
Fibonacci number - Wikipedia

コード

Fibonacci Numberという名前で追加しています。
GitHub - Nekodigi/Math: Time estimate and more

【Processing】Sobel Operatorを実装する。

成果物

f:id:Nekodigi:20200620100951p:plain:w200f:id:Nekodigi:20200620101030p:plain:w200
Sobel Operatorを実行すると、この様に輪郭が検出できます。予め決まった行列を掛け合わせるだけのシンプルな仕組みです。

仕組み

水平方向と垂直方向の輪郭に反応する行列を畳み込み演算し、それぞれの結果を二乗して足し合わせ平方根を求めると、Sobel Operatorが実現できます。
f:id:Nekodigi:20200620101011p:plain:w200f:id:Nekodigi:20200620101008p:plain:w200
数式等が貼り付けられなかったので、こちらのサイトを参照してください。
Sobel operator - Wikipedia
【画像処理】ソーベルフィルタの原理・特徴・計算式 | 西住工房

コード

Image Sobel Filterという名前で追加しています。
github.com

【Processing】Gaussian Blurを実装する

成果物

f:id:Nekodigi:20200619221504p:plain
今までGaussian Blurを実装しようと思ったことはあってもやっていなかったので、やってみました。FFTを使って高速で実行する方法もあるらしいのですが、今は遠慮しておきます。

仕組み

ある点からの距離結果が変わるように拡張したガウス関数を使ってフィルタになる行列を作ります。そのフィルタを使って、全ピクセルにフィルタをかけるとGaussian Blurを行うことができます。境界の処理ではConstrain関数を使って有効範囲に制限しています。
ガウシアンぼかし - Wikipedia

コード

Image Gaussian Blurという名前で追加しています。
github.com

【Processing】破壊可能なばねを作る

成果物

www.youtube.com
橋を作るゲームを見て、壊れる動作が、どうやったら再現できるのか気になったので、破壊可能なばねを作ってみました。

仕組み

物体が壊れるのは力がかかった時というイメージがありますが、力を計算するのは難しいです。ただ、物体は力がかかった時伸び縮みするので、伸び縮みを観測し、それをもとに物体を破壊すれば力を計算しなくて済むという仕組みになっています。

コード

Destructible Springという名前で追加しています。
github.com

【Processing】針を落として円周率を計算する。

成果物

www.youtube.com
アイヨシキさんに、視覚化したらきれいな数学の問題はありますかと聞いたらビュンフォンの針を紹介していただいたので、さっそく実装してみました。ただ、精度が悪いのが難点です。

仕組み

感覚dの平行線を書き、長さがd/2の針を落とすと、平行線と交差する確率が\dfrac{1}{\pi}になります。針を落とす動作は、平行線内のランダムな位置に、ランダムな角度で置くことで実現できます。
mathtrain.jp

コード

Buffons Needleという名前で追加しています。
github.com

【Processing】Taylor展開とマクローリン展開を実装する。

成果物

www.youtube.com
アイヨシキさんがTaylor展開を作ろうとしていたのを見て、お蔵入りになっていたマクローリン展開を思い出しました。お蔵入りになっていたマクローリン展開をちょっと改良すればTaylor展開を作れるのでは、ということで作ってみることにしました。

仕組み

 \begin{array}{l}
Taylor展開の良い所は、a点でのf( a) を調べるだけで、\\
周りを知ることができることにあります。\\
f( x) =\sum ^{\infty }_{n=0}\frac{f^{( n)}( a)}{n!}( x-a)^{n}\\
また\frac{f^{( n)}( a)}{n!} はxが含まれないので定数項として先に計算しておけます。\\
a=0でのテイラー展開を特別に、マクローリン展開と言います。\\
f( x) =\sum ^{\infty }_{n=0}\frac{f^{( n)}( 0)}{n!} x^{n}
\end{array}

コード

Taylor series Formulaという名前で追加しています。
github.com

【Processing】Differential Growthを実装する

成果物

www.youtube.com
HoudiniでRelaxノードというものを使って、Differential Growthを実装するTutorialを見たのですが、Processingでも簡単に出来そうなのに一度も実装したことがなかったので、さっそく実装してみました。

仕組み

Relaxは頂点をある大きさの円だと見なして、ぶつからないように移動させるというものです。
Relaxを行い、点と点の距離が一定になるようにResampleし、繰り返すとDifferential Growthが出来ます。Relaxノードはぶつかった円の法線方向にずらすだけでいいのですが。Resampleがなかなか大変でした。等間隔にサンプリングしていくと、最後に少し余りが発生してしまいます。このままだと、毎回終点の周りがスカスカになってしまいます。そこで、始めからと終わりから交互にResampleするとうまくいくはずです。ですが、普通のResampleをちょっと工夫をするとうまく動いてしまいまったので、そちらを採用しました。
今回は辺にSmoothをかけていないせいか、点が交差し始め発散してしまったので、Resampleをした時に離れすぎ内容に調整する処理を挟みました。

コード

Line Differential Growthという名前で追加しています。
github.com

【Processing】パーリンノイズを使ってアゲートを作る

成果物

www.youtube.com
パーリンノイズを累算して何かアニメーションが作れないかなと思っていたら、Houdini TutorialでAgate Sectionというものが紹介されていたので、自分もアゲートを作ってみました。

仕組み

パーリンノイズを円状にサンプリングして、記録しておきます。その後、記録したデータを足し合わせ最終的なアゲートの半径を求めます。ただ、足し合わせながら表示すると大きい層に隠されるので、先に合計を求めてから引き算しています。
今回は見栄えのために周りを薄くしています。このサイトを見たところ、Agateは外側から成長するようなので、うまくいったらまた試してみたいです。
stonebuyer.exblog.jp

コード