この記事はJulia Advent Calendar 2018の15日目の記事です。 また、ここ数年チャレンジしている@kjunichiのパーソナルアドベントカレンダーの15日目の記事も兼ねてます。
背景
JuliaにはSpecialFunctionsパッケージにゼータ関数が用意されている。 これを使ってJuliaはllvmを吐けるから、WASMにして、ブラウザに描画させたらは高速な描画が 期待できるのでは?
と思いやってみたが、llvmの吐き出し方が分からず挫折したw。
でも、PyPlotのようにPythonに頼らずも、Juliaで直接3Dのグラフを描画するくらいなら なんとかなるかもと始めた。
JuliaからJupyterに直接3Dグラフを描画する
原理
juliaからjupyterにhtmlを出力できる命令がある。
以下のようにdisplay関数を使うことで、Jupyterのノートブックに直接HTMLやJavaScriptを埋め込める。
これを使って、JuliaからJupyterのブラウザ側に様々なデータを送ることが出来る。
display("text/html", """ <h1>hoge</h1> """)
PyPlotなどがJupyterに描画しているのもこの仕組みをつかってる模様。
Juliaで虚数を扱うには
im
で虚数単位のを表すことができる。
3D描画
WebGLを生で扱うと長くなりがちなので、Three.jsを利用した。
また、Jupyterのブラウザ側にJsのライブラリを管理する目的でRequireJSが利用されているようだったので、 この流儀に従い、Three.jsを組み込んだ。
頂点データの渡し方
ブラウザ(Three.js)側で処理しやすいだろうということで、Julia側でJSONにして渡すことにした。
Pkg.add("JSON") using JSON zdata=JSON.json(z);
あとはThree.jsで頂点のデータをいい感じにポリゴンにして描画すればOK
$zdataにJavaScript実行時には先ほどのJulia側で作成したJSONが展開される。
const data = $zdata const geometry = new THREE.PlaneBufferGeometry(10, 10, xsize-1, ysize-1); const plane = new THREE.Mesh(geometry, material); scene.add(plane); const vertices = geometry.attributes.position.array; for (let y = 0; y < ysize; y++) { for (let x = 0; x < xsize; x++) { vertices[3 * ((xsize) * y + x) + 2] = data[y][x] } } geometry.computeFaceNormals(); geometry.computeVertexNormals();
取り組んで得た知見
実行結果
成果物
マインクラフト(MCPI)編
これまではJupyterへ描画する話でしたが、今度は、マインクラフトを描画先にしてみます。
以降はRaspberry PiでJuliaを動かして Raspberry Piで動くマイクラにゼータ関数を描画します。 (イマイチ話のつながりがありませんが、親子で今年の後半はマイクラ三昧だったので許してくださいw)
マイクラ(MCPI)用に陰関数のプロットツール
実は以前の記事
でPythonでマイクラ(MCPI)用に陰関数のプロットツールを作っていたので、 これを今回のアドベントカレンダーの記事用にプロット範囲を複素平面にしてJuliaで実装し直したのでした。
実行結果
成果物
あとがき
マイクラはWindows10版をターゲットに進めたのですが、Juliaで使えるWebSocketのライブラリだと、 マイクラとうまくWebSocketが繋がらず、途方に暮れていたのですが、Juliaのバージョン1.0.0以降はArmにも 対応しているのを公式で見かけ、幸運なことにRaspberry Pi用のマインクラフト向けのパッケージまで 用意されていたので、なんとか進めることができました。
参考資料
関連記事
Raspberry Piつながり
- Raspberry Pi 3が届いた!
- 2018年春版Raspberry Pi 3の3.5mmジャックからAlexaを出した
- Raspberry Pi3でTensorflowをビルドして動かした
- Raspberry Piの温度をgRPCを使ってElectronで作ったデスクトップマスコットに表示させた