发信人: vrml() 
整理人: funboy(1999-11-24 09:18:34), 站内信件
 | 
 
 
	JAVA3D学习系列(8)-----直线的生成
 
 
     汕头大学机电系    张杰([email protected])
 
 
 
 
     我们可以利用JAVA3D的一些对象,生成各种直线。
 可以生成直线的对象有:
 1.  LineArray
     LineArray(int vertexCount, int vertexFormat)
 
 2.  LineStripArray 
     LineStripArray(int vertexCount ,int vertexFormat,
 	           int[] stripVertexCounts )
 
 3.  IndexedLineArray
     IndexedLineArray(int vertexCount, int vertexFormat,
 	           int indexCount )
 
 4.  IndexedLineStripArray
     IndexedLineStripArray( int vertexCount, int vertexFormat,
 	           int indexCount, int stripIndexCounts[])
 
 一. 利用LineArray生成直线
     LineArray对象的定义如下:
         LineArray(int vertexCount, int vertexFormat)
     这里:
         vertexCount表示顶点的个数(必须为偶数)
         vertexFormat表示顶点的格式(第七讲有介绍)
 
     由下面的程序我们得知,Line1.java和前面介绍的
 Point4.java几乎完全一样,lineShape1.java和
 pointShape.java也相差不多。运行Line1.java我们获得
 了三条直线,由此得知,LineArray的作用是生成多条直线,
 顶点坐标数组的每一对数据构成一条直线。
     在编写LineArray生成的直线时,要注意,顶点及颜色
 的个数必须相等且为偶数,此数目必须赋值于vertexCount,也即
 程序中的vertexCount必须为偶数且不能少于顶点的个数。
 
    --------------------------  第一条
 
        ----------------        第二条
 
    --------------------------  第三条
 
     我们可以根据各种不同的情况,生成不同的直线,如
 给定宽度的直线、虚线等。相应的的方法有:
     setLineWidth(float lineWidth)
     setLinePattern(int linePattern)
     setLineAntialiasingEnable(boolean state)
     对于线型linePattern有以下数据可选:
       int  PATTERN_SOLID
       int  PATTERN_DASH
       int  PATTERN_DOT
       int  PATTERN_DASH_DOT
     这些内容对所有种类的直线都有效。
 
     前面我们利用PointArray生成了六个点,这里,我们
 将前面的pointShape.java稍微变化一下,则同样的六个点生
 成了三条直线,所用的两个程序为:
 //lineShape1.java
 
 import javax.media.j3d.*;
 
 public class lineShape1 extends Shape3D {
 
     private float vert[] = { 
         .8f, 0.8f,0.0f,
         -0.8f, 0.8f,0.0f,
         0.5f, 0.0f,0.0f,
         -0.5f, 0.0f,0.0f,
         -0.8f,-0.8f,0.0f,
         0.8f,-0.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,
       };
 
     public lineShape1() {
         LineArray line = new LineArray(6, 
                   LineArray.COORDINATES|LineArray.COLOR_3);
           line.setCoordinates(0,vert);
           line.setColors(0,color);
         LineAttributes la = new LineAttributes();
           la.setLineWidth(5.0f);
           la.setLineAntialiasingEnable(true);
         Appearance ap = new Appearance();
          ap.setLineAttributes(la);
         this.setGeometry(line);
         this.setAppearance(ap); 
     }
 }
 //end of lineShape1.java
 ------------------------------------
 //Line1.java  ---using LineArray object
 
 import java.applet.Applet;
 import java.awt.BorderLayout;
 import com.sun.j3d.utils.applet.MainFrame;
 import com.sun.j3d.utils.universe.*;
 import javax.media.j3d.*;
 import javax.vecmath.*;
 
 public class Line1 extends Applet {
 
     private BranchGroup createSceneGraph() {
 	BranchGroup objRoot = new BranchGroup();
         Shape3D shape = new lineShape1();
         objRoot.addChild(shape);
 	objRoot.compile();
 	return objRoot;
     }
 
     public Line1() {
 	setLayout(new BorderLayout());
 	Canvas3D c = new Canvas3D(null);
 	add("Center", c);
 	BranchGroup scene = createSceneGraph();
 	SimpleUniverse u = new SimpleUniverse(c);
         u.getViewingPlatform().setNominalViewingTransform();
 	u.addBranchGraph(scene);
     }
 
     public static void main(String[] args) {
         new MainFrame(new Line1(), 400,400);
     }
 }
 
 //end of Line1.java
 
 
 
 二. 利用LineStripArray生成直线
     LineStripArray可用来生成多条折线段
     LineStripArray对象的定义如下:
         LineStripArray(int vertexCount ,int vertexFormat,
 	               int[] stripVertexCounts )
     这里:
         vertexCount表示顶点的个数(必须为偶数)
         vertexFormat表示顶点的格式(第七讲有介绍)
         stripVertexCounts为一数组,数组里的每一个数值表示
                          每条折线段所拥有的顶点数目。
     下面我们利用lineShape1.java同样的顶点坐标数组及
 颜色数组,用LineStripArray对象生成直线。程序也是两个:
 lineShape2.java、Line2.java,并使生成的直线绕着Y轴旋转,
 直线线型为虚线,线宽为30个像素。
 //lineShape2.java
 
 import javax.media.j3d.*;
 
 public class lineShape2 extends Shape3D {
     int StripCount[] = new int[1];
 
     private float vert[] = { 
         .8f, 0.8f,0.0f,
         -0.8f, 0.8f,0.0f,
         0.5f, 0.0f,0.0f,
         -0.5f, 0.0f,0.0f,
         -0.8f,-0.8f,0.0f,
         0.8f,-0.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,
       };
 
     public lineShape2() {
         StripCount[0] = 6;
 
         LineStripArray line = new LineStripArray(6, 
                   LineStripArray.COORDINATES|
                   LineStripArray.COLOR_3,StripCount);
           line.setCoordinates(0,vert);
           line.setColors(0,color);
         LineAttributes la = new LineAttributes();
           la.setLineWidth(30.0f);
           la.setLineAntialiasingEnable(true);
           la.setLinePattern(LineAttributes.PATTERN_DASH);
         Appearance ap = new Appearance();
          ap.setLineAttributes(la);
         this.setGeometry(line);
         this.setAppearance(ap); 
     }
 }
 
 //end of lineShape2.java
 -----------------------------------------
 //Line2.java
 
 import java.applet.Applet;
 import java.awt.BorderLayout;
 import com.sun.j3d.utils.applet.MainFrame;
 import com.sun.j3d.utils.universe.*;
 import javax.media.j3d.*;
 import javax.vecmath.*;
 
 public class Line2 extends Applet {
 
     private BranchGroup createSceneGraph() {
 	BranchGroup objRoot = new BranchGroup();
         objRoot.addChild(createObject());
 	objRoot.compile();
 	return objRoot;
     }
 
     private Group createObject() {
 	Transform3D t = new Transform3D();
 	TransformGroup objTrans = new TransformGroup(t);
         objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
  
         Shape3D shape = new lineShape2();
 	objTrans.addChild(shape);
 
         Transform3D yAxis = new Transform3D();
         Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
                                         0, 0,
                                         4000, 0, 0,
                                         0, 0, 0);
         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), 50.0);
         rotator.setSchedulingBounds(bounds);
         objTrans.addChild(rotator);
         
 	return objTrans;
     }
 
     public Line2() {
 	setLayout(new BorderLayout());
 	Canvas3D c = new Canvas3D(null);
 	add("Center", c);
 	BranchGroup scene = createSceneGraph();
 	SimpleUniverse u = new SimpleUniverse(c);
         u.getViewingPlatform().setNominalViewingTransform();
         u.addBranchGraph(scene);
     }
 
     public static void main(String[] args) {
         new MainFrame(new Line2(), 400,400);
     }
 }
 
 //end of Line2.java
 
     由上可知,Line2.java这个程序和Point5.java几乎没有
 什么差别,除了类的名字于调用的外部程序名不同之外,其余
 完全相同。
     lineShape1.java和lineShape2.java相差不大,
 lineShape2.java多了一个StripCount数组,它可以用来生成
 多个折线段,下面的lineShape3.java程序就将Line2.java生成
 的一条折线段分成了两条折线段:0、1、2三个点构成了一个折
 线段,3、4、5构成了另一条折线段,每个折线段的顶点数目就
 构成了数组StripCount,StripCount数组的大小等于折线段的
 数目。
 //lineShape3.java
 
 import javax.media.j3d.*;
 
 public class lineShape3 extends Shape3D {
     int StripCount[] = new int[2];
 
     private float vert[] = { 
         .8f, 0.8f,0.0f,
         -0.8f, 0.8f,0.0f,
         0.5f, 0.0f,0.0f,
         -0.5f, 0.0f,0.0f,
         -0.8f,-0.8f,0.0f,
         0.8f,-0.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,
       };
 
     public lineShape3() {
         StripCount[0] = 3;
         StripCount[1] = 3;
 
         LineStripArray line = new LineStripArray(6, 
                   LineStripArray.COORDINATES|
                   LineStripArray.COLOR_3,StripCount);
           line.setCoordinates(0,vert);
           line.setColors(0,color);
         LineAttributes la = new LineAttributes();
           la.setLineWidth(30.0f);
           la.setLineAntialiasingEnable(true);
           la.setLinePattern(LineAttributes.PATTERN_DASH);
         Appearance ap = new Appearance();
          ap.setLineAttributes(la);
         this.setGeometry(line);
         this.setAppearance(ap); 
     }
 }
 
 //end of lineShape3.java
 
     将lineShape3.java生成的绕Y轴旋转的形体用VRML
 程序表示的结果为:
 
 #VRML V2.0 utf8
 DEF T Transform{
   children  Shape {
     geometry IndexedLineSet {
       coord Coordinate {
         point [.8 .8 .0, -.8, .8 0, .5 0 0,
 		-.5 0 0, -.8 -.8 0, .8 -.8 0]}
       coordIndex [0 1 2 -1, 3 4 5 ]		
               #  两个折线段
       color Color{
         color [ .0 .5 1., .5 .0 1, 0 .8 .2,
 		1 0 .3, 0 1 .3, .3 .8 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
 #end of lineShape3.wrl
 
 
 三. 利用IndexedLineArray生成直线
     IndexedLineArray对象的定义为:
     IndexedLineArray(int vertexCount, int vertexFormat,
 	             int indexCount )
     这里:
         vertexCount表示顶点数组里顶点的个数
         vertexFormat表示顶点的格式(第七讲有介绍)
         indexCount表示选用的顶点个数,如果一个点用了
                   几次,则要把几次加进去
         
     在上一节里我们介绍了利用IndexedPoint生成点
 的程序,和IndexedPoint相类似,我们可以利用
 IndexedLineArray生成直线段。
     下面的lineShape4.java利用了IndexedLineArray
 从六个点中挑选了3个点,生成了2条直线。
     从程序中我们可以看到,下标为0的点使用了两次,
 但生成的是两条线,因而参数VertexCount应为4,即
 此处的VertexCount的数值应为直线条数的两倍。
 //lineShape4.java
 
 import javax.media.j3d.*;
 
 public class lineShape4 extends Shape3D {
     int[] index={ 1, 0, 0 , 3, };
     int VertexCount=4;
 
     private float vert[] = { 
         .8f, 0.8f,0.0f,
         -0.8f, 0.8f,0.0f,
         0.5f, 0.0f,0.0f,
         -0.5f, 0.0f,0.0f,
         -0.8f,-0.8f,0.0f,
         0.8f,-0.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,
       };
 
     public lineShape4() {
 
         IndexedLineArray line = new IndexedLineArray(6, 
                   IndexedLineArray.COORDINATES|
                   IndexedLineArray.COLOR_3,VertexCount);
           line.setCoordinates(0,vert);
           line.setColors(0,color);
           line.setCoordinateIndices(0,index);
           line.setColorIndices(0,index);
         LineAttributes la = new LineAttributes();
           la.setLineWidth(30.0f);
           la.setLineAntialiasingEnable(true);
           la.setLinePattern(LineAttributes.PATTERN_DASH);
         Appearance ap = new Appearance();
          ap.setLineAttributes(la);
         this.setGeometry(line);
         this.setAppearance(ap); 
     }
 }
 
 //end of lineShape4.java
 
     将lineShape4.java翻译成VRML的相应程序为:
 
 #VRML V2.0 utf8
 DEF T Transform{
   children  Shape {
     geometry IndexedLineSet {
       coord Coordinate {
         point [.8 .8 .0, -.8, .8 0, .5 0 0,
 		-.5 0 0, -.8 -.8 0, .8 -.8 0]}
       coordIndex [1 0 -1 0 3]
       color Color{
         color [ .0 .5 1., .5 .0 1, 0 .8 .2,
 		1 0 .3, 0 1 .3, .3 .8 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
 
 
 四. 利用IndexedLineStripArray生成直线
     IndexedLineStripArray对象的定义如下:
     IndexedLineStripArray( int vertexCount, int vertexFormat,
 	                   int indexCount, int stripIndexCounts[])
     这里:
         vertexCount表示顶点数组里顶点的个数
         vertexFormat表示顶点的格式(第七讲有介绍)
         indexCount表示选用的顶点的个数
         stripIndexCounts为一数组,数组里的每一个数值表示
                          每条折线段所拥有的顶点数目。
     下面的程序里,我们给出10个顶点,
 
           --0--      --1--
 
           --2--      --3--
 
           --4--      --5--
 
           --6--      --7--
 
           --8--      --9--
 
     然后我们用IndexedLineStripArray生成三个折线段,第一个
 折线段为:0 1 3 2,第二个折线段为3、5、4,第三个折线段为
 6、7、8、6,最后一个点没有用到。所有的直线宽度为30像数。
 这时我们只用了10个点中的9个点,但有2个点用了两次,因而程序
 中的vertexCount为11,
 程序如下:
 //lineShape5.java
 
 import javax.media.j3d.*;
 
 public class lineShape5 extends Shape3D {
     int StripCount[] = new int[3];
     int[] index={ 0 , 1 , 3 , 2 , 3 , 5 ,
                   4 , 6 , 7 , 8 , 6 } ;
        int vertexCount = 11;
     private float vert[] = { 
         -.3f , .8f , .0f,
          .3f , .8f , .0f,
         -.3f , .4f , .0f,
          .3f , .4f , .0f,
         -.3f , .0f , .0f,
          .3f , .0f , .0f,
         -.3f , -.4f , .0f,
          .3f , -.4f , .0f,
         -.3f , -.8f , .0f,
          .3f , -.8f , .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,
         1.0f,0.0f,0.3f
       };
 
     public lineShape5() {
               StripCount[0] = 4;
               StripCount[1] = 3;
               StripCount[2] = 4;
         IndexedLineStripArray line = new IndexedLineStripArray(10 ,
                   IndexedLineStripArray.COORDINATES|
                   IndexedLineStripArray.COLOR_3, vertexCount , StripCo unt);
           line.setCoordinates(0,vert);
           line.setColors(0,color);
                   line.setCoordinateIndices(0,index);
                   line.setColorIndices(0,index);
         LineAttributes la = new LineAttributes();
           la.setLineWidth(30.0f);
           la.setLineAntialiasingEnable(true);
           la.setLinePattern(LineAttributes.PATTERN_DASH);
         Appearance ap = new Appearance();
          ap.setLineAttributes(la);
         this.setGeometry(line);
         this.setAppearance(ap); 
     }
 }
 
 //end of lineShape5.java
  -- ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.192.159.19]
  | 
 
 
 |