2011年06月12日
球の描画1
球の描画は、主に2パターンの方法があると思う。
1. 地球儀のような、緯度と経度で割って描画する方法。
2. 正二十面体を、さらに割って描画する方法。
1 の方法は赤道付近でポリゴンが荒く、北極・南極に近づくと細かくなっていき効率が悪い。
ただ、プログラムで球を描くケースはゲーム画面内ではほとんどない。
単にデバッグ時に当たり描画用に出す程度ではないかと思う。
とりあえず、今回は地球儀のような方法で描画してみる。
以下ソースはJava ( JOGL 2.0 ) 。
まずトライアングルストリップで描ける中間部分を描画し、後で上下端をトライアングルファンで描画している。
三角関数がわかればそれほど難しくないと思う。
加法定理を使っているのは、何度も sin/cos を計算するコストを減らすため。
上下端を別に分けているが、頂点のリストを作って後で描画するのなら、まとめてやってしまった方が加法定理の計算部分うかせられる。
そもそも毎回計算して描かなくても、頂点のリストを1度作って、マトリックスで拡大縮小すれば済む話でもあるんだけど。
public void draw( Sphere shape, GL2 gl ) { final int div_h = 40; // 水平方向分割数 // 中間の帯の部分はトライアングルストリップで描ける // 加法定理によって、垂直方向のsin/cos値を更新する float rd = radius * accu_v_s; // 1個後の半径 float accu_s = sinTheta; // 水平方向sin // 加法定理によって、水平方向のsin/cos値を更新する // 上半球の描画 // 加法定理によって、水平方向のsin/cos値を更新する // 下半球の描画 // 加法定理によって、水平方向のsin/cos値を更新する ( 逆回転 ) |
で、上記ソースをコンパイルしてアプレットにしたものをここに置く。
分割数が多いのでそれなりに綺麗。
投稿者 Takenori : 01:49 | トラックバック
2011年06月17日
球の描画2
球の描画1に続き球の描画。
正二十面体を使う方法。
各頂点座標は以下で求める。
a = 1.0f / sqrt(5.0f) = 0.447213595 頂点座標は以下のようになる。 |
参考ページ
正二十面体(正20面体、Icosahedron)の頂点情報
これがわかれば二十面体を描画するのは簡単。
以下、前回に続き Java のソース。
public void draw( Sphere shape, GL2 gl ) { // { 0, 1, 2 }, { 0, 2, 3 }, { 0, 3, 4 }, { 0, 4, 5 }, { 0, 5, 1 }, // ファン, 上側 // ストリップで真ん中の帯を描く |
同じようにアプレットをここに。
制止していたら話からづらいのでカメラをくるくる回すようにした。
見てわかるけど、これでは球とははほど遠い。
球に近づけるには、各三角形のそれぞれの辺の中点を求め、三角形を4分割し、中点の頂点を正規化する。
これを必要なだけ繰り返し球を作る。
特に必要なかったので、このソースは書いていないが、頂点のインデックスを持った辺 ( Edge ) とトライアングルのクラスを作ってやれば、それほど難しくないと思う。
ただ、実際にゲーム等で表示するのなら、モデリングソフトで簡単に球が作れるので、そこからデータ取ってきてそれを表示した方が楽だし早い。
だから、あんまり使うことはないと思う。
投稿者 Takenori : 21:08 | トラックバック
カメラの回転1
中心位置のオブジェクトの周りをくるくる回る簡単なカメラ
簡単。
// 以下をメンバ変数に // 三角関数で毎回計算する
// 以下の処理をフレームごとに実行する。 |
ゲームなどで上下にカメラを振る場合はこれではダメで、上下に振るカメラ位置の横軸を中心に回転させる必要があるので、クォータニオンで回転させるのが手軽。