Java 3D でプリミティブ(基本3Dモデル)を描画します。

Applet でプログラムを体験できます。
Applet のプログラム

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

プログラムの作成

  1. メモ帳などでタイプして View_Cylinder.java の名前で保存して下さい。
    //★ Java3D で Cylinder(円柱)を描画する
    import java.awt.*;
    import javax.swing.*;
    import javax.media.j3d.*;
    import javax.vecmath.*;
    import com.sun.j3d.utils.universe.*;
    import com.sun.j3d.utils.geometry.*;
    
    public class View_Cylinder extends JFrame
    {
        // main Method
        public static void main(String[] args)
        {   new View_Cylinder();  }
    
        // Constructor
        public View_Cylinder()
        {   // JFrame の初期化
            super("Cylinder_View test");
            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();
    
            // Scene を生成
            universe.addBranchGraph(CreateScene());
    
            setVisible(true);
        }
    
        // Scene の生成
        public BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
    
            BoundingSphere bounds = new BoundingSphere(new Point3d(),100.0);
            // Light の設定
            DirectionalLight dlight =
              new DirectionalLight(true, new Color3f(1.0f,1.0f,1.0f), new Vector3f(0.3f,-0.3f,-0.3f));
            dlight.setInfluencingBounds(bounds);
            objRoot.addChild(dlight);
            AmbientLight alight = new AmbientLight();
            alight.setInfluencingBounds(bounds);
            objRoot.addChild(alight);
    
            // 座標変換の設定
            TransformGroup trans = new TransformGroup();
            // Cylinder を生成
            trans.addChild(new Cylinder(0.3f,0.8f,createAppearance()));
            //trans.addChild(new Cylinder(0.2f,0.8f,Cylinder.GENERATE_NORMALS,createAppearance()));
            objRoot.addChild(trans);
    
            return objRoot;
        }
    
        // Material の設定
        public Appearance createAppearance()
        {   Appearance app = new Appearance();
            Material mat = new Material();
            mat.setDiffuseColor(1.0f, 1.0f, 0.0f);
            //mat.setDiffuseColor(0.0f, 0.8f, 0.7f);
            mat.setSpecularColor(0.1f, 0.1f, 0.1f);
            app.setMaterial(mat);
            return app;
        }
    }
    
  2. ソースプログラムをコンパイルして class オブジェクトを実行して下さい。
    Cylinder(円柱)が描画されたら完成です。

プログラムの説明

  1. Java3Dには、基本的な図形が "Primitive"(プリミティブ)として登録されています。
    "ColorCube" を除いて色は設定されていませんが、法線ベクトルは設定されています。
    他の言語では、点や線もプリミティブと呼ぶことがあるのですが、細かいことは抜きにしましょう。 (^_^;)
  2. これまでのプログラムと同様に Swing を使って JFrame を継承しています。
    Java3D 用のライブラリを import します。
    main Method では View_Cylinder Class をインスタンス化するだけです。
        import java.awt.*;
        import javax.swing.*;
        import javax.media.j3d.*;
        import javax.vecmath.*;
        import com.sun.j3d.utils.universe.*;
        import com.sun.j3d.utils.geometry.*;
    
        public class View_Cylinder extends JFrame
        {   // main Method
            public static void main(String[] args)
            {   new View_Cylinder();  }
        
  3. View_Cylinder Class の Constructor です。
    これまのプログラムと同様に JFrame の初期設定を行います。
    次に Java3D の初期化です。
    GraphicsConfiguration を取得して Canvas3D を生成(インスタンス化)します。
    add(canvas); で JFrame に Canvas3D を追加します。
    SimpleUniverse(canvas) で、Java3D の標準的な描画環境を設定します。
    CreateScene() メソッドで、Cylinder(円柱)を生成して、SimpleUniverse に追加します。
        // Constructor
        public View_Cylinder()
        {   // JFrame の初期化
            super("Cylinder_View test");
            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();
    
            // Scene を生成
            universe.addBranchGraph(CreateScene());
    
            setVisible(true);
        }
        
  4. Cylinder(円柱)を生成する CreateScene() メソッドです。
    BranchGroup を生成して、ここに描画するシーンを設定します。
    DirectionalLight() で平行光源を設定します。
    光源の説明は 四面体を描画 を参照して下さい。
    new TransformGroup() で座標変換を設定します。
    Cylinder を生成して TransformGroup に追加します。
    二種類の書き方を示しましたが、どちらも同じです。
    0.3f が Cylinder の太さで、0.8f が長さです。サイズを変えて試して下さい。
    createAppearance() メソッドで、モデルに Material を設定します。
    BranchGroup に TransformGroup を追加します。
        public BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
    
            BoundingSphere bounds = new BoundingSphere(new Point3d(),100.0);
            // Light の設定
            DirectionalLight dlight =
              new DirectionalLight(true, new Color3f(1.0f,1.0f,1.0f), new Vector3f(0.3f,-0.3f,-0.3f));
            dlight.setInfluencingBounds(bounds);
            objRoot.addChild(dlight);
            AmbientLight alight = new AmbientLight();
            alight.setInfluencingBounds(bounds);
            objRoot.addChild(alight);
    
            // 座標変換グループの設定
            TransformGroup trans = new TransformGroup();
            // Cylinder を生成
            trans.addChild(new Cylinder(0.3f,0.8f,createAppearance()));
            //trans.addChild(new Cylinder(0.2f,0.8f,Cylinder.GENERATE_NORMALS,createAppearance()));
            objRoot.addChild(trans);
    
            return objRoot;
        }
        
  5. Material を設定する createAppearance() メソッドです。
    Material の説明は 四面体を描画 を参照して下さい。
    setDiffuseColor() がモデルの色で、赤・緑・青の順に 0.0〜1.0 の範囲で設定します。
    モデルの色を変えて試してみて下さい。
        public Appearance createAppearance()
        {   Appearance app = new Appearance();
            Material mat = new Material();
            mat.setDiffuseColor(1.0f, 1.0f, 0.0f);
            //mat.setDiffuseColor(0.0f, 0.8f, 0.7f);
            mat.setSpecularColor(0.1f, 0.1f, 0.1f);
            app.setMaterial(mat);
            return app;
        }
        

その他のモデル

  1. CreateScene() メソッドを次のように修正して下さい。
    Cone() で円錐を生成しています。
    0.5f が Cone の太さで、0.9f が高さです。
        // Scene の生成
        public BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
            BoundingSphere bounds = new BoundingSphere(new Point3d(),100.0);
    
            // Light の設定
            DirectionalLight dlight =
              new DirectionalLight(true, new Color3f(1.0f,1.0f,1.0f), new Vector3f(0.3f,-0.3f,-0.3f));
            dlight.setInfluencingBounds(bounds);
            objRoot.addChild(dlight);
            AmbientLight alight = new AmbientLight();
            alight.setInfluencingBounds(bounds);
            objRoot.addChild(alight);
    
            // 座標変換グループの設定
            TransformGroup trans = new TransformGroup();
    
            // Cone を生成
            trans.addChild(new Cone(0.5f, 0.9f, Cone.GENERATE_NORMALS, createAppearance()));
            objRoot.addChild(trans);
    
            return objRoot;
        }
        
  2. 次に Box の描画ですが、名前が他の Object でも使われているので混同を避けるために geometry.Box をインポートして下さい。
    //import com.sun.j3d.utils.geometry.*;
    import com.sun.j3d.utils.geometry.Box;
    CreateScene() メソッドを次のように修正して下さい。
    Box() で直方体を生成しています。
    0.5f, 0.25f, 0.5 が、X,Y,Z方向の大きさです。
    Box を正面から描画したのでは、単なる矩形にしか見えません。
    そこで座標を少し回転して描画します。
    Transform3D を生成して、三次元の回転係数(0.2, 0.3, -0.1)を設定します。
    new TransformGroup(t3d) で座標変換グループを生成します。
    直方体を回転するので setCapability() で ALLOW_TRANSFORM_WRITE を許可して下さい。
        // Scene の生成
        public BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
            BoundingSphere bounds = new BoundingSphere(new Point3d(),100.0);
    
            // Light の設定
            DirectionalLight dlight =
              new DirectionalLight(true, new Color3f(1.0f,1.0f,1.0f), new Vector3f(0.3f,-0.3f,-0.3f));
            dlight.setInfluencingBounds(bounds);
            objRoot.addChild(dlight);
            AmbientLight alight = new AmbientLight();
            alight.setInfluencingBounds(bounds);
            objRoot.addChild(alight);
    
            // 座標を回転して描画
            Transform3D t3d = new Transform3D();
            t3d.setRotation(new AxisAngle4d(0.2,0.3,-0.1,Math.PI/4.0));
    
            // Model の修正を許可
            TransformGroup trans = new TransformGroup(t3d);
            trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    
            // Box生成
            trans.addChild(new Box(0.5f,0.25f,0.5f,createAppearance()));
            objRoot.addChild(trans);
    
            return objRoot;
        }
        
  3. geometry.ColorCube を import して、CreateScene() メソッドを次のように修正して下さい。
    ColorCube は立方体の各面に色を設定したモデルですが、Java3D では簡単に生成することが出来ます。
    //import com.sun.j3d.utils.geometry.*;
    import com.sun.j3d.utils.geometry.ColorCube;
    new ColorCube(0.4) で ColorCube を生成します。
    0.4f が立方体の大きさです。
    正面から描画したのでは、単なる矩形にしか見えないので Box と同様に回転して描画します。
        // Scene の生成
        public BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
            BoundingSphere bounds = new BoundingSphere(new Point3d(),100.0);
    
            // Light の設定
            DirectionalLight dlight =
              new DirectionalLight(true, new Color3f(1.0f,1.0f,1.0f), new Vector3f(0.3f,-0.3f,-0.3f));
            dlight.setInfluencingBounds(bounds);
            objRoot.addChild(dlight);
            AmbientLight alight = new AmbientLight();
            alight.setInfluencingBounds(bounds);
            objRoot.addChild(alight);
    
            // 座標を回転して描画
            Transform3D t3d = new Transform3D();
            t3d.setRotation(new AxisAngle4d(0.2,0.3,-0.1,Math.PI/4.0));
    
            // Model の修正を許可
            TransformGroup trans = new TransformGroup(t3d);
            trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    
            // 色を設定した ColorCube 生成
            trans.addChild(new ColorCube(0.4));
            objRoot.addChild(trans);
    
            return objRoot;
        }
        

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