Graphics 版 (精华区)

发信人: seaman (翩翩少年), 信区: Graphics
标  题: JAVA3D学习系列(8)--线的生成
发信站: 哈工大紫丁香 (Tue Sep 28 19:10:55 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.hit.edu.cn.[FROM: sunsoft.bbs@bbs.net.]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:209.152毫秒