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