ポリゴンできれいな球を作るのは難しい

ポリゴンで球を作ろうとすると、真っ先に考えるのは、地球儀の緯度・経度のように2つの角度で球面上の点を表す極座標モデルであろう。しかし、それだと、赤道の辺りのメッシュが荒く、極点の辺りが細かくなり、球面が均一にならない。何とか、なるべく均等な面積のポリゴン片で球を作れないものか…と考えてみた所、次のような方法を思いついた。

球面上の3点からなる三角形の各辺の中点を取り、それらの間を結んで、三角形を4等分する。そのまま、前述の中点を球面に張り付かせるように動かす。

上から、元の三角形、4等分して球面に張り付かせた4つの三角形、そのポリゴンに色をつけたものである。合同な三角形から成る正八面体から始めて、これを繰り返していけば、均一な球面ができるのではないか?と期待して、やってみた。

テストアプリ(Java3D)の起動ページへ
ソースコード
画面サンプル

右から反時計回りに、8, 32, 128, 512, 2048, 8192個の三角形ポリゴンからなる球であり、手前が線で表示したもの、奥が面で表示したものである。

うまくできているようにも見えるが、細かくしても正八面体の面影が残っている。よく見ると、元々頂点だった所が密で、面の中心だった所が疎であり、くっきりと境目がある。これは、上記の方法で三角形を4等分して各頂点を球面に張り付ける時に、真ん中の三角形の面積が他の3つより大きくなるのが原因である。このことは、三角形の辺の中点が球面から遠い、赤道に近い位置の大きな三角形で考えてみるとわかりやすい。
正八面体に代えて正四面体で始めてみると、その影響が顕著になる。

テストアプリ(Java3D)の起動ページへ
ソースコード
画面サンプル

こうなると、却って緯線・経線の四角形ポリゴンで作る球の方が自然に見えてしまう。

テストアプリ(Java3D)の起動ページへ
ソースコード
画面サンプル

何かいい方法がありそうな気がするのだが…


なお、javax.media.j3d.Shape3Dで作るポリゴンには表裏があり、通常は「カリング」(culling、計算量削減のための間引き)のため、線表示であっても表しか表示されない。ポリゴンを成す頂点を並べていった時に、前後の頂点が成す外積が正の方向の面(右手の法則、右ねじの法則が指す方向の面)が表である。当てずっぽうにポリゴンを作る時は注意が必要である。
カリングを無効にするには、PolygonAttributesクラスのインスタンスにCULL_NONEを設定する。

また、光源を使って光を反射させる場合は、ポリゴンに法線ベクトルを設定しておかないと、やはり何も表示されないので、要注意である。