gombeのブログ

マイコンの電子工作系PIC32/KiCad/C/C++/3D/

アルゴリズムを可視化したいときの描画エンジンの話

アルゴリズムを解く最中に何かアニメーションしたりして可視化したい時がありますね。 そんなとき、どんな方法で可視化するのがいいのか悩むことがあります。

ざっと手法をいくつか比較してみます。

printfで頑張る

ログも追えていいと思います。 ただ、どのように動いたのかわかりにくいことがあります。 テキストベースであるには限界があります。

GUI

グラフィックベースで描画するとき、2Dのエンジンの中でどんなものがいいか、スタイルに合わせた選び方が重要だと思います。

イベントドリブンな描画

描画ルーチンをdrawの中で分けて書く方法です。これは、向いているものと向いていないものがあると思います。 アニメーションを意識して分けながら実装できるか、そうでないかで変わると思います。

ルービックキューブを解く過程で、解法をメモリに入れて最後にアニメーションするような場合はイベントドリブンでも問題にはなりません。 しかし、実際に解きながらアニメーションする場合はかなり複雑になってしまいます。 具体的には、アルゴリズムの進行をアニメーションに同期するような処理が複雑になります。 この場合は、マルチスレッドにしてアルゴリズムの処理と描画を通信することも考えられますが、複雑になりすぎてしまいます。

  • SDL2などパッシブな描画エンジン

ドローをこちらで制御できるメリットとして描画のタイミングをこちらで制御できます。 たとえば、move関数にアニメーションを追加しておけば、アニメーション後にコールから復帰してその後の処理をしてまたアニメーションに入るみたいなことが簡単にできます。

SDL2のメリットとして、描画が非常に高速です。ゲームエンジンが目的なので、30x30の900タイルを全更新しながらループを回しても処理が全然追いつきます。 これは、GPUによるアクセラレートの力が強いです。20%くらいのGPU使用率で100fpsの滑らかなアニメーションができます(笑)

(さらに本気出せば、GPUのドローコールを減らすために大き目なテクスチャからUV頂点を切り出して2D描画すればおそらくもっと高速に全体描画できると思います。ただ、そこまでする必要があるかは、、わかりません。)

f:id:electgombe:20200628170114p:plain
描画のプログラミングの方式の違い

パッシブな方式には、SDL2などのローレベルなもの以外にも、プロットに適したGNUplotやmatplotlibなど様々なツールがあります。 最近では高速な描画が可能なものが増えてきているようで、アニメーションもできるものがあるそうです。 様々なツールを、その場のニーズに応じて使えればいいと思います。

Processingなどのイベントコールでの描画

コールルーティン内で描画だけを分けて書く方式です。webやprocessingなどはこの方式で、広く使われています。 ただ、プログラムの再設計が必要になることが多く、すでに組んだプログラムへ手軽に描画を追加というわけにはいかなそうです。 最初はprocessingで実装しようと思ったのですが、移植が大変そうなのでやめました。