物理エンジンと遺伝的アルゴリズムを使ってなんかする、という動画たち
が面白かったので、俺もそういうのをやってみたい、と思った。
WEB上で動かせるといいので、JavaScriptで動く物理エンジンを探してみたところ、Physijsというものがあった。
これはThree.jsというJavaScript用の3D描画エンジンのプラグインになっているので、3D表示が統合されていて便利。
物理計算はammo.jsという、C++で書かれたBullet Physicsという物理エンジンをEmscriptenでJavaScriptにコンバートしたものを使っている。
そこそこ動いてよかったんだけど、剛体間に角度バネみたいな拘束をさせたくて、剛体にapplyForce()
をしてみたところ物体が消えてしまい、原因や解決方法がよくわからなかった。
しかたがないので一旦基本に戻って、C++でやってみることにした。 使う物理エンジンはBullet Physicsじゃなくて、導入の簡単さからOpen Dynamics Engineで試してみた。 ODEは使う浮動小数点数型をSINGLE(float)かDOUBLEを選べるんだけど、ちょっと試したところSINGLEだと計算エラーが発生しやすい感じだったので、configure時に–enable-double-precisionをつけてやったほうがよさそう。 それでも頻繁に計算エラーや発散が発生するので、実際のアプリでの利用は大丈夫なのか心配。
で角度バネをどうやって実装しようかとぐぐったところ、ODEのジョイント(拘束)は固いバネ+ダンパーのような仕組みでできているので、うまくパラメータを設定するとそのようなことが実現できるらしい(Problems, Solutions, and Ideas: Implicit springs in the Open Dynamics Engine (ODE))。 でジョイントは角度などの最小値と最大値を設定できるので、両方共に同じ値を設定してやれば希望の角度にダンパー付きバネで収束してくれる。
dReal angle1 = M_PI / 2, angle2 = M_PI / 2; |
ということで、複数の剛体をユニバーサルジョイント(2軸回転)でつないで、角度バネを設定して、へびっぽい物体を作ってみた。
今後は遺伝的アルゴリズムというのを試してみたい。