Graphics 版 (精华区)
发信人: seaman (翩翩少年), 信区: Graphics
标 题: JAVA3D学习系列(13)--形体的组合及几何坐标变换
发信站: 哈工大紫丁香 (Tue Sep 28 19:15:07 1999), 转信
JAVA3D学习系列(13)---形体的组合及几何坐标变换
汕头大学机电系 张杰(jzhang@mailserv.stu.edu.cn)
****************书名 VRML2.0交互式三维图形编程******
JAVA3D学习系列中的例题将有非常多的VRML程序与之相比较,
介绍JAVA3D的顺序也和VRML2.0新书基本一致,
欢迎购买VRML2.0新书。
特殊购书方式:
1。作者售书
1。网上订购(email address: jzhang@mailserv.stu.edu.cn)
2。可以先获书,后汇款(不满意可退书),
只需将通信地址及邮编告知作者,即可在最短的时间内得到书。
3。书价为25元/本,免收邮购费用。
4。书为16开本,正文161页。
5. 购书可获盖有出版社财务章的收据。
6. 如果需要书中所有的源程序,我可以email一个打包程序
*************书名 VRML2.0交互式三维图形编程******
VRML2.0(VRML97)中,有两个用来组合各形体的组节点:
Transform、Group,其中的Group节点完全可以用Transform
节点来代替。如何在JAVA3D中实现Transform所提供的几何变换
功能,是我们掌握JAVA3D应用编程的基础。下面我们对此给以
详细的介绍。
我们首先来看一下VRML97的Transform节点的定义:
Transform节点的定义是:
Transform {
eventIn MFNode addChildren
eventIn MFNode removeChildren
exposedField SFVec3f center 0 0 0
exposedField MFNode children []
exposedField SFRotation rotation 0 0 1 0
exposedField SFVec3f scale 1 1 1
exposedField SFRotation scaleOrientation 0 0 1 0
exposedField SFVec3f translation 0 0 0
field SFVec3f bboxCenter 0 0 0
field SFVec3f bboxSize -1 -1 -1
}
由定义我们可以看出,VRML程序中,我们可以通过设定
translation、rotation、scale来使形体产生平移、旋转、
比例变换。如VRML2.0交互式三维图形编程一书所给出的一个
生成一个小丑的程序Ex4_03.wrl,里面就对形体进行了平移、
旋转、比例变换。我们先给出Ex4_03.wrl程序(我们对
书中的程序进行了修改,使生成的小丑能够旋转),再给出
用JAVA3D编写出来的Ex4_03.java。
//Ex4_03.wrl
#VRML V2.0 utf8
DEF T Transform{
children[
Transform {
scale 1 1.2 1
children Shape {
appearance Appearance{material Material
{diffuseColor 1 1 0 }}
geometry Sphere{}}}
Transform{
translation .5 .4 .6
scale 1 1 2
children Shape{
appearance Appearance{material Material
{diffuseColor 0 0 1}}
geometry Sphere{radius .2}}}
Transform {
translation -.5 .4 .6
scale 1 1 2
children Shape{
appearance Appearance{material Material
{diffuseColor 0 0 1}}
geometry Sphere {radius .2}}}
Transform{
translation 0 1 0
scale 1.1 .4 1.1
children Shape{
appearance Appearance{material Material
{diffuseColor 1 0 0}}
geometry Cone{}}}
Transform{
translation 1 0 0
scale .2 .4 .2
children Shape{
appearance Appearance{material Material
{diffuseColor 0 1 1}}
geometry Sphere{}}}
Transform{
translation -1 0 0
scale .2 .4 .2
children Shape{
appearance Appearance{material Material
{diffuseColor 0 1 1}}
geometry Sphere{}}}
Transform{
translation 0 0 1
scale .2 .4 .2
rotation 1 0 0 -.5
children Shape{
appearance Appearance{material Material
{diffuseColor 1 0 0}}
geometry Sphere{}}}
Transform{
translation 0 -.5 .9
scale .4 .1 .3
children Shape{
appearance Appearance{material Material
{diffuseColor 1 1 1}}
geometry Sphere{}}}
]}
DEF TS TimeSensor{
cycleInterval 8
loop TRUE}
DEF OI OrientationInterpolator{
key [0 .25 .5 .75 1]
keyValue [0 1 0 0, 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
Background {skyColor 1 1 1}
//end of Ex4_03.wrl
------------------------------
//Ex4_03.java
import java.applet.Applet;
import java.awt.BorderLayout;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.Cone;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.geometry.Primitive;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
public class Ex4_03 extends Applet{
public BranchGroup createSceneGraph() {
BranchGroup objRoot = new BranchGroup();
Transform3D t3d = new Transform3D();
t3d.setScale(0.3);
TransformGroup objScale = new TransformGroup();
objScale.setTransform(t3d);
Transform3D temp = new Transform3D();
TransformGroup obj = new TransformGroup();
obj.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
obj.setTransform(temp);
objScale.addChild(obj);
Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
0, 0,
4000, 0, 0,
0, 0, 0);
RotationInterpolator rotator =
new RotationInterpolator(rotationAlpha, obj, temp,
0.0f, (float) Math.PI*2.0f);
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
rotator.setSchedulingBounds(bounds);
obj.addChild(rotator);
objRoot.addChild(objScale);
Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -12.0f);
DirectionalLight light1
= new DirectionalLight(light1Color, light1Direction);
light1.setInfluencingBounds(bounds);
objRoot.addChild(light1);
Appearance app_red = new Appearance();
Material material1 = new Material();
material1.setDiffuseColor(new Color3f(1.0f,0.0f,0.0f));
app_red.setMaterial(material1);
Appearance app_yellow = new Appearance();
Material material2 = new Material();
material2.setDiffuseColor(new Color3f(1.0f,1.0f,0.0f));
app_yellow.setMaterial(material2);
Appearance app_blue = new Appearance();
Material material3 = new Material();
material3.setDiffuseColor(new Color3f(0.0f,0.0f,1.0f));
app_blue.setMaterial(material3);
Appearance app_cyan = new Appearance();
Material material4 = new Material();
material4.setDiffuseColor(new Color3f(0.0f,1.0f,1.0f));
app_cyan.setMaterial(material4);
Appearance app_white = new Appearance();
Material material5 = new Material();
material5.setDiffuseColor(new Color3f(1.0f,1.0f,1.0f));
app_white.setMaterial(material5);
Cone c = new Cone(1.0f,2.0f,1,app_red);
Primitive s_1 = (Primitive) new Sphere(1.0f,app_yellow);
Primitive s_2 = (Primitive) new Sphere(.2f ,app_blue);
Primitive s_2b = (Primitive) new Sphere(.2f ,app_blue);
Primitive s_3 = (Primitive) new Sphere(1.0f,app_cyan);
Primitive s_3b = (Primitive) new Sphere(1.0f,app_cyan);
Primitive s_4 = (Primitive) new Sphere(1.0f,app_red);
Primitive s_5 = (Primitive) new Sphere(1.0f,app_white);
Transform3D t1 = new Transform3D();
t1.setScale(new Vector3d(1,1.2,1));
TransformGroup objTrans1 = new TransformGroup(t1);
objTrans1.addChild(s_1);
Transform3D t2 = new Transform3D();
t2.setScale(new Vector3d(1,1,2));
t2.setTranslation(new Vector3f(0.5f, 0.4f, 0.6f));
TransformGroup objTrans2 = new TransformGroup(t2);
objTrans2.addChild(s_2);
Transform3D t3 = new Transform3D();
t3.setScale(new Vector3d(1,1,2));
t3.setTranslation(new Vector3f(-0.5f, 0.4f, 0.6f));
TransformGroup objTrans3 = new TransformGroup(t3);
objTrans3.addChild(s_2b);
Transform3D t4 = new Transform3D();
t4.setScale(new Vector3d(1.1,0.4,1.1));
t4.setTranslation(new Vector3f(0.0f, 1.0f, 0.0f));
TransformGroup objTrans4 = new TransformGroup(t4);
objTrans4.addChild(c);
Transform3D t5 = new Transform3D();
t5.setScale(new Vector3d(0.2, 0.4, 0.2));
t5.setTranslation(new Vector3f(1.0f, 0.0f, 0.0f));
TransformGroup objTrans5 = new TransformGroup(t5);
objTrans5.addChild(s_3);
Transform3D t6 = new Transform3D();
t6.setScale(new Vector3d(0.2, 0.4, 0.2));
t6.setTranslation(new Vector3f(-1.0f, 0.0f, 0.0f));
TransformGroup objTrans6 = new TransformGroup(t6);
objTrans6.addChild(s_3b);
Transform3D t7 = new Transform3D();
t7.setScale(new Vector3d(0.2, 0.4, 0.2));
t7.setTranslation(new Vector3f(0.0f, 0.0f, 1.0f));
TransformGroup objTrans7 = new TransformGroup(t7);
objTrans7.addChild(s_4);
Transform3D t8 = new Transform3D();
t8.setScale(new Vector3d(0.4, 0.1, 0.3));
t8.setTranslation(new Vector3f(0.0f, -0.5f, 0.9f));
TransformGroup objTrans8 = new TransformGroup(t8);
objTrans8.addChild(s_5);
Color3f bgColor = new Color3f(1.0f, 1.0f, 1.0f);
Background bg = new Background(bgColor);
bg.setApplicationBounds(bounds);
objRoot.addChild(bg);
obj.addChild(objTrans1);
obj.addChild(objTrans2);
obj.addChild(objTrans3);
obj.addChild(objTrans4);
obj.addChild(objTrans5);
obj.addChild(objTrans6);
obj.addChild(objTrans7);
obj.addChild(objTrans8);
objRoot.compile();
return objRoot;
}
public Ex4_03() {
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 Ex4_03(), 640, 480);
}
}
//end of Ex4_03.java
我们来仔细研究JAVA3D所提供的形体几何变换功能。
前面我们主要介绍形体生成的方法,其中,编写自己的形体
用到的是Shape3D对象,VRML97与之对应的是Shape节点。
同样,JAVA3D对应于VRML97的Transform节点的对象是Transform3D。
VRML97编程中,形体的平移可以通过Transform节点的
translation字段来设置;JAVA3D编程时,形体的平移可以通过
Transform3D的setTranslation方法完成。
VRML97编程中,形体的旋转可以通过Transform节点的
rotation字段来设置;JAVA3D编程时,形体的旋转可以通过
Transform3D的setRotation方法完成。
VRML97编程中,形体的比例变化可以通过Transform节点的
scale字段来设置;JAVA3D编程时,形体的比例变化可以通过
Transform3D的setScale方法完成,其中,当扩弧里只有一个双
精度数时,setScale对所有的方向均采用同一个比例,而当里面
有三个双精度数时,setScale对不同的方向可以采用不同的比例,
双精度数后面不加符号,而单精度浮点数后面要加一个f。
我们来看一下程序的主要内容:
程序一开始就定义了一个BranchGroup,后面所有的生成的内容
如形体、形体的变换、背景、灯光都放入其中。
为了使我们生成的图形有合适的大小,我们定义了一个
TransformGroup对象objScale,通过一个t3d使其按比例缩小,这
相当于我们将视野往后移动。
为了使我们生成的小丑能够旋转,我们定义一个TransformGroup
类型的obj,这相当于定义了一个小丑所在的局部坐标系,设定此
坐标系可以旋转,选转方式由一个Transform3D类型的temp来确定,
定义obj为objScale的一个子节点。
通过定义rotationAlpha、rotator地定义使得obj能够产生旋转。
它们的作用类似于VRML的时间传感器及方向内插器。
接下来我们在空间中定义了一个定向光、各种材质、形体,并
将灯光、具有一定材质的形体放入objRoot、obj之中,最后我们
还定义了一个背景光。
通过这个程序的编写,我们掌握了JAVA3D生成复杂形体的最基本
概念,即如何进行形体的几何坐标变换。掌握了形体几何坐标变换
方法,我们就具有了编写JAVA3D复杂应用程序的能力。
--
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.192.158.172]
--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: sunsoft.bbs@bbs.net.]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:206.932毫秒