Graphics 版 (精华区)

发信人: seaman (翩翩少年), 信区: Graphics
标  题: JAVA3D学习系列(9)--面的生成(上)
发信站: 哈工大紫丁香 (Tue Sep 28 19:11:34 1999), 转信

        JAVA3D学习系列(9)----- 面的生成(上)


    汕头大学机电系    张杰(jzhang@mailserv.stu.edu.cn)

一. 生成平面的对象及其定义
    JAVA3D可通过编程显示出面来,面有两种:三角形和四边形,
相应的对象为Triangle和Quad。
    JAVA3D用于生成平面的对象有:
1.  TriangleArray
    TriangleArray (int vertexCount, int vertexFormat )

2.  QuadArray
    QuadArray (int vertexCount, int vertexFormat )

3.  TriangleStripArray
    TriangleStripArray ( int vertexCount , int vertexFormat,
                         int[] stripVertexCounts )

4.  TriangleFanArray
    TriangleFanArray ( int vertexCount ,int vetexFormat,
                       int[] stripVertexCounts )

5.  IndexedTriangleArray
    IndexedTriangleArray (int vertexCount , int vertexFormat,
                          int indexCount)

6.  IndexedQuadArray
    IndexedQuadArray (int vertexCount , int vertexFormat,
                      int indexCount )

7.  IndexedTriangleStripArray
    IndexedTriangleStripArray( int vertexCount, int vertexFormat,
                               int indexCount, int stripIndexCounts[])

8.  IndexedTriangleFanArray
    IndexedTriangleFanArray ( int vertexCount, int vertexFormat,
                              int indexCount, int stripIndexCounts[])

二. TriangleArray生成的面
    和前面介绍的PointArray、LineArray一样,面也可以用
TriangleArray来生成,利用它可以生成三角片面我们先看一下TriangleArray的定义:
        TriangleArray (int vertexCount, int vertexFormat )
    这里:
        vertexCount表示顶点的个数(必须为三的倍数)
        vertexFormat表示顶点的格式(第七讲有介绍)
    下面我们看一个利用TriangleArray的例子,例子里有九个点。

      --1--         --4--      --7--

 --0--        --3--        --6--   

      --2--         --5--      --8--

//triShape1.java
import javax.media.j3d.*;

public class triShape1 extends Shape3D {

    private float vert[] = { 
        -.8f , .0f ,0.0f,
        -.4f , .8f ,0.0f,
        -.4f , -.8f,0.0f,
        -.2f , .0f ,0.0f,
        0.2f , .8f ,0.0f,
        0.2f , -.8f,0.0f,
        0.4f , .0f ,0.0f,
        0.8f , .8f ,0.0f,
        0.8f , -.8f,0.0f,
       };

    private float color[] = {
        0.0f,0.5f,1.0f,
        0.5f,0.0f,1.0f,
        0.0f,0.8f,2.0f,
        1.0f,0.0f,0.3f,
        0.0f,1.0f,0.3f,
        0.3f,0.8f,0.0f,
        0.0f,0.5f,1.0f,
        0.5f,0.0f,1.0f,
        0.0f,0.8f,2.0f,
      };

    public triShape1() {
        TriangleArray tri = new TriangleArray(9, 
             TriangleArray.COORDINATES|TriangleArray.COLOR_3);
          tri.setCoordinates(0,vert);
          tri.setColors(0,color);
        this.setGeometry(tri);
    }
}

//end of triShape1.java

    从程序运行结果可以得知,TriangleArray将一个顶点数组的
每三个数组合在一个,生成一个面,因而vertexCount的点数必须
为三的倍数。triShape1.java显示的结果是三个三角形构成的面。
由于对每一个顶点都定义了颜色,因而程序显示的是色彩变化的
三角形,且只能从正面看到,反面看不到,这和VRML程序生成面
的效果完全一样。在VRML程序中,为了使一个面的正反方向都可见,
可以在IndexedFaceSet节点中将solid字段设为FALSE。
    下面是和triShape1.java相对应的VRML程序,为了使面的正反
都可见,我们将IndexedFaceSet的solid字段设为FALSE。

#VRML V2.0 utf8
DEF T Transform{
  children  Shape {
    geometry IndexedFaceSet {
      solid FALSE
      coord Coordinate {
        point [ -.8 , .0 ,0.0,
                -.4 , .8 ,0.0,
                -.4 , -.8,0.0,
                -.2 , .0 ,0.0,
                0.2 , .8 ,0.0,
                0.2 , -.8,0.0,
                0.4 , .0 ,0.0,
                0.8 , .8 ,0.0,
                0.8 , -.8,0.0,]}
      coordIndex [0 1 2 -1 3 4 5 -1 6 7 8]
      color Color{
        color [ 0.0,0.5,1.0,
                0.5,0.0,1.0,
                0.0,0.8,2.0,
                1.0,0.0,0.3,
                0.0,1.0,0.3,
                0.3,0.8,0.0
                0.0,0.5,1.0,
                0.5,0.0,1.0,
                0.0,0.8,2.0,]}
 }}}

DEF TS TimeSensor{
  cycleInterval 4
  loop TRUE}

DEF OI OrientationInterpolator{
   key      [0 .25 .5 .75 1]
   keyValue [0 1 0 1,   0 1 0  1.57,  0 1 0 3.14
             0 1 0 4.71 0 1 0  6.28]}

ROUTE TS.fraction TO OI.fraction
ROUTE OI.value TO T.rotation

    如何将triShape1.java显示的内容从色彩变化及单面显示
变为每一个面只有一种颜色及双面显示?
    VRML程序中我们可以将IndexedFaceSet节点的
colorPerVertex设为FALSE,并提供一个
colorIndex字段以挑选颜色数组中的颜色。
    在JAVA3D程序中我们有一个笨办法处理颜色问题,即将
每一个面的三个点的颜色均设定为相同的数值,因为
TriangleArray对象没有
      setColorIndices(0,index)
这一方法,故不能从颜色组中选用颜色。
    至于双面显示问题,我们可以通过设定PolygonAttributes
对象的setCullFace(int cullFace)方法来获得,cullFace可以为:
      CULL_NONE
      CULL_FRONT
      CULL_BACK
通过选择其中之一,来获得前面、后面及双面的显示效果,缺省
值为只显示前面。
    另外,我们还可以通过设定PolygonAttributes对象的
setPolygonMode(int polygonMode)方法使面用顶点或端线来代替。
    polygonMode有下列三种选择:
      POLYGON_POINT
      POLYGON_LINE
      POLYGON_FILL
缺省值为POLYGON_FILL。
    triShape2.java显示的是前后都可以看得见的面,每一个面
都有唯一的颜色。
//triShape2.java

import javax.media.j3d.*;

public class triShape2 extends Shape3D {
     private float vert[] = { 
        -.8f , .0f ,0.0f,
        -.4f , .8f ,0.0f,
        -.4f , -.8f,0.0f,
        -.2f , .0f ,0.0f,
        0.2f , .8f ,0.0f,
        0.2f , -.8f,0.0f,
        0.4f , .0f ,0.0f,
        0.8f , .8f ,0.0f,
        0.8f , -.8f,0.0f,
       };

    private float color[] = {
        1.0f,0.0f,0.0f,
        1.0f,0.0f,0.0f,
        1.0f,0.0f,0.0f,
        0.0f,1.0f,0.0f,
        0.0f,1.0f,0.0f,
        0.0f,1.0f,0.0f,
        0.0f,0.0f,1.0f,
        0.0f,0.0f,1.0f,
        0.0f,0.0f,1.0f,
      };

    public triShape2() {
        TriangleArray tri = new TriangleArray(9, 
             TriangleArray.COORDINATES|TriangleArray.COLOR_3);
          tri.setCoordinates(0,vert);
          tri.setColors(0,color);

        PolygonAttributes pa = new PolygonAttributes();
          pa.setCullFace(PolygonAttributes.CULL_NONE);

        //pa.setPolygonMode(PolygonAttributes.POLYGON_LINE);
                      //  增加这一行会使面由线代替

        Appearance ap = new Appearance();
          ap.setPolygonAttributes(pa);
        this.setGeometry(tri);
        this.setAppearance(ap);
    }
}


三. QuadArray生成的面
    QuadArray对象的定义如下:
    QuadArray (int vertexCount, int vertexFormat )
    这里,每一个参数的含义都和TriangleArray里的一样。
    QuadArray可用来生成平面,构成平面的顶点的数目必须为
4的倍数。
    下面我们来看一个利用QuadArray的例子,例子里有8个点,
程序运行后生成了两个长方形面。
//quadShape1.java

import javax.media.j3d.*;

public class quadShape1 extends Shape3D {
     private float vert[] = { 
        -.6f , .8f ,0.0f,
        -.6f , -.8f,0.0f,
        -0.2f , -.6f,0.0f,
        -0.2f , .6f ,0.0f,
        0.2f , .8f ,0.0f,
         0.6f , .8f, 0.0f,
        0.6f , -.8f, 0.0f,
        0.2f , -.8f,0.5f,
         };

    private float color[] = {
        1.0f,0.5f,0.0f,
        1.0f,0.0f,0.5f,
        1.0f,0.8f,0.0f,
        5.0f,1.0f,0.0f,
        0.0f,1.0f,0.5f,
        0.9f,1.0f,0.0f,
        0.5f,0.0f,1.0f,
        0.0f,0.5f,1.0f,
      };

    public quadShape1() {
        QuadArray tri = new QuadArray(8, 
             QuadArray.COORDINATES|QuadArray.COLOR_3);
          tri.setCoordinates(0,vert);
          tri.setColors(0,color);

        this.setGeometry(tri);
     }
}
//end of quadShape1.java
    程序的双面显示问题及单一颜色问题的处理同上面的
triShape2.java。
    编写QuadArray应用程序时,我们要注意几个问题。
    首先是四点应当共面,如果不共面,程序仍然可以编译
运行,但显示的内容为两个三角面。
    其次是四个点组成的面不应有凹点,这有点象VRML程序中
的Extrusion、IndexedFaceSet里的情况,当然,在VRML程序中
四个点构成的面可以有凹点,这时只需要在相应的节点内加上
一个参数:
        convex  TRUE
    而在JAVA3D程序中,如果QuadArray生成的面有凹点时,
程序的显示结果会不正确,例如,当我们将quadShape里的顶点
坐标换为:
private float vert[] = { 
        -.6f ,  .8f , 0.0f,
        -.6f , -.8f , 0.0f,
        -0.2f, -.6f , 0.0f,
        -0.5f, .0f  , 0.0f,
        0.2f , .8f  , 0.0f,
        0.6f , .8f  , 0.0f,
        0.6f , -.8f , 0.0f,
        0.2f , -.8f , 0.5f,
         };
时,显示的结果不确定,正面时是一个形状,转到反面时是
另一个形状。
    最后一个问题是QuadArray所利用的每四个点,其坐标
位置除了要共面、凸点,四个点的旋转方向也要注意,如果
点的旋转方向是逆时针的话,其正面朝外,反之则朝内。当
我们将顶点的坐标换成下面的数据时,我们可以清楚地得出
这一结论。
 private float vert[] = { 
        -.6f  , .8f  ,0.0f,
        -.6f  , -.8f ,0.0f,
        -0.2f , -.4f ,0.0f,
        -0.2f , .4f  ,0.0f,
        0.2f  , .8f  ,0.0f,
         0.6f , .8f  ,0.0f,
        0.6f  , -.8f ,0.0f,
        0.2f  , -.8f ,0.5f,
         };


四. TriangleStripArray生成的面
    TriangleStripArray对象的定义为:
    TriangleStripArray ( int vertexCount , int vertexFormat,
                         int[] stripVertexCounts )
    利用TriangleStripArray对象,我们可以生成多组三角片面,
对于每一组三角片面来说,它的头三个点生成一个面,从第四个点
开始,每一个点都和前两个点生成一个新的面。
    下面的程序中,我们利用一组点,生成了两组三角片面。程序
中,顶点数组的个数为11,头一组用了7个顶点,生成了5个相连的
三角片面,后一组用了5个顶点,生成了三个相连的三角片面。
//triShape3.java

import javax.media.j3d.*;

public class triShape3 extends Shape3D {
    int StripCount[] = new int[2];
     private float vert[] = { 
         -.6f ,  .8f , 0.0f,
         -.6f , -.8f,  0.2f,
        -0.2f ,  .5f,  -.2f,
        -0.2f , -.5f , 0.2f,
         0.0f , -.5f,  -.2f,
         0.0f ,  .5f ,  .2f,
         0.2f ,  .0f,   .0f,
         0.2f ,  .8f , 0.3f,
         0.2f , -.8f, -0.3f,
         0.6f ,  .8f,  0.0f,
         0.6f , -.8f,  0.5f,
         0.8f , 0.0f ,  .3f
         };

    private float color[] = {
        1.0f,0.5f,0.0f,
        1.0f,0.0f,0.5f,
        1.0f,0.8f,0.0f,
        5.0f,1.0f,0.0f,
        0.0f,1.0f,0.5f,
        0.9f,1.0f,0.0f,
        0.5f,0.0f,1.0f,
        0.0f,0.5f,1.0f,
        1.0f,0.5f,0.0f,
        1.0f,0.0f,0.5f,
        1.0f,0.8f,0.0f,
      };

    public triShape3() {
        StripCount[0] = 7;
        StripCount[1] = 5;
        TriangleStripArray tri = new TriangleStripArray(12, 
             TriangleStripArray.COORDINATES|
                      TriangleStripArray.COLOR_3 , StripCount);
          tri.setCoordinates(0,vert);
          tri.setColors(0,color);
        PolygonAttributes pa = new PolygonAttributes();
          pa.setCullFace(PolygonAttributes.CULL_NONE);
        Appearance ap = new Appearance();
          ap.setPolygonAttributes(pa);
        this.setGeometry(tri);
        this.setAppearance(ap);
        this.setGeometry(tri);
     }
}
//end of triShape3.java


五. TriangleFanArray生成的面
    TriangleFanArray对象的定义为:
    TriangleFanArray ( int vertexCount ,int vetexFormat,
                       int[] stripVertexCounts )
    利用TriangleFanArray对象,我们可以生成多组三角片面,每组
三角片面占用一定数量的顶点,每个组在生成三角片面时,头三个顶
点构成一个三角片面,其余的顶点和前面的顶点及每组第一个顶点生成
一个三角片面。下面的triShape4.java程序中,我们生成了两组三角
片面,头5个点生成了三个相连的三角片面,后6个点生成了四个相连的
三角片面。形状就像两把扇子,一大一小。
//triShape4.java

import javax.media.j3d.*;

public class triShape4 extends Shape3D {
    int FanCount[] = new int[2];
     private float vert[] = { 
              0.0f , 0.0f , 0.0f, 
              -0.3f , 0.3f , 0.02f,
              -0.1f , 0.4f , -0.02f,
               0.1f , 0.4f ,  0.02f, 
               0.3f,  0.3f ,  -0.02f,
               0.0f, -0.8f ,  0.0f,
              -0.6f, -0.2f,  0.02f,
              -0.3f, -0.1f , -0.02f,
                 .0f, -0.05f, 0.02f,
                 .3f, -0.1f, -0.02f,
                 .6f, -0.2f,  0.02f
          };

    private float color[] = {
        1.0f,0.5f,0.0f,
        1.0f,0.0f,0.5f,
        1.0f,0.8f,0.0f,
        5.0f,1.0f,0.0f,
        0.0f,1.0f,0.5f,
        0.9f,1.0f,0.0f,
        0.5f,0.0f,1.0f,
        0.0f,0.5f,1.0f,
       1.0f,0.5f,0.0f,
        1.0f,0.0f,0.5f,
      };

    public triShape4() {
        FanCount[0] = 5;
        FanCount[1] = 6;
        TriangleFanArray tri = new TriangleFanArray(11, 
             TriangleFanArray.COORDINATES|
                      TriangleFanArray.COLOR_3 , FanCount);
          tri.setCoordinates(0,vert);
          tri.setColors(0,color);
        PolygonAttributes pa = new PolygonAttributes();
          pa.setCullFace(PolygonAttributes.CULL_NONE);
        Appearance ap = new Appearance();
          ap.setPolygonAttributes(pa);
        this.setGeometry(tri);
        this.setAppearance(ap);
        this.setGeometry(tri);
     }
}
//end of triShape4.java

--
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.192.158.112]

--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: sunsoft.bbs@bbs.net.]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:207.235毫秒