BBS水木清华站∶精华区

发信人: vrml (3d), 信区: Java        
标  题: JAVA3D学习系列(8)--线的生成 
发信站: BBS 水木清华站 (Thu Apr  8 10:38:11 1999) 
 
        JAVA3D学习系列(8)-----直线的生成 
 
 
    汕头大学机电系    张杰(jzhang@mailserv.stu.edu.cn) 
 
 
 
 
    我们可以利用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 , StripCount); 
          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 
 
-- 
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.192.158.112] 

BBS水木清华站∶精华区