- 前言
- 坐标对应关系
- 加一个面
鉴于许多同学对计算机图形学设计作品无法下手,特此推出Java3D设计作品入门级教程,可以给予毫无头绪的你一点思路。本文仅起到抛砖引玉的作用,并不提供现成的作品。
坐标对应关系首先我们要理解java3d中的坐标轴,这个坐标轴与我们平常摆的位置的不太一样,所以要做下区分
然后我们把这个坐标轴代入到我们真实的环境中,代码及运行结果如下:
package com.test.demo01; import java.applet.Applet; import java.awt.*; import com.sun.j3d.utils.applet.Mainframe; import com.sun.j3d.utils.geometry.*; import com.sun.j3d.utils.universe.*; import javax.media.j3d.*; import javax.vecmath.*; import com.sun.j3d.utils.behaviors.mouse.*; public class BezierSurfaceMerging extends Applet {public BranchGroup createBranchGroupSceneGraph() {BranchGroup BranchGroupRoot =new BranchGroup(); BoundingSphere bounds=new BoundingSphere(new Point3d(0.0,0.0,0.0),100.0); Color3f bgColor=new Color3f(0f,1.0f,1.0f); Background bg=new Background(bgColor); bg.setApplicationBounds(bounds); BranchGroupRoot.addChild(bg); Color3f directionalColor=new Color3f(1.f,0.f,0.f); Vector3f vec=new Vector3f(0.f,0.f,-1.0f); DirectionalLight directionalLight=new DirectionalLight(directionalColor,vec); directionalLight.setInfluencingBounds(bounds); BranchGroupRoot.addChild(directionalLight); Transform3D tr=new Transform3D(); tr.setScale(0.85); TransformGroup transformgroup=new TransformGroup(tr); transformgroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); transformgroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); BranchGroupRoot.addChild(transformgroup); MouseRotate mouserotate = new MouseRotate(); mouserotate.setTransformGroup(transformgroup); BranchGroupRoot.addChild(mouserotate); mouserotate.setSchedulingBounds(bounds); MouseZoom mousezoom = new MouseZoom(); mousezoom.setTransformGroup(transformgroup); BranchGroupRoot.addChild(mousezoom); mousezoom.setSchedulingBounds(bounds); MouseTranslate mousetranslate = new MouseTranslate(); mousetranslate.setTransformGroup(transformgroup); BranchGroupRoot.addChild(mousetranslate); mousetranslate.setSchedulingBounds(bounds); //定义第一个Bezier曲面的16个控制顶点 float[][][] P1={{{-0.8f,0.9f,-0.4f,1.f}, {-0.2f,0.8f,-0.5f,1.f}, {0.2f,0.9f,-0.4f,1.f}, {0.8f,0.8f,-0.5f,1.f} }, { {-0.8f,0.7f,-0.4f,1.f}, {-0.2f,0.6f,0.9f,1.f}, {0.2f,0.7f,0.8f,1.f}, {0.8f,0.6f,-0.4f,1.f} }, {{-0.8f,0.4f,-0.4f,1.f}, {-0.2f,0.5f,0.8f,1.f}, {0.2f,0.3f,0.7f,1.f}, {0.8f,0.4f,-0.5f,1.f} }, { {-0.8f,0.f,-0.8f,1.f}, {-0.2f,0.1f,0.9f,1.f}, {0.2f,0.f,-0.8f,1.f}, {0.8f,0.1f,0.9f,1.f} } }; //定义第一个Bezier曲面外观属性 Appearance app1 = new Appearance(); PolygonAttributes polygona1=new PolygonAttributes(); polygona1.setBackFaceNormalFlip(true); polygona1.setCullFace(PolygonAttributes.CULL_NONE); // polygona1.setPolygonMode(PolygonAttributes.POLYGON_LINE); app1.setPolygonAttributes(polygona1); ColoringAttributes color1=new ColoringAttributes(); color1.setColor(1.f,0.f,0.f); app1.setColoringAttributes(color1); Shape3D BezierSurfaceface1=new BezierThreeOrderSurfaceface(P1,app1); transformgroup.addChild(BezierSurfaceface1); BranchGroupRoot.compile(); return BranchGroupRoot; } public BezierSurfaceMerging() {setLayout(new BorderLayout()); GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration(); Canvas3D c=new Canvas3D(gc); add("Center",c); BranchGroup BranchGroupScene=createBranchGroupSceneGraph(); SimpleUniverse u=new SimpleUniverse(c); u.getViewingPlatform().setNominalViewingTransform(); u.addBranchGraph(BranchGroupScene); } public static void main(String[] args) {new Mainframe(new BezierSurfaceMerging(),400,400); } } class BezierThreeOrderSurfaceface extends Shape3D {public BezierThreeOrderSurfaceface(float[][][] P,Appearance app) {int i,j,k; int n0;//定义对参数u、v在[0,1]区间的等分点数 float division;//参数u在[0,1]区间的等分线段长度 n0=50;division=1.f/n0; //分别定义存放控制顶点x、y、z坐标与第四维坐标的数组 float[][] PX=new float[4][4]; float[][] PY=new float[4][4]; float[][] PZ=new float[4][4]; float[][] P4=new float[4][4]; //定义系数矩阵及其转置矩阵 float[][] M1={{1.f,0.f,0.f,0.f}, {-3.f,3.f,0.f,0.f}, {3.f,-6.f,3.f,0.f}, {-1.f,3.f,-3.f,1.f}}; float[][] M2={{1.f,-3.f,3.f,-1.f}, {0.f,3.f,-6.f,3.f}, {0.f,0.f,3.f,-3.f}, {0.f,0.f,0.f,1.f}}; //定义Bezier曲面的u、v参数分割点坐标数组 float[][][] UV=new float[n0+1][n0+1][2]; //定义U、V矩阵数组 float[][] UU=new float[1][4]; float[][] VV=new float[4][1]; //定义存放曲面上点的坐标的数组 float[][][] SurfaceXYZ=new float[n0+1][n0+1][4]; for(i=0;i
在这一长段代码中,只有P1的这16个坐标是我们要改动的地方,这16个的坐标共同组成了一个曲面。每个点包含了4个坐标,但其中的1.f我们是不需要去动的,因此真正有用的是前三个
{X, Y, Z, 1.f}
这里的XYZ就分别对应到上述提到的坐标轴中,那么理解了坐标是怎么使用后,还要将坐标对应到曲面中。为了方便演示,我们将P1中的坐标改成如下:
float[][][] P1={ {{-0.8f, -1.2f, -0.8f, 1.f}, {-0.2f, 0.2f, -0.5f, 1.f}, {0.2f, 0.3f, -0.5f, 1.f}, {0.8f, -1.2f, -0.8f, 1.f}}, {{-0.8f, -0.1f, -0.2f, 1.f}, {-0.2f, 0.9f, -0.2f, 1.f}, {0.2f, 0.9f, -0.2f, 1.f}, {0.8f, -0.1f, -0.2f, 1.f}}, {{-0.8f, -0.1f, 0.2f, 1.f}, {-0.2f, 0.9f, 0.2f, 1.f}, {0.2f, 0.9f, 0.2f, 1.f}, {0.8f, -0.1f, 0.2f, 1.f}}, {{-0.6f, -0.6f, 0.9f, 1.f}, {-0.2f, 0.2f, 0.5f, 1.f}, {0.2f, 0.3f, 0.5f, 1.f}, {0.6f, -0.65f, 0.8f, 1.f}}};运行我们的代码,得到如下结果:
到这步后,我们要把最前面提到的坐标轴,与这张图相结合。这里注意一下,为了避免把自己搞混乱,运行出结果后就不要随便去转动它!!!第一印象很重要。
这就是在这张图中代表的坐标系(上下位置不一定准确)
我们的重头戏要来了,这16个点分别代表图中的哪个位置,因为这个图像凹凸有致,我们很容易想到去调整它的Y坐标,来得到最佳的观察效果。
我们将这里的坐标分别4组,从上至下,从左至右,依次记为1,2,3……16
首先我们将第一个点的Y坐标改为0,观察效果
可以看到已经有了一定的变化,随后我们转动图像,以俯视的视角,也就是想象自己飞到了图像的上方。
可以看到图形的这一角比较特别,相比较原先有点翘起,归根结底就是我们把第一个点的纵坐标由-1.2f变为了0f,产生了这个效果。有兴趣的同学可以再把它改成-1.2f,就会得到如下 结果:
我们依葫芦画瓢,把这16个点都改一遍,也就是只把它们的Y坐标改为0,分别会得到以下结果(均采用了俯视的视角):
到这里,我们第一组的坐标全部测试完毕了,相信大家一定对坐标和曲面之间的对应关系有了一定的了解。现在我们再测一下每组的第一个点,同样修改其Y坐标
自己都试一遍印象才能深刻噢!接着我们看看把全部的Y坐标归0的结果
可以看到打开的时候已经变成了一个平面了,不再是曲面,这也给了 我们一个构造平面的思路,也就是把16个的坐标的XYZ任意一个全部设置为0,就可以得到平面。当然学到这里,你已经掌握了一个曲面是如何运转的,然而我们的作品肯定不是只由一个曲面就能完成,除非你看开了。
加一个面接下来我们将详细分析一下,自己如何再加一个曲面
添加如下代码, 这里的P2是由P1的Y坐标修改为0.5f得来,也就是把整个面往上抬了0.5f的距离,可以先在脑海中想想会是什么样子再往下滑,建立空间感
float[][][] P2={ {{-0.8f, 0.5f, -0.8f, 1.f}, {-0.2f, 0.5f, -0.5f, 1.f}, {0.2f, 0.5f, -0.5f, 1.f}, {0.8f, 0.5f, -0.8f, 1.f}}, {{-0.8f, 0.5f, -0.2f, 1.f}, {-0.2f, 0.5f, -0.2f, 1.f}, {0.2f, 0.5f, -0.2f, 1.f}, {0.8f, 0.5f, -0.2f, 1.f}}, {{-0.8f, 0.5f, 0.2f, 1.f}, {-0.2f, 0.5f, 0.2f, 1.f}, {0.2f, 0.5f, 0.2f, 1.f}, {0.8f, 0.5f, 0.2f, 1.f}}, {{-0.6f, 0.5f, 0.9f, 1.f}, {-0.2f, 0.5f, 0.5f, 1.f}, {0.2f, 0.5f, 0.5f, 1.f}, {0.6f, 0.5f, 0.8f, 1.f}}}; //定义第一个Bezier曲面外观属性 Appearance app2 = new Appearance(); PolygonAttributes polygona2=new PolygonAttributes(); polygona2.setBackFaceNormalFlip(true); polygona2.setCullFace(PolygonAttributes.CULL_NONE); polygona2.setPolygonMode(PolygonAttributes.POLYGON_LINE); app2.setPolygonAttributes(polygona2); ColoringAttributes color2=new ColoringAttributes(); color2.setColor(0.8f,0.f,0.f); app2.setColoringAttributes(color2); Shape3D BezierSurfaceface2=new BezierThreeOrderSurfaceface(P2,app2); transformgroup.addChild(BezierSurfaceface2);说说要改的地方,P2 app2 polygona2 color2 BezierSurfaceface2
这里都由原先的1改为了2,要是想添加3个,4个,10个,100个,也是以此类推。
效果如下:
看到这里,相信你一定已经会意了
小练习:可以先动手试试如何用6个曲面拼成一个方块
本次教程就到这里了,快去完成自己的设计作品吧!
4班冲!package com.test.demo01; import java.applet.Applet; import java.awt.*; import com.sun.j3d.utils.applet.Mainframe; import com.sun.j3d.utils.geometry.*; import com.sun.j3d.utils.universe.*; import javax.media.j3d.*; import javax.vecmath.*; import com.sun.j3d.utils.behaviors.mouse.*; public class BezierSurfaceMerging extends Applet {public BranchGroup createBranchGroupSceneGraph() {BranchGroup BranchGroupRoot =new BranchGroup(); BoundingSphere bounds=new BoundingSphere(new Point3d(0.0,0.0,0.0),100.0); Color3f bgColor=new Color3f(0f,1.0f,1.0f); Background bg=new Background(bgColor); bg.setApplicationBounds(bounds); BranchGroupRoot.addChild(bg); Color3f directionalColor=new Color3f(1.f,0.f,0.f); Vector3f vec=new Vector3f(0.f,0.f,-1.0f); DirectionalLight directionalLight=new DirectionalLight(directionalColor,vec); directionalLight.setInfluencingBounds(bounds); BranchGroupRoot.addChild(directionalLight); Transform3D tr=new Transform3D(); tr.setScale(0.85); TransformGroup transformgroup=new TransformGroup(tr); transformgroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); transformgroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); BranchGroupRoot.addChild(transformgroup); MouseRotate mouserotate = new MouseRotate(); mouserotate.setTransformGroup(transformgroup); BranchGroupRoot.addChild(mouserotate); mouserotate.setSchedulingBounds(bounds); MouseZoom mousezoom = new MouseZoom(); mousezoom.setTransformGroup(transformgroup); BranchGroupRoot.addChild(mousezoom); mousezoom.setSchedulingBounds(bounds); MouseTranslate mousetranslate = new MouseTranslate(); mousetranslate.setTransformGroup(transformgroup); BranchGroupRoot.addChild(mousetranslate); mousetranslate.setSchedulingBounds(bounds); //定义第一个Bezier曲面的16个控制顶点 float[][][] P1={ {{-0.8f, 0f, -0.8f, 1.f}, {-0.2f, 0f, -0.5f, 1.f}, {0.2f, 0f, -0.5f, 1.f}, {0.8f, 0f, -0.8f, 1.f}}, {{-0.8f, 0f, -0.2f, 1.f}, {-0.2f, 0f, -0.2f, 1.f}, {0.2f, 0f, -0.2f, 1.f}, {0.8f, 0f, -0.2f, 1.f}}, {{-0.8f, 0f, 0.2f, 1.f}, {-0.2f, 0f, 0.2f, 1.f}, {0.2f, 0f, 0.2f, 1.f}, {0.8f, 0f, 0.2f, 1.f}}, {{-0.6f, 0f, 0.9f, 1.f}, {-0.2f, 0f, 0.5f, 1.f}, {0.2f, 0f, 0.5f, 1.f}, {0.6f, 0f, 0.8f, 1.f}}}; //定义第一个Bezier曲面外观属性 Appearance app1 = new Appearance(); PolygonAttributes polygona1=new PolygonAttributes(); polygona1.setBackFaceNormalFlip(true); polygona1.setCullFace(PolygonAttributes.CULL_NONE); polygona1.setPolygonMode(PolygonAttributes.POLYGON_LINE); app1.setPolygonAttributes(polygona1); ColoringAttributes color1=new ColoringAttributes(); color1.setColor(0.8f,0.f,0.f); app1.setColoringAttributes(color1); float[][][] P2={ {{-0.8f, 0.5f, -0.8f, 1.f}, {-0.2f, 0.5f, -0.5f, 1.f}, {0.2f, 0.5f, -0.5f, 1.f}, {0.8f, 0.5f, -0.8f, 1.f}}, {{-0.8f, 0.5f, -0.2f, 1.f}, {-0.2f, 0.5f, -0.2f, 1.f}, {0.2f, 0.5f, -0.2f, 1.f}, {0.8f, 0.5f, -0.2f, 1.f}}, {{-0.8f, 0.5f, 0.2f, 1.f}, {-0.2f, 0.5f, 0.2f, 1.f}, {0.2f, 0.5f, 0.2f, 1.f}, {0.8f, 0.5f, 0.2f, 1.f}}, {{-0.6f, 0.5f, 0.9f, 1.f}, {-0.2f, 0.5f, 0.5f, 1.f}, {0.2f, 0.5f, 0.5f, 1.f}, {0.6f, 0.5f, 0.8f, 1.f}}}; //定义第一个Bezier曲面外观属性 Appearance app2 = new Appearance(); PolygonAttributes polygona2=new PolygonAttributes(); polygona2.setBackFaceNormalFlip(true); polygona2.setCullFace(PolygonAttributes.CULL_NONE); polygona2.setPolygonMode(PolygonAttributes.POLYGON_LINE); app2.setPolygonAttributes(polygona2); ColoringAttributes color2=new ColoringAttributes(); color2.setColor(0.8f,0.f,0.f); app2.setColoringAttributes(color2); Shape3D BezierSurfaceface2=new BezierThreeOrderSurfaceface(P2,app2); transformgroup.addChild(BezierSurfaceface2); Shape3D BezierSurfaceface1=new BezierThreeOrderSurfaceface(P1,app1); transformgroup.addChild(BezierSurfaceface1); BranchGroupRoot.compile(); return BranchGroupRoot; } public BezierSurfaceMerging() {setLayout(new BorderLayout()); GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration(); Canvas3D c=new Canvas3D(gc); add("Center",c); BranchGroup BranchGroupScene=createBranchGroupSceneGraph(); SimpleUniverse u=new SimpleUniverse(c); u.getViewingPlatform().setNominalViewingTransform(); u.addBranchGraph(BranchGroupScene); } public static void main(String[] args) {new Mainframe(new BezierSurfaceMerging(),400,400); } } class BezierThreeOrderSurfaceface extends Shape3D {public BezierThreeOrderSurfaceface(float[][][] P,Appearance app) {int i,j,k; int n0;//定义对参数u、v在[0,1]区间的等分点数 float division;//参数u在[0,1]区间的等分线段长度 n0=50;division=1.f/n0; //分别定义存放控制顶点x、y、z坐标与第四维坐标的数组 float[][] PX=new float[4][4]; float[][] PY=new float[4][4]; float[][] PZ=new float[4][4]; float[][] P4=new float[4][4]; //定义系数矩阵及其转置矩阵 float[][] M1={{1.f,0.f,0.f,0.f}, {-3.f,3.f,0.f,0.f}, {3.f,-6.f,3.f,0.f}, {-1.f,3.f,-3.f,1.f}}; float[][] M2={{1.f,-3.f,3.f,-1.f}, {0.f,3.f,-6.f,3.f}, {0.f,0.f,3.f,-3.f}, {0.f,0.f,0.f,1.f}}; //定义Bezier曲面的u、v参数分割点坐标数组 float[][][] UV=new float[n0+1][n0+1][2]; //定义U、V矩阵数组 float[][] UU=new float[1][4]; float[][] VV=new float[4][1]; //定义存放曲面上点的坐标的数组 float[][][] SurfaceXYZ=new float[n0+1][n0+1][4]; for(i=0;i欢迎分享,转载请注明来源:内存溢出
评论列表(0条)