Java3D设计作品入门级教程

点击此处,获取更良好的阅读体验

文章目录

  • 前言
  • 坐标对应关系
  • 加一个面

前言

鉴于许多同学对计算机图形学设计作品无法下手,特此推出Java3D设计作品入门级教程,可以给予毫无头绪的你一点思路。本文仅起到抛砖引玉的作用,并不提供现成的作品。

坐标对应关系

首先我们要理解java3d中的坐标轴,这个坐标轴与我们平常摆的位置的不太一样,所以要做下区分

Java3D设计作品入门级教程_第1张图片

然后我们把这个坐标轴代入到我们真实的环境中,代码及运行结果如下:

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<n0+1;i++)
        for(j=0;j<n0+1;j++)
        { 	UV[i][j][0]=i*division;
            UV[i][j][1]=j*division;   }
    for(i=0;i<4;i++)
        for(j=0;j<4;j++)
        { PX[i][j]=P[i][j][0];
            PY[i][j]=P[i][j][1];
            PZ[i][j]=P[i][j][2];
            P4[i][j]=P[i][j][3]; }
//计算曲面上点的坐标值
    for(i=0;i<n0+1;i++)
        for(j=0;j<n0+1;j++)
        {   UU[0][0]=1.f;
            UU[0][1]=UV[i][j][0];
            UU[0][2]=UV[i][j][0]*UV[i][j][0];
            UU[0][3]=UV[i][j][0]*UV[i][j][0]*UV[i][j][0];
            VV[0][0]=1.f;
            VV[1][0]=UV[i][j][1];
            VV[2][0]=UV[i][j][1]*UV[i][j][1];
            VV[3][0]=UV[i][j][1]*UV[i][j][1]*UV[i][j][1];
            //计算一点的x坐标
            matrixm g0=new matrixm(1,4,4,UU,M1);
            matrixm g1=new matrixm(1,4,4,g0.CC,PX);
            matrixm g2=new matrixm(1,4,4,g1.CC,M2);
            matrixm g3=new matrixm(1,4,1,g2.CC,VV);
            SurfaceXYZ[i][j][0]=g3.CC[0][0];
            //计算一点的y坐标
            matrixm g4=new matrixm(1,4,4,UU,M1);
            matrixm g5=new matrixm(1,4,4,g4.CC,PY);
            matrixm g6=new matrixm(1,4,4,g5.CC,M2);
            matrixm g7=new matrixm(1,4,1,g6.CC,VV);
            SurfaceXYZ[i][j][1]=g7.CC[0][0];
            //计算一点的z坐标
            matrixm g8=new matrixm(1,4,4,UU,M1);
            matrixm g9=new matrixm(1,4,4,g8.CC,PZ);
            matrixm g10=new matrixm(1,4,4,g9.CC,M2);
            matrixm g11=new matrixm(1,4,1,g10.CC,VV);
            SurfaceXYZ[i][j][2]=g11.CC[0][0];
            //计算一点的第4维坐标
            matrixm g12=new matrixm(1,4,4,UU,M1);
            matrixm g13=new matrixm(1,4,4,g12.CC,P4);
            matrixm g14=new matrixm(1,4,4,g13.CC,M2);
            matrixm g15=new matrixm(1,4,1,g14.CC,VV);
            SurfaceXYZ[i][j][3]=g15.CC[0][0];
            //将齐次坐标转换为三维坐标系坐标,如果第4维为1,则不用除第4维
            SurfaceXYZ[i][j][0]=SurfaceXYZ[i][j][0]/SurfaceXYZ[i][j][3];
            SurfaceXYZ[i][j][1]=SurfaceXYZ[i][j][1]/SurfaceXYZ[i][j][3];
            SurfaceXYZ[i][j][2]=SurfaceXYZ[i][j][2]/SurfaceXYZ[i][j][3];
        }
    QuadArray BezierQuadsurfaceface = new QuadArray(n0*n0*4,
            GeometryArray.COORDINATES|GeometryArray.NORMALS);
    int c=0;//以顶点数累加的方式设置顶点的序号
    for(i=0;i<n0;i++)
    {for(j=0;j<n0;j++)
    {//设置一个平面上的4个点
        Point3f A=new Point3f(SurfaceXYZ[i][j][0],SurfaceXYZ[i][j][1],
                SurfaceXYZ[i][j][2]);
        Point3f B=new Point3f(SurfaceXYZ[i][j+1][0],SurfaceXYZ[i][j+1][1],
                SurfaceXYZ[i][j+1][2]);
        Point3f C=new Point3f(SurfaceXYZ[i+1][j+1][0],SurfaceXYZ[i+1][j+1][1],
                SurfaceXYZ[i+1][j+1][2]);
        Point3f D=new Point3f(SurfaceXYZ[i+1][j][0],SurfaceXYZ[i+1][j][1],
                SurfaceXYZ[i+1][j][2]);
//计算由四个点形成的平面的法向量
        Vector3f a = new Vector3f(A.x - B.x, A.y - B.y, A.z - B.z);
        Vector3f b = new Vector3f(C.x - B.x, C.y - B.y, C.z - B.z);
        Vector3f n = new Vector3f();
        n.cross(b, a);
        n.normalize();
//设置点的序号
        BezierQuadsurfaceface.setCoordinate(c, A);
        BezierQuadsurfaceface.setCoordinate(c+1, B);
        BezierQuadsurfaceface.setCoordinate(c+2, C);
        BezierQuadsurfaceface.setCoordinate(c+3, D);
//设置点的法向量
        BezierQuadsurfaceface.setNormal(c, n);
        BezierQuadsurfaceface.setNormal(c+1, n);
        BezierQuadsurfaceface.setNormal(c+2, n);
        BezierQuadsurfaceface.setNormal(c+3, n);
        c=c+4;
    }}
    this.addGeometry(BezierQuadsurfaceface);
    this.setAppearance(app);
}}
class  BezierSurfaceControlPoints extends Shape3D
{public BezierSurfaceControlPoints(float[][][] P,Appearance app)
{int i,j,k;
    QuadArray BeziersurfacecontrolPointsNet =new QuadArray(3*3*4,
            GeometryArray.COORDINATES|GeometryArray.NORMALS);
    int c=0;
    for(i=0;i<3;i++)
    {for(j=0;j<3;j++)
    {Point3f A=new Point3f(P[i][j][0],P[i][j][1],P[i][j][2]);
        Point3f B=new Point3f(P[i][j+1][0],P[i][j+1][1],P[i][j+1][2]);
        Point3f C=new Point3f(P[i+1][j+1][0],P[i+1][j+1][1],P[i+1][j+1][2]);
        Point3f D=new Point3f(P[i+1][j][0],P[i+1][j][1],P[i+1][j][2]);
        Vector3f a = new Vector3f(A.x - B.x, A.y - B.y, A.z - B.z);
        Vector3f b = new Vector3f(C.x - B.x, C.y - B.y, C.z - B.z);
        Vector3f n = new Vector3f();
        n.cross(b, a);
        n.normalize();
        BeziersurfacecontrolPointsNet.setCoordinate(c, A);
        BeziersurfacecontrolPointsNet.setCoordinate(c+1, B);
        BeziersurfacecontrolPointsNet.setCoordinate(c+2, C);
        BeziersurfacecontrolPointsNet.setCoordinate(c+3, D);
        BeziersurfacecontrolPointsNet.setNormal(c, n);
        BeziersurfacecontrolPointsNet.setNormal(c+1, n);
        BeziersurfacecontrolPointsNet.setNormal(c+2, n);
        BeziersurfacecontrolPointsNet.setNormal(c+3, n);
        c=c+4;
    }}
    this.addGeometry(BeziersurfacecontrolPointsNet);
    this.setAppearance(app);
}}
class matrixm
{public float CC[][]= new float[4][4];
    int ll,mm,kk;
    public matrixm(int mmm, int kkk, int nnn,float a[][],float b[][])
    {for(ll=0;ll<mmm;ll++)
        for(mm=0;mm<nnn;mm++){CC[ll][mm]=0.f;}
        for(ll=0;ll<mmm;ll++)
            for(mm=0;mm<nnn;mm++)
            {for(kk=0;kk<kkk;kk++) CC[ll][mm]=CC[ll][mm]+a[ll][kk]*b[kk][mm];}
    }}


Java3D设计作品入门级教程_第2张图片

在这一长段代码中,只有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}}};

运行我们的代码,得到如下结果:

Java3D设计作品入门级教程_第3张图片

到这步后,我们要把最前面提到的坐标轴,与这张图相结合。这里注意一下,为了避免把自己搞混乱,运行出结果后就不要随便去转动它!!!第一印象很重要。

Java3D设计作品入门级教程_第4张图片

这就是在这张图中代表的坐标系(上下位置不一定准确)
我们的重头戏要来了,这16个点分别代表图中的哪个位置,因为这个图像凹凸有致,我们很容易想到去调整它的Y坐标,来得到最佳的观察效果。
我们将这里的坐标分别4组,从上至下,从左至右,依次记为1,2,3……16

Java3D设计作品入门级教程_第5张图片

首先我们将第一个点的Y坐标改为0,观察效果

Java3D设计作品入门级教程_第6张图片

可以看到已经有了一定的变化,随后我们转动图像,以俯视的视角,也就是想象自己飞到了图像的上方。

Java3D设计作品入门级教程_第7张图片

可以看到图形的这一角比较特别,相比较原先有点翘起,归根结底就是我们把第一个点的纵坐标由-1.2f变为了0f,产生了这个效果。有兴趣的同学可以再把它改成-1.2f,就会得到如下 结果:

Java3D设计作品入门级教程_第8张图片

我们依葫芦画瓢,把这16个点都改一遍,也就是只把它们的Y坐标改为0,分别会得到以下结果(均采用了俯视的视角):

Java3D设计作品入门级教程_第9张图片
Java3D设计作品入门级教程_第10张图片
Java3D设计作品入门级教程_第11张图片

到这里,我们第一组的坐标全部测试完毕了,相信大家一定对坐标和曲面之间的对应关系有了一定的了解。现在我们再测一下每组的第一个点,同样修改其Y坐标

Java3D设计作品入门级教程_第12张图片
Java3D设计作品入门级教程_第13张图片
Java3D设计作品入门级教程_第14张图片

自己都试一遍印象才能深刻噢!

接着我们看看把全部的Y坐标归0的结果

Java3D设计作品入门级教程_第15张图片

可以看到打开的时候已经变成了一个平面了,不再是曲面,这也给了 我们一个构造平面的思路,也就是把16个点的XYZ任意一个全部设置为0,就可以得到平面。

当然学到这里,你已经掌握了一个曲面是如何运转的,然而我们的作品肯定不是只由一个曲面就能完成,除非你看开了。

加一个面

接下来我们将详细分析一下,自己如何再加一个曲面,然后在此基础上,你可以添加任意N个面

添加如下代码, 这里的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个,也是以此类推。
效果如下:

Java3D设计作品入门级教程_第16张图片

看到这里,相信你一定已经会意了
小练习:可以先动手试试如何用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<n0+1;i++)
        for(j=0;j<n0+1;j++)
        { 	UV[i][j][0]=i*division;
            UV[i][j][1]=j*division;   }
    for(i=0;i<4;i++)
        for(j=0;j<4;j++)
        { PX[i][j]=P[i][j][0];
            PY[i][j]=P[i][j][1];
            PZ[i][j]=P[i][j][2];
            P4[i][j]=P[i][j][3]; }
//计算曲面上点的坐标值
    for(i=0;i<n0+1;i++)
        for(j=0;j<n0+1;j++)
        {   UU[0][0]=1.f;
            UU[0][1]=UV[i][j][0];
            UU[0][2]=UV[i][j][0]*UV[i][j][0];
            UU[0][3]=UV[i][j][0]*UV[i][j][0]*UV[i][j][0];
            VV[0][0]=1.f;
            VV[1][0]=UV[i][j][1];
            VV[2][0]=UV[i][j][1]*UV[i][j][1];
            VV[3][0]=UV[i][j][1]*UV[i][j][1]*UV[i][j][1];
            //计算一点的x坐标
            matrixm g0=new matrixm(1,4,4,UU,M1);
            matrixm g1=new matrixm(1,4,4,g0.CC,PX);
            matrixm g2=new matrixm(1,4,4,g1.CC,M2);
            matrixm g3=new matrixm(1,4,1,g2.CC,VV);
            SurfaceXYZ[i][j][0]=g3.CC[0][0];
            //计算一点的y坐标
            matrixm g4=new matrixm(1,4,4,UU,M1);
            matrixm g5=new matrixm(1,4,4,g4.CC,PY);
            matrixm g6=new matrixm(1,4,4,g5.CC,M2);
            matrixm g7=new matrixm(1,4,1,g6.CC,VV);
            SurfaceXYZ[i][j][1]=g7.CC[0][0];
            //计算一点的z坐标
            matrixm g8=new matrixm(1,4,4,UU,M1);
            matrixm g9=new matrixm(1,4,4,g8.CC,PZ);
            matrixm g10=new matrixm(1,4,4,g9.CC,M2);
            matrixm g11=new matrixm(1,4,1,g10.CC,VV);
            SurfaceXYZ[i][j][2]=g11.CC[0][0];
            //计算一点的第4维坐标
            matrixm g12=new matrixm(1,4,4,UU,M1);
            matrixm g13=new matrixm(1,4,4,g12.CC,P4);
            matrixm g14=new matrixm(1,4,4,g13.CC,M2);
            matrixm g15=new matrixm(1,4,1,g14.CC,VV);
            SurfaceXYZ[i][j][3]=g15.CC[0][0];
            //将齐次坐标转换为三维坐标系坐标,如果第4维为1,则不用除第4维
            SurfaceXYZ[i][j][0]=SurfaceXYZ[i][j][0]/SurfaceXYZ[i][j][3];
            SurfaceXYZ[i][j][1]=SurfaceXYZ[i][j][1]/SurfaceXYZ[i][j][3];
            SurfaceXYZ[i][j][2]=SurfaceXYZ[i][j][2]/SurfaceXYZ[i][j][3];
        }
    QuadArray BezierQuadsurfaceface = new QuadArray(n0*n0*4,
            GeometryArray.COORDINATES|GeometryArray.NORMALS);
    int c=0;//以顶点数累加的方式设置顶点的序号
    for(i=0;i<n0;i++)
    {for(j=0;j<n0;j++)
    {//设置一个平面上的4个点
        Point3f A=new Point3f(SurfaceXYZ[i][j][0],SurfaceXYZ[i][j][1],
                SurfaceXYZ[i][j][2]);
        Point3f B=new Point3f(SurfaceXYZ[i][j+1][0],SurfaceXYZ[i][j+1][1],
                SurfaceXYZ[i][j+1][2]);
        Point3f C=new Point3f(SurfaceXYZ[i+1][j+1][0],SurfaceXYZ[i+1][j+1][1],
                SurfaceXYZ[i+1][j+1][2]);
        Point3f D=new Point3f(SurfaceXYZ[i+1][j][0],SurfaceXYZ[i+1][j][1],
                SurfaceXYZ[i+1][j][2]);
//计算由四个点形成的平面的法向量
        Vector3f a = new Vector3f(A.x - B.x, A.y - B.y, A.z - B.z);
        Vector3f b = new Vector3f(C.x - B.x, C.y - B.y, C.z - B.z);
        Vector3f n = new Vector3f();
        n.cross(b, a);
        n.normalize();
//设置点的序号
        BezierQuadsurfaceface.setCoordinate(c, A);
        BezierQuadsurfaceface.setCoordinate(c+1, B);
        BezierQuadsurfaceface.setCoordinate(c+2, C);
        BezierQuadsurfaceface.setCoordinate(c+3, D);
//设置点的法向量
        BezierQuadsurfaceface.setNormal(c, n);
        BezierQuadsurfaceface.setNormal(c+1, n);
        BezierQuadsurfaceface.setNormal(c+2, n);
        BezierQuadsurfaceface.setNormal(c+3, n);
        c=c+4;
    }}
    this.addGeometry(BezierQuadsurfaceface);
    this.setAppearance(app);
}}
class  BezierSurfaceControlPoints extends Shape3D
{public BezierSurfaceControlPoints(float[][][] P,Appearance app)
{int i,j,k;
    QuadArray BeziersurfacecontrolPointsNet =new QuadArray(3*3*4,
            GeometryArray.COORDINATES|GeometryArray.NORMALS);
    int c=0;
    for(i=0;i<3;i++)
    {for(j=0;j<3;j++)
    {Point3f A=new Point3f(P[i][j][0],P[i][j][1],P[i][j][2]);
        Point3f B=new Point3f(P[i][j+1][0],P[i][j+1][1],P[i][j+1][2]);
        Point3f C=new Point3f(P[i+1][j+1][0],P[i+1][j+1][1],P[i+1][j+1][2]);
        Point3f D=new Point3f(P[i+1][j][0],P[i+1][j][1],P[i+1][j][2]);
        Vector3f a = new Vector3f(A.x - B.x, A.y - B.y, A.z - B.z);
        Vector3f b = new Vector3f(C.x - B.x, C.y - B.y, C.z - B.z);
        Vector3f n = new Vector3f();
        n.cross(b, a);
        n.normalize();
        BeziersurfacecontrolPointsNet.setCoordinate(c, A);
        BeziersurfacecontrolPointsNet.setCoordinate(c+1, B);
        BeziersurfacecontrolPointsNet.setCoordinate(c+2, C);
        BeziersurfacecontrolPointsNet.setCoordinate(c+3, D);
        BeziersurfacecontrolPointsNet.setNormal(c, n);
        BeziersurfacecontrolPointsNet.setNormal(c+1, n);
        BeziersurfacecontrolPointsNet.setNormal(c+2, n);
        BeziersurfacecontrolPointsNet.setNormal(c+3, n);
        c=c+4;
    }}
    this.addGeometry(BeziersurfacecontrolPointsNet);
    this.setAppearance(app);
}}
class matrixm
{public float CC[][]= new float[4][4];
    int ll,mm,kk;
    public matrixm(int mmm, int kkk, int nnn,float a[][],float b[][])
    {for(ll=0;ll<mmm;ll++)
        for(mm=0;mm<nnn;mm++){CC[ll][mm]=0.f;}
        for(ll=0;ll<mmm;ll++)
            for(mm=0;mm<nnn;mm++)
            {for(kk=0;kk<kkk;kk++) CC[ll][mm]=CC[ll][mm]+a[ll][kk]*b[kk][mm];}
    }}


你可能感兴趣的:(算法竞赛,java)