发信人: vrml() 
整理人: (1999-11-24 09:12:48), 站内信件
 | 
 
 
       JAVA3D学习系列(13)---形体的组合及几何坐标变换
 
 
 
 
     汕头大学机电系    张杰([email protected])
 
 ****************书名  VRML2.0交互式三维图形编程******
 JAVA3D学习系列中的例题将有非常多的VRML程序与之相比较,
 介绍JAVA3D的顺序也和VRML2.0新书基本一致,
 欢迎购买VRML2.0新书。
 特殊购书方式:
 1。作者售书
 1。网上订购(email address: [email protected])
 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复杂应用程序的能力。
  -- ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.192.159.19]
  | 
 
 
 |