发信人: vrml() 
整理人: funboy(1999-11-24 09:18:18), 站内信件
 | 
 
 
	JAVA3D学习系列(9)----- 面的生成(上)
 
 
     汕头大学机电系    张杰([email protected])
 
 一. 生成平面的对象及其定义
     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
  -- ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.192.159.19]
  | 
 
 
 |