新 3D クラス開発日記(12) ~ 頂点を使った 3D 表現<4> type="sphere" ~
2007/02/13 22:53 - AS3.0
sphere は pivot の特殊形とでも言うべきものでしょうか。
pivot が軌道上に表示オブジェクトを貼りつけたイメージなら、sphere は球面上に表示オブジェクトを貼りつけたイメージです。
これも pivot 同様、VertexTransform 用に、第 3 引数 info が必要で、フォーマットは以下のとおりになります。

dist は頂点座標を計算する際に用いた「距離」の値をそのまま使います。
「距離」とは何ぞや、という問いに対して、まず XY 平面上に環状配置の頂点座標値計算から始めると話が分かりやすいと思いますので、そちらから説明します。
原点 O ( 0 , 0 ) を中心とする単位円(半径が 1 の円)の円周上に点 P があるとします。
P と O を結んだ線分 PO とX 軸が成す角度がθだとします。θはX 軸の正の側から反時計回りをした角度です。
そうすると、この点 P の座標値は( cosθ , sinθ ) となります。
数学の Y 軸は上が+、下が-であるのに対して、Flash、というかコンピュータが扱う Y 軸は、上が-、下が+と逆になっています。 なので、Flash の実際の計算値は上図と上下逆になります。
今までに配布したサンプルコードでは以下のように記述しています。
DIST = 75; for ( i=0; i<8; i++ ) { var degree:Number = ( 360 / 8 ) * i; var cos:Number = Math.cos( AqMath.d2r( degree ) ) * DIST; var sin:Number = Math.sin( AqMath.d2r( degree ) ) * DIST; vector_array[i] = new Vector( cos , sin , 0 ); } coordinate_ring.txt より AqMath.d2r は角度からラジアンを求めるカスタムメソッドです。
まぁ、この辺りは flash.geom.Point.polar を使った極座標→直交点座標変換を使うともっと簡単になりそうな気がしますが、それは次への課題ってことで。
で、この単位円の座標に乗算している DIST は円の半径ですが、3D 上では Z 座標の最大値と最小値の絶対値と見なすこともできます(上図の縦軸を Z 座標と見なすと理解しやすいと思います)。 この 3D クラスにおいては、そういう性格を持つこの変数を Z 座標の「距離」の基準として扱っています。
球面上の座標計算も原理は同じです。実際のコードでは以下のように記述しています。
var DIST:uint = 75;
var vNum:int = 7; // 垂直軸上のポイント数
var hNum:int = 8; // 水平軸上のポイント数
for ( var v:int=0,i:int=0; v<vNum ; v++ ) {
for ( var h:int=0; h<hNum ; h++,i++ ) {
var vD:Number = 180 / ( vNum + 1 ) * ( v + 1 ) - 90;
var hD:Number = ( 360 / hNum ) * h;
var px:Number = DIST * Math.cos( AqMath.d2r( hD ) )
* Math.cos( AqMath.d2r( vD ) );
var py:Number = DIST * Math.sin( AqMath.d2r( vD ) );
var pz:Number = DIST * Math.sin( AqMath.d2r( hD ) )
* Math.cos( AqMath.d2r( vD ) );
vector_array[i] = new Vector( px , py , pz );
}
}
sphere.fla の第 1 フレームより
このように、単位球の座標に DIST を乗算していますが、円の場合と同様、球でも Z 座標の最大値と最小値の絶対値になります。
type="sphere" を指定した場合、VertexTransform で、この値を scaleX の変動計算に使っています。
ソース( sphere.zip 17.8 KB )
点を使った 3D 表現の話はここまで。
次回からは面を使った 3D 表現の話になります。
まずは面を扱うクラスをまとめたパッケージ Aq3D.skin から。