3Dカッチンアプレット

作ろうとしていたものが何となくそれらしく動き出したので、一旦ここに貼っておく。
3Dカッチンアプレットのページへのリンク
ソースコード

一応、衝突したら弾き合うのだが、わかりづらい。どうしたらわかり易くなるのだろう。
衝突したら赤く光るチェックボックスを付けてみたが、やはりわかりづらい。
3Dだと仕方ないのだろうか。


動的に球を増やせるようにしようとしたのだが、3D処理開始後にシーングラフにノードを追加しようとすると、
javax.media.j3d.RestrictedAccessException: Group: only a BranchGroup node may be added
という例外が出てしまい、これに対応しようとするとシーングラフの構造に大改造が入るので、今回は諦めた。

これの作成途中のJava3DのテストアプリではSwingを使っていたが、よく考えるとSwingを使う意味が特に無いので、AWTに書き直した。
また、球の座標として極座標形式の3つの回転角(ロール、ピッチ、ヨー)を持ち、球をローカル座標系のXY平面で(つまりZ軸で)回転させて、各球のローカル座標系をX軸、Y軸で回転させることにより球を3次元的に回転させていたが、それだと球の衝突計算の式にsinやcosが数十個出てくる恐ろしいことになることがわかったので、ローカル座標系の回転はせず、各球に普通の(直交座標の)x,y,zの座標と回転情報を持たせて、x,y,zを地道に動かしていくように変えた。
その回転行列の作り方、衝突時の回転行列の変え方で悩んでたのだが、3Dプログラミングの情報を探してるとよく目にするクォータニオン(Quaternion)というものにヒントを得て、回転行列は使わず、座標も回転情報も全てクォータニオンに統一して計算している。

色々な所に、クォータニオンを使うと3次元上の回転が扱いやすくなる、と書かれており、3次元回転以外のクォータニオンの使い道はほとんど目にしないのだが、使い道は回転行列と大差ないと思う。計算量が減ることと、回転行列だと再構成時にsinやcosの符号を考慮する必要が生じたりするのが避けられるというメリットがあり有用なのだが、幾何学的(数学的)には、回転行列が回転角3つ、クォータニオンが回転軸+回転角1つという違いくらいで、知らなくて済むことというのはあまり無さそうである。
今回のコーディングでも、外積取って内積取って…とやっていると、クォータニオンを使っても回転行列を使ってもやることは変わらないように感じた。Java3Dにも行列演算のライブラリが充実しているので、回転行列を使っても似たようなコードになりそうだと思うのだが、理解不足だろうか。

Quaternion参考リンク
四元数で回転 入門
Java3D vecmath package
 多くのリンクあり、「vecmath を理解するための数学(PDF) 」は読みやすい
Vector-Complex-Quaternion
 『ベクトル・複素数・クォータニオン』 (PDF)は大変詳しく書かれている