BBS水木清华站∶精华区

发信人: vrml (3d), 信区: Java        
标  题: JAVA3D学习系列(13)--形体的组合及几何坐标变换 
发信站: BBS 水木清华站 (Sat Apr 17 21:42:11 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水木清华站∶精华区