説明およびサンプルコード 1
個別説明
以降では、このプログラムを部分ごとに区切って説明します。完全なプログラムリストについては、リスト15を参照してください。
プログラムの本体に取り掛かる前に、プログラムの本体を通じて呼び出されるいくつかのユーティリティメソッドについて個別に説明します。最初に説明するユーティリティメソッドはtranslateメソッドです。リスト1は、このメソッド全体を示しています。
translateメソッド
これは、特定のノードとそのすべての子を平行移動するTransformGroupオブジェクトを作成する必要がある場合に、プログラム本体から呼び出されるメソッドです。
//Given an incoming node object and a vector object, // this method will return a transform group designed // to translate that node according to that vector. TransformGroup translate(Node node,Vector3f vector){ Transform3D transform3D = new Transform3D(); transform3D.setTranslation(vector); TransformGroup transformGroup = new TransformGroup(); transformGroup.setTransform(transform3D); transformGroup.addChild(node); return transformGroup; }//end translate
Node型のパラメータ
このメソッドは、2つの入力パラメータを受け取ります。最初のパラメータは、Node型オブジェクトへの参照です。すでに学習したように、Nodeは、LeafとGroupのスーパークラスです。したがって、最初のパラメータは、ColorCubeなどの可視オブジェクト、または別のTransformGroupオブジェクトへの参照です。
Vector3f型のパラメータ
2番目のパラメータは、Vector3f型オブジェクトへの参照です。このオブジェクトは、x、y、zの各軸に沿った目的の平行移動距離を表す、float型の3つの数値をカプセル化します。
メソッドの目的
メソッドの目的は、ノードとそのすべての子(後でグループに追加される可能性がある他の子も含む)を、ベクトルにカプセル化された距離に応じて平行移動させるTransformGroupオブジェクトを作成し、返すことです。
新しいTransformGroupオブジェクト
このメソッドは、最初に新しいTransform3Dオブジェクトを作成し、そのtranslationプロパティを、平行移動距離を含むベクトルオブジェクトに設定します。次に、新しいTransformGroupオブジェクトを作成し、そのtransformプロパティを、新しいTransform3Dオブジェクトに設定します。
2つの代替のプログラミング手法
最初のパラメータを削除し、この時点で新しいTransformGroupメソッドを単に返すという方法もあります。このようにプログラミングすると、メソッドを呼び出したコードが、ノードを子としてTransformGroupに即時に追加します。
しかし、私は、そのステップをメソッドに組み込むことを選択しました。入力ノードオブジェクトは子として新しいTransformGroupオブジェクトに追加され(addChildメソッドを呼び出すことにより)、ノードがすでに子として追加されたTransformGroupオブジェクトが返されます。
scaleメソッド
これは、特定のノードとそのすべての子を拡大縮小するTransformGroupオブジェクトを作成する必要がある場合に、プログラム本体から呼び出されるメソッドです。
//Given an incoming node object and a vector object, // this method will return a transform group designed // to scale that node according to that vector. TransformGroup scale(Node node,Vector3d vector){ Transform3D transform3D = new Transform3D(); transform3D.setScale(vector); TransformGroup transformGroup = new TransformGroup(); transformGroup.setTransform(transform3D); transformGroup.addChild(node); return transformGroup; }//end scale
上記のtranslateメソッドの場合と同様、このメソッドもNodeパラメータとVector3fパラメータを受け取ります。この場合の目的は、特定のノードとそのすべての子に加えて、グループに子として追加される可能性がある他の子についても拡大縮小を行うTransformGroupオブジェクトを作成し、返すことです。
このメソッドのコードは、translateメソッドのコードとほぼ同じです。ただし、translateメソッドが、新しいTransform3DオブジェクトでsetTranslationメソッドを呼び出してそのtransformプロパティを設定するのに対して、scaleメソッドは新しいTarnsform3DオブジェクトでsetScaleメソッドを呼び出してそのscaleプロパティを設定します。
tiltTheAxesメソッド
このメソッドの目的は、特定のノードの子孫であるすべてのLeafオブジェクト(および、後でTransformGroupオブジェクトの子として追加される可能性がある他のノードの子孫であるすべてのLeafオブジェクト)を、x、y、zの各軸を中心に回転させるTransformGroupオブジェクトを作成し、返すことです。
このメソッドは、1つの変数の名前が異なることを除けば、「Combining Rotation and Translation in Java 3d」(稿末の「参考資料」を参照)というレッスンで説明した、同じ名前のメソッドと同一です。そのため、このレッスンでその説明を繰り返すことはしません。
displayMatrixメソッド
このメソッドは、Transform3Dオブジェクトへの参照である入力パラメータを受け取り、そのTransform3Dオブジェクトに含まれる4x4行列の内容を表示します。
void displayMatrix(Transform3D transform){ //Retrieve the contents of the matrix into an array. // The first four elements of the array contain the // first row of the matrix, etc. double[] matrixData = new double[16]; transform.get(matrixData); for(int outCnt = 0;outCnt < 16;outCnt += 4){ for(int cnt = 0;cnt < 4;cnt++){ System.out.printf( "%6.2f ",matrixData[cnt + outCnt]); }//end inner loop System.out.println(); }//end outer loop }//end displayMatrix
このメソッドのコードは非常に単純です。リスト3のコメントを読めば大体の内容はわかるでしょう。
getAxesGroupメソッド
これは、3本の直交軸のように見えるセットから成るTransformGroupオブジェクトを作成し、返す便利なメソッドです(図12の左下のイメージの右上の部分を参照)。3本の個々の軸は、細長いColorCubeオブジェクトでそれぞれ作成されています。
TransformGroup getAxesGroup(){
ColorCube xAxis = new ColorCube();
//Scale the ColorCube to make it long and skinny
// in the x dimension.
TransformGroup xGroup = ''scale''(
xAxis,
new Vector3d(0.25,0.01,0.01));
ColorCube yAxis = new ColorCube();
TransformGroup yGroup = ''scale''(
yAxis,
new Vector3d(0.01,0.25,0.01));
ColorCube zAxis = new ColorCube();
TransformGroup zGroup = ''scale''(
zAxis,
new Vector3d(0.01,0.01,0.25));
TransformGroup axesGroup = new TransformGroup();
axesGroup.addChild(xGroup);
axesGroup.addChild(yGroup);
axesGroup.addChild(zGroup);
return axesGroup;
}//end getAxesGroup
このメソッドのコードは単純であり、埋め込まれているコメント以上の説明は必要ないでしょう。
