Java 3D で Polygon(多角形)を描画します。

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

プログラムの作成

  1. メモ帳などでタイプして Triangle.java の名前で保存して下さい。
    //★ Java3D で Triangle(三角ポリゴン)を描画する
    import java.awt.*;
    import javax.swing.*;
    import javax.media.j3d.*;
    import javax.vecmath.*;
    import com.sun.j3d.utils.universe.*;
    
    // Main Class
    public class Triangle extends JFrame
    {
        // main Method
        public static void main(String[] args)
        {   new Triangle();  }
    
        // Constructor
        public Triangle()
        {   // JFrame の初期化
            super("Triangle test");
            setSize(300,300);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            // Java3D関係の設定
            GraphicsConfiguration g_config = SimpleUniverse.getPreferredConfiguration();
            Canvas3D canvas = new Canvas3D(g_config);
            add(canvas);
    
            // SimpleUniverseを生成
            SimpleUniverse universe = new SimpleUniverse(canvas);
            universe.getViewingPlatform().setNominalViewingTransform();
    
            // Triangle(三角ポリゴン)の生成
            BranchGroup scene = CreateScene();
            universe.addBranchGraph(scene);
    
            setVisible(true);
        }
    
        //  Triangle(三角ポリゴン)を生成
        private BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
            Point3d[] vertices =
            {  new Point3d(-0.8, 0.4, 0.0), new Point3d(-0.5, -0.4, 0.0), new Point3d(-0.1, 0.3, 0.0),
               new Point3d(0.1, 0.0, 0.0),  new Point3d(0.3, -0.4, 0.0),  new Point3d(0.6, 0.1, 0.0)
            };
    
            TriangleArray geometry = new TriangleArray(vertices.length, GeometryArray.COORDINATES);
            geometry.setCoordinates(0, vertices);
    
            Shape3D shape = new Shape3D(geometry);
            objRoot.addChild(shape);
    
            return objRoot;
        }
    }
    
  2. ソースプログラムをコンパイルして class オブジェクトを実行して下さい。
    三角ポリゴンが2個描画されたら完成です。

プログラムの説明

  1. このプログラムは CreateScene() メソッド以外は Point.java と同じ要領です。
    基本的な説明は Java 3D で点を描画 を参照して下さい。
  2. 三角形 Polygon を生成する CreateScene() メソッドです。
    BranchGroup を生成して、ここに描画するシーンを設定します。
    Point3d[] 配列で2個の三角形の座標を定義します。
    new TriangleArray() で 三角形 Polygon を生成します。
    new Shape3D(geometry) を生成して、addChild() メソッドで親となるノードに追加します。
    Point(点)も Line(線)も Polygon(多角形)も三次元座標で定義するのですが、現在の所Z座標はゼロに設定しています。
    Window の座標系と三次元座標系では、向きが異なります。
        //  Triangle(三角ポリゴン)を生成
        private BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
            Point3d[] vertices =
            {  new Point3d(-0.8, 0.4, 0.0), new Point3d(-0.5, -0.4, 0.0), new Point3d(-0.1, 0.3, 0.0),
               new Point3d(0.1, 0.0, 0.0),  new Point3d(0.3, -0.4, 0.0),  new Point3d(0.6, 0.1, 0.0)
            };
    
            TriangleArray geometry = new TriangleArray(vertices.length, GeometryArray.COORDINATES);
            geometry.setCoordinates(0, vertices);
    
            Shape3D shape = new Shape3D(geometry);
            objRoot.addChild(shape);
    
            return objRoot;
        }
        
  3. CreateScene() メソッドをアレンジしてみましょう。
    POLYGON_FILL でポリゴンの面が描画されます。
    POLYGON_LINE でポリゴンの線が描画されます。
    POLYGON_POINT でポリゴンの頂点が点で描画されます。
    面/線/頂点を試してみて下さい。
    setCullFace() はカリングモードの設定です。
    ポリゴンには表と裏があって、通常は裏面を描画しないように設定されています。
    カリングモードを修正して試してみて下さい。
    カリングと座標系の説明は Windows Guid を参照して下さい。
        //  Triangle(三角ポリゴン)を生成
        private BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
            Point3d[] vertices =
            {  new Point3d(-0.8, 0.4, 0.0), new Point3d(-0.5, -0.4, 0.0), new Point3d(-0.1, 0.3, 0.0),
               new Point3d(0.1, 0.0, 0.0),  new Point3d(0.3, -0.4, 0.0),  new Point3d(0.6, 0.1, 0.0)
            };
    
            TriangleArray geometry = new TriangleArray(vertices.length, GeometryArray.COORDINATES);
            geometry.setCoordinates(0, vertices);
    
            PolygonAttributes pattr = new PolygonAttributes();
            pattr.setPolygonMode(PolygonAttributes.POLYGON_FILL); //面
            //pattr.setPolygonMode(PolygonAttributes.POLYGON_LINE); //線
            //pattr.setPolygonMode(PolygonAttributes.POLYGON_POINT); //Point
            //pattr.setCullFace(PolygonAttributes.CULL_NONE); //両面を描画
            //pattr.setCullFace(PolygonAttributes.CULL_FRONT); //表面をカリング
            pattr.setCullFace(PolygonAttributes.CULL_BACK); //裏面をカリング
            Appearance aleft = new Appearance();
            aleft.setPolygonAttributes(pattr);
    
            Shape3D shape = new Shape3D(geometry, aleft);
            objRoot.addChild(shape);
    
            return objRoot;
        }
        
  4. 今度は CreateScene() メソッドを次のように修正して下さい。
    三角形を一個ずつ定義しないで、連続して(TriangleStripArray)定義します。
    最初の8個が1枚目のポリゴンで、次の7個が2枚目のポリゴンです。
    説明は Windows Guid を参照して下さい。
        // 連続したポリゴンを生成
        private BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
            Point3d[] vertices =
            {  new Point3d(-0.9, -0.6, 0.0), new Point3d(-0.5, -0.8, 0.0),
               new Point3d(-0.3, -0.4, 0.0), new Point3d(0.0, -0.6, 0.0),
               new Point3d(0.0, 0.0, 0.0), new Point3d(0.3, -0.2, 0.0),
               new Point3d(0.5, 0.1, 0.0),   new Point3d(0.9, 0.0, 0.0),
    
               new Point3d(-0.8, 0.2, 0.0),  new Point3d(-0.6, 0.0, 0.0),
               new Point3d(-0.6, 0.5, 0.0),  new Point3d(-0.3, 0.3, 0.0),
               new Point3d(-0.2, 0.6, 0.0),  new Point3d(0.1, 0.5, 0.0),
               new Point3d(0.0, 0.8, 0.0)
            };
            int[] stripVertexCounts = { 8, 7 };
    
            TriangleStripArray geometry = new TriangleStripArray(
              vertices.length, GeometryArray.COORDINATES, stripVertexCounts);
            geometry.setCoordinates(0, vertices);
    
            Shape3D shape = new Shape3D(geometry);
            objRoot.addChild(shape);
    
            return objRoot;
        }
        

四角形ポリゴン

  1. CreateScene() メソッドを次のように修正して下さい。
    BranchGroup を生成して、ここに描画するシーンを設定します。
    Point3d[] 配列で2個の四角形の座標を定義します。
    new QuadArray() で四角形 Polygon を生成します。
        //  Quad(4角ポリゴン)を生成
        private BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
            Point3d[] vertices =
            {  new Point3d(-0.8, 0.0, 0.0), new Point3d(-0.2, -0.4, 0.0),
               new Point3d(0.0, 0.3, 0.0), new Point3d(-0.5, 0.3, 0.0),
               new Point3d(0.2, 0.0, 0.0),  new Point3d(0.5, -0.4, 0.0),
               new Point3d(0.8, 0.1, 0.0),  new Point3d(0.4, 0.3, 0.0)
            };
    
            QuadArray geometry = new QuadArray(vertices.length, GeometryArray.COORDINATES);
            geometry.setCoordinates(0, vertices);
    
            Shape3D shape = new Shape3D(geometry);
            objRoot.addChild(shape);
    
            return objRoot;
        }
        

色の設定

  1. ポリゴンの頂点に色を設定します。
    CreateScene() メソッドを次のように修正して下さい。
    一個目の三角形に赤を、二個目の三角形に青を設定してみました。
    TriangleArray() に GeometryArray.COORDINATES | GeometryArray.COLOR_3 を指定して下さい。
    geometry.setColors(0, colors1); で色を設定しているのですが、colors1[3] なので 0,1,2 に色が設定されます。
    同様に geometry.setColors(3, colors2); で 3,4,5 に色が設定されます。
    一個の三角形の頂点に別々の色を設定すると、頂点の色がグラデーションして描画されます。
        //  Triangle(三角ポリゴン)を生成
        private BranchGroup createSceneGraph()
        {   BranchGroup objRoot = new BranchGroup();
            Point3d[] vertices =
            {  new Point3d(-0.8, 0.0, 0.0), new Point3d(-0.5, -0.4, 0.0), new Point3d(-0.1, 0.3, 0.0),
               new Point3d(0.1, 0.0, 0.0),  new Point3d(0.3, -0.4, 0.0),  new Point3d(0.6, 0.1, 0.0)
            };
    
            TriangleArray geometry = new TriangleArray(
              vertices.length, GeometryArray.COORDINATES | GeometryArray.COLOR_3);
            geometry.setCoordinates(0, vertices);
            Color3f red = new Color3f(1.0f, 0.0f, 0.0f); 
            Color3f blue = new Color3f(0.0f, 0.0f, 1.0f);
            Color3f[] colors1 = { red, red, red };
            Color3f[] colors2 = { blue, blue, blue };
            geometry.setColors(0, colors1);     // 0,1,2 に red を設定
            geometry.setColors(3, colors2);     // 3,4,5 の blue を設定
    
            Shape3D shape = new Shape3D(geometry);
            objRoot.addChild(shape);
    
            return objRoot;
        }
        
  2. Shape3D 全体に色を設定します。
    CreateScene() メソッドを次のように修正して下さい。
    高速/高品質/フラット/グーローを試してみて下さい。そんなに違いが無いかも知れません。
    モデルに色を設定する方法には幾通りかあります。
        //  Triangle(三角ポリゴン)を生成
        private BranchGroup createSceneGraph()
        {   BranchGroup objRoot = new BranchGroup();
            Point3d[] vertices =
            {  new Point3d( 0.0, 0.5, 0.0), new Point3d(-0.8, -0.5, 0.0), new Point3d( 0.8, -0.5, 0.0)  };
    
            TriangleArray geometry = new TriangleArray(vertices.length, GeometryArray.COORDINATES);
            geometry.setCoordinates(0, vertices);
    
            ColoringAttributes cattr = new ColoringAttributes(0.8f,0.8f,0.0f,ColoringAttributes.FASTEST); //高速
            //ColoringAttributes cattr = new ColoringAttributes(0.8f,0.0f,0.0f,ColoringAttributes.NICEST); //高品質
            //ColoringAttributes cattr = new ColoringAttributes(0.8f,0.0f,8.0f,ColoringAttributes.SHADE_FLAT); //フラット
            //ColoringAttributes cattr = new ColoringAttributes(0.0f,0.3f,0.8f,ColoringAttributes.SHADE_GOURAUD); //グーロー
            Appearance aleft = new Appearance();
            aleft.setColoringAttributes(cattr);
    
            Shape3D shape = new Shape3D(geometry, aleft);
            objRoot.addChild(shape);
    
            return objRoot;
        }
        

5角形を描画


  1. 5角形の頂点に乱数で色を設定して綺麗な模様を描画してみましょう。
    CreateScene() メソッドを次のように修正して、回転計算メソッド(Rot) を追加して下さい。
    5角形の描画には、中心座標と扇型に広がる座標を指定する TriangleFanArray を使っています。
    座標の設定は vect[0] が中心座標で、vect[1]〜vect[5] に5角形の頂点座標を設定します。
    さらに vect[6] には元の座標に戻るために vect[1] と同じ値を設定します。
    頂点に色を設定するので TriangleArray() に GeometryArray.COORDINATES | GeometryArray.COLOR_3 を指定します。
    このプログラムで作成したポリゴンは、裏向きになっています。
    そこで setCullFace を CULL_FRONT に設定します。
        // 5角形を生成
        private BranchGroup CreateScene()
        {   int i;
    
            BranchGroup objRoot = new BranchGroup();
            Point3d[] vect = new Point3d[7];
            for(i=0; i<7; i++)  vect[i] = new Point3d();
            for(i=1; i<6; i++)  Rot(72.0f*i, 0.5f, vect[i]);
            Rot(72.0f, 0.5f, vect[6]);
    
            int[] stripVertexCounts = { 7 };
            TriangleFanArray geometry =
            //  new TriangleFanArray(vect.length, GeometryArray.COORDINATES, stripVertexCounts);
              new TriangleFanArray(vect.length, GeometryArray.COORDINATES | GeometryArray.COLOR_3, stripVertexCounts);
            geometry.setCoordinates(0, vect);
    
            Color3f[] colors = new Color3f[7];
            colors[0] = new Color3f(1.0f, 1.0f, 1.0f);
            for(i=1; i<7; i++)  colors[i] = new Color3f((float)Math.random(), (float)Math.random(), (float)Math.random());
            geometry.setColors(0, colors);
    
            PolygonAttributes pattr = new PolygonAttributes();
            //pattr.setCullFace(PolygonAttributes.CULL_BACK); //裏面をカリング
            pattr.setCullFace(PolygonAttributes.CULL_FRONT); //表面をカリング
            Appearance aleft = new Appearance();
            aleft.setPolygonAttributes(pattr);
            Shape3D shape = new Shape3D(geometry, aleft);
            objRoot.addChild(shape);
            return objRoot;
        }
    
        //★ 回転計算(rt=度)、中心(0,0)、半径(len)
        public void Rot(float rt, float len, Point3d vect)
        {   vect.x = (float)(Math.sin(rt / 180 * Math.PI)) * len;
            vect.y = (float)(Math.cos(rt / 180 * Math.PI)) * len;
            vect.z = 0;
        }
        

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