親子孫関係で回転する

3個の ColorCube を親子孫の関係で回転しながら描画します。

前田稔の超初心者のプログラム入門

プログラムの作成

  1. 2個の ColorCube を RotationInterpolator を使って、親子関係で回転しながら描画します。
    メモ帳などでタイプして Rot2.java の名前で保存して下さい。
    //★ 親子関係で回転する    前田 稔
    import java.awt.*;
    import javax.swing.*;
    import javax.media.j3d.*;
    import com.sun.j3d.utils.universe.*;
    import com.sun.j3d.utils.geometry.*;
    import com.sun.j3d.utils.geometry.ColorCube;
    import javax.vecmath.*;
    
    public class Rot2 extends JFrame
    {
        // main Method
        public static void main(String[] args)
        {   new Rot2();  }
    
        // Constructor
        public Rot2()
        {   // JFrame の初期化
            super("親子関係で回転");
            setSize(700,700);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            // Java3D 関係の設定
            GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
            Canvas3D canvas = new Canvas3D(config);
            add(canvas);
    
            // SimpleUniverseを生成
            SimpleUniverse universe = new SimpleUniverse(canvas);
            universe.getViewingPlatform().setNominalViewingTransform();
    
            // Scene を生成
            universe.addBranchGraph(CreateScene());
            setVisible(true);
        }
    
        // 親子の ColorCube を生成
        public BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
            BoundingSphere bounds = new BoundingSphere(new Point3d(),100.0);
    
            //※ 親の設定
            TransformGroup group1 = new TransformGroup();
            group1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
            objRoot.addChild(group1);
            group1.addChild(new ColorCube(0.2));
    
            // 親の回転
            Transform3D rotY = new Transform3D();
            Alpha alpha1 = new Alpha(-1, 8000);
            RotationInterpolator rotator =
                new RotationInterpolator(alpha1, group1, rotY, 0.0f, (float) Math.PI*2.0f);
            rotator.setSchedulingBounds(bounds);
            objRoot.addChild(rotator);
    
            //※ 子の設定
            TransformGroup group2 = new TransformGroup();
            group2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
            group1.addChild(group2);
    
            // 子の移動
            Transform3D trans = new Transform3D();
            trans.set(new Vector3d(0.0, 0.0, 0.5));
            TransformGroup groupw = new TransformGroup(trans);
            group2.addChild(groupw);
            groupw.addChild(new ColorCube(0.05));
    
            // 子の回転(X軸)
            Transform3D rotX = new Transform3D();
            rotX.setRotation(new AxisAngle4d(0.0, 0.0, 1.0, Math.PI/2));
            Alpha alpha2 = new Alpha(-1, 2000);
            RotationInterpolator rotator2 =
                new RotationInterpolator(alpha2, group2, rotX, (float) Math.PI*2.0f, 0.0f);
            rotator2.setSchedulingBounds(bounds);
            group1.addChild(rotator2);
    
            objRoot.compile();
            return objRoot;
        }
    }
    
  2. ソースプログラムをコンパイルしてクラスオブジェクトを実行して下さい。
    中央の ColorCube がY軸で回転し、その周りを小さな ColorCube がX軸で回転します。

プログラムの説明

  1. このプログラムは CreateScene() メソッド以外は Point.java と同じ要領です。
    基本的な説明は Java 3D で点を描画 を参照して下さい。
  2. 親子の ColorCube を生成する CreateScene() メソッドです。
    プリミティブなら何でも良かったのですが、設定が簡単で回転の様子が良く分かる ColorCube を使いました。
    BranchGroup を生成して、ここに描画するシーンを設定します。
    中央に配置する大きな親の ColorCube を設定します。
    ColorCube の自動回転 と同様にY軸を中心に自動的に回転するように設定しています。
        // 親子の ColorCube を生成
        public BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
            BoundingSphere bounds = new BoundingSphere(new Point3d(),100.0);
    
            //※ 親の設定
            TransformGroup group1 = new TransformGroup();
            group1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
            objRoot.addChild(group1);
            group1.addChild(new ColorCube(0.2));
    
            // 親の回転
            Transform3D rotY = new Transform3D();
            Alpha alpha1 = new Alpha(-1, 8000);
            RotationInterpolator rotator =
                new RotationInterpolator(alpha1, group1, rotY, 0.0f, (float) Math.PI*2.0f);
            rotator.setSchedulingBounds(bounds);
            objRoot.addChild(rotator);
        
  3. 親のまわりを回る子の設定です。
    group2 が子の TransformGroup ですが group1.addChild(group2); で親のグループにアッドします。
    これで親子関係が設定されます。
    そのままの位置では、二個のモデルが重なって描画されるので new Vector3d(0.0, 0.0, 0.5); で移動します。
    子はX軸を中心に自動的に回転するように設定します。
            //※ 子の設定
            TransformGroup group2 = new TransformGroup();
            group2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
            group1.addChild(group2);
    
            // 子の移動
            Transform3D trans = new Transform3D();
            Vector3d vect =  new Vector3d(0.0, 0.0, 0.5);
            trans.set(vect);
            TransformGroup groupw = new TransformGroup(trans);
            group2.addChild(groupw);
            groupw.addChild(new ColorCube(0.05));
    
            // 子の回転(X軸)
            Transform3D rotX = new Transform3D();
            rotX.setRotation(new AxisAngle4d(0.0, 0.0, 1.0, Math.PI/2));
            Alpha alpha2 = new Alpha(-1, 2000);
            RotationInterpolator rotator2 =
                new RotationInterpolator(alpha2, group2, rotX, (float) Math.PI*2.0f, 0.0f);
            rotator2.setSchedulingBounds(bounds);
            group1.addChild(rotator2);
    
            objRoot.compile();
            return objRoot;
        }
        

親子孫の設定

  1. 今度は親子孫の関係で回転してみましょう。
    親の設定は、親子のときと同じです。
    子の設定では、回転軸をYにして逆方向((float)Math.PI*2.0f, 0.0f) に回転してみました。
        // 親子孫の ColorCube を生成
        public BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
            BoundingSphere bounds = new BoundingSphere(new Point3d(),100.0);
    
            //※ 親の設定
                ・・・
    
            //※ 子の設定
                ・・・
            // 子の回転
            Alpha alpha2 = new Alpha(-1, 2000);
            RotationInterpolator rotator2 =
                new RotationInterpolator(alpha2, group2, rotY, (float) Math.PI*2.0f, 0.0f);
            rotator2.setSchedulingBounds(bounds);
            group2.addChild(rotator2);
        
  2. 子のまわりを回る孫の設定です。
    group1, group2, group3 が親子孫の TransformGroup です。
    group2 は group1 に addChild() します。
    group3 は group2 に addChild() します。
    これで親子孫の関係が設定されます。
    孫の位置を Vector3d(0.0, 0.3, 0.5) で移動して group3 に設定します。
    孫はX軸を中心に自動的に回転するように設定します。
    これで親のまわりを子が、子のまわりを孫がまわるようになります。
            //※ 孫の設定
            TransformGroup group3 = new TransformGroup();
            group3.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
            group2.addChild(group3);
    
            // 孫の移動
            Transform3D trans3 = new Transform3D();
            trans3.set(new Vector3d(0.0, 0.3, 0.5));
            groupw = new TransformGroup(trans3);
            group3.addChild(groupw);
            groupw.addChild(new ColorCube(0.03));
    
            // 孫の回転
            Transform3D rotX = new Transform3D();
            rotX.setRotation(new AxisAngle4d(1.0, 0.0, 0.0, Math.PI/2));
            alpha2 = new Alpha(-1, 2000);
            RotationInterpolator rotator3 =
                new RotationInterpolator(alpha2, group3, rotX, (float) Math.PI*2.0f, 0.0f);
            rotator3.setSchedulingBounds(bounds);
            group3.addChild(rotator3);
    
            objRoot.compile();
            return objRoot;
        }
        
  3. TransformGroup は、中に格納されている Node型オブジェクト(ColorCubeや別のTransformGroupオブジェクト)の座標を変換します。
    Node が TransformGroup のときは、さらにその中に格納されている Node型オブジェクトの座標が変換されます。
    親子孫の関係で回転を設定するのは、説明しただけではなかなか理解出来ないでしょう。
    太陽・地球・月や太陽・火星・フォボス/ダイモスの関係などを想定して、実際にプログラムしてみて下さい。

超初心者のプログラム入門(Java2)