ColorCube を自動的に回転しながら描画します。

Applet でプログラムを体験できます。
ColorCube を回転しながら描画する

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

プログラムの作成

  1. ColorCube を RotationInterpolator を使って自動的に回転しながら描画します。
    メモ帳などでタイプして Rot_Auto.java の名前で保存して下さい。
    //★ ColorCube を自動的に回転する    前田 稔
    import java.awt.GraphicsConfiguration;
    import javax.swing.*;
    import javax.media.j3d.*;
    import javax.vecmath.*;
    import com.sun.j3d.utils.universe.*;
    import com.sun.j3d.utils.geometry.ColorCube;
    
    public class Rot_Auto extends JFrame
    {
        // main Method
        public static void main(String[] args)
        {   java.awt.EventQueue.invokeLater(new Runnable()
            {   public void run()
                {   new Rot_Auto().setVisible(true);  }
            });
        }
    
        // Constructor
        public Rot_Auto()
        {   // JFrame の初期化
            super("Box Rotate");
            setSize(250,250);
            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();
            // FPS の設定(200 ミリ秒)
            universe.getViewer().getView().setMinimumFrameCycleTime(5);
    
            // Scene を生成
            universe.addBranchGraph(CreateScene());
        }
    
        // Scene の生成
        public BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
    
            // 座標変換の設定
            TransformGroup objTrans = new TransformGroup();
            objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
            objRoot.addChild(objTrans);
    
            // 色を設定した立方体
            objTrans.addChild(new ColorCube(0.4));
    
            // モデルの回転設定
            Transform3D yAxis = new Transform3D();      // 回転軸
            Alpha rotationAlpha = new Alpha(-1, 4000);  // 繰り返し回数:無限  変化時間:4秒
            RotationInterpolator rotator =
                new RotationInterpolator(rotationAlpha, objTrans, yAxis, 0.0f, (float)Math.PI*2.0f);
            BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
            rotator.setSchedulingBounds(bounds);
            objTrans.addChild(rotator);
    
            // BranchGroup の設定
            objRoot.compile();
            return objRoot;
        }
    }
    
  2. ソースプログラムをコンパイルして class オブジェクトを実行して下さい。
    ColorCube が回転しながら描画されたら完成です。
    j3d-examples-1_5_2-src.zip の中の \examples\hello_universe\ を参考にしました。

プログラムの説明

  1. Java3D にはアニメーション用のツールとして Interpolator(補間)が用意されています。
    単純な繰り返しなら Interpolator を設定するだけで簡単にアニメーションプログラムを作成することが出来ます。
    Interpolator は回転や移動など幾つかのものが用意されていますが、最初に 地球がまわる で使用した RotationInterpolator から説明しましょう。
    javax.media.j3d に登録されている Interpolator の種類です。
    Interpolator 説明
    ColorInterpolator 拡散反射による色の変化
    TransparencyInterpolator 透明度の変化
    ScaleInterpolator モデルの拡大/縮小
    RotationInterpolator モデルの回転
    PositionInterpolator モデルの移動
    SwitchValueInterpolator モデルの ON/OFF
    PositionPathInterpolator 変化点に従ってモデルの移動
    RotationPathInterpolator 変化点に従ってモデルの回転
    RotPosPathInterpolator 変化点に従ってモデルの回転と移動
    RotPosScalePathInterpolator 変化点に従ってモデルの回転/拡大縮小/位置
  2. これまでのプログラムと同様に Swing を使って JFrame を継承しています。
    Java3D 用のライブラリを import します。
    ColorCube を使うので geometry.ColorCube を import します。
        import java.awt.GraphicsConfiguration;
        import javax.swing.*;
        import javax.media.j3d.*;
        import javax.vecmath.*;
        import com.sun.j3d.utils.universe.*;
        import com.sun.j3d.utils.geometry.ColorCube;
        
  3. main Method では Rot_Auto Class をインスタンス化するだけなのですが、Runnable が使われています。
    Runnable の説明は Runnable で FPS を制御 を参照して下さい。
    Sun から提供されたサンプルが Runnable を使っているので、尊重することにします。 ヽ(^^ )
        public class Rot_Auto extends JFrame
        {
            // main Method
            public static void main(String[] args)
            {   java.awt.EventQueue.invokeLater(new Runnable()
                {   public void run()
                    {   new Rot_Auto().setVisible(true);  }
                });
            }
        
    試しに従来と同じようにプログラムしても、動くことを確認しました。 (^_^;)
        public static void main(String[] args)
        {   new Rot_Auto();  }
    
        // Constructor
        public Rot_Auto()
        {   ・・・
    
            setVisible(true);
        }
        
  4. Rot_Auto Class の Constructor です。
    これまのプログラムと同様に JFrame の初期設定を行います。
    次に Java3D の初期化です。
    GraphicsConfiguration を取得して Canvas3D を生成(インスタンス化)します。
    add(canvas); で JFrame に Canvas3D を追加します。
    SimpleUniverse(canvas) で、Java3D の標準的な描画環境を設定します。
    次に FPS(frames per second)を1秒間に5フレーム(200ミリ秒)に設定します。
    この設定が効いているか否かは不明で、コメントアウトしても問題無く動くようです。 (^_^;)
    // FPS の設定(200 ミリ秒)
    universe.getViewer().getView().setMinimumFrameCycleTime(5);
    CreateScene() メソッドで ColorCube を生成して、SimpleUniverse に追加します。
        // Constructor
        public Rot_Auto()
        {   // JFrame の初期化
            super("Box Rotate");
            setSize(250,250);
            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();
            // FPS の設定(200 ミリ秒)
            universe.getViewer().getView().setMinimumFrameCycleTime(5);
    
            // Scene を生成
            universe.addBranchGraph(CreateScene());
        }
        
  5. ColorCube を生成する CreateScene() メソッドです。
    BranchGroup を生成して、ここに描画するシーンを設定します。
    new TransformGroup() で座標変換を設定します。
    モデルを回転するので setCapability() で ALLOW_TRANSFORM_WRITE を許可して下さい。
    ColorCube() を生成して BranchGroup に追加します。
    次にモデルの回転を設定します。
    new Transform3D() で回転軸を設定します。
    既定値では、Y軸を中心に回転します。
    new Alpha(-1, 4000); で繰り返し回数と速度を設定します。
    繰り返し回数に -1 を設定すると無限に繰り返されます。
    4000 が速度で、4秒で一回転します。
    この値を大きくすると回転速度が遅くなり、小さくすると速くなります。
    RotationInterpolator() で繰り返し実行される回転情報を設定します。
    rotationAlpha が繰り返し回数と速度で、objTrans が回転対象で、yAxis が回転軸です。
    続く 0.0f, (float)Math.PI*2.0f が回転角度の最小(0度)と最大(360度)です。
    BoundingSphere で RotationInterpolator の及ぶ範囲を設定して BranchGroup に追加します。
        // Scene の生成
        public BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
    
            // 座標変換の設定
            TransformGroup objTrans = new TransformGroup();
            objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
            objRoot.addChild(objTrans);
    
            // ColorCube を生成
            objTrans.addChild(new ColorCube(0.4));
    
            // モデルの回転設定
            Transform3D yAxis = new Transform3D();      // 回転軸
            Alpha rotationAlpha = new Alpha(-1, 4000);  // 繰り返し回数:無限  変化時間:4秒
            RotationInterpolator rotator =
                new RotationInterpolator(rotationAlpha, objTrans, yAxis, 0.0f, (float)Math.PI*2.0f);
            BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
            rotator.setSchedulingBounds(bounds);
            objTrans.addChild(rotator);
    
            // BranchGroup の設定
            objRoot.compile();
            return objRoot;
        }
        
  6. new Alpha(-1, 4000); を修正して回転速度を遅く(速く)してみて下さい。
    new Alpha(2, 4000); に修正して、二回転で止まることを確認して下さい。
  7. Transform3D yAxis = new Transform3D(); が回転軸ですが、このままではY軸を中心に回転します。
        Transform3D yAxis = new Transform3D();      // このままではY軸で回転
        
    次のようにソースコードを追加するとX軸を中心に回転します。
        Transform3D yAxis = new Transform3D();
        yAxis.setRotation(new AxisAngle4d(0.0, 0.0, 1.0, Math.PI/2));  // X軸で回転
        
    また次のように修正するとZ軸を中心に回転します。
        Transform3D yAxis = new Transform3D();
        yAxis.setRotation(new AxisAngle4d(1.0, 0.0, 0.0, Math.PI/2));  // Z軸で回転
        
    setRotationメソッドは原点(0,0,0)と引数である(x,y,z)の2点を結ぶ直線を軸として、同じく引数であるangleを回転角度として回転を行います。
    例えばX軸を中心として30度回転させたいのであれば setRotationメソッドを使って記述すると下記のようになります。
        Transform3D yAxis = new Transform3D();
        t3d.setRotation(new AxisAngle4f(1.0f, 0.0f, 0.0f, (float)(Math.PI / 6)));
        

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