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毫秒