您的当前位置:首页正文

计算机图形学--实验四-几何变换

来源:爱站旅游
导读计算机图形学--实验四-几何变换
贵州大学实验报告

学院: 计算机科学与信息学院 专业:软件工程 班级: 102班

姓名 实验时间 实验项目名称 实掌握二维图形的几何变换的基本原理。二维图形的基本几何变换:位置改变(平移、旋验转)和变形(缩放、错切,反射、投影等)以及复合变换。 目了解三维图形的错切变换 的 根据本实验的特点、要求和具体条件,掌握二维图形的几何变换的基本原理,了解三维实验要图形的错切变换,并成功编写测试代码进行实验。 1.设有一三角形ABC,其中三个顶点为A(5,10),B(1,2),C(8,5),如三角形的顶点A不变,将AB和AC边缩小一倍后,求缩小后的三角形对于直线-2x+4y+3=0的对称变换后的结果图。 学号 指导教师 实验组 成绩 实验四 几何变换 求 2.将一四边形以原点为中心,以15°为间隔旋转。 3.在三维坐标中,对长度为1的标准立方体做错切变换,错切单位为2; 一、实验原理:标准齐次坐标(x,y,1) 二维变换的矩阵表示 平移变换 实验原 xy1 x1y1 0tx01ty0记为0 x1y1T(tx,ty)理 旋转变换 xy1 xcosy1 sin0sincos00记为0 x1y1 R() 放缩变换 平移变换只改变图形的位置,不改变图形的大小。 cos Rsin0sincos0001旋转变换不改变图形的形状 放缩变换引起图形形状的变化。 复合变换结果与变换的顺序有关(矩阵乘法不可交换) xy1x0sy0sxy1000010sy000x1y1S(sx,sy)sxS(sx,sy)00二、Java3D 在java3D中坐标轴的显示如下所示: Java3D的编程思想显示如下: 在实验时,要引入相关的jar包,显示如下所示: 实验环境 实验步骤 1. 掌握算法原理; 2. 依据算法,编写源程序并进行调试; 3. 对运行结果进行保存与分析; 4. 把源程序以文件的形式提交; 硬件平台:PC机 软件:Windows7平台,eclipse集成开发环境,java编程语言。 Java 3D 5. 按格式书写实验报告。 处理点的类: package wangqian.draw.transform; public class MyPoint { private int x; private int y; public MyPoint() { } public MyPoint(int x, int y) { super(); this.x = x; this.y = y; } public int getX() { return x; } 实 public void setX(int x) { 验 this.x = x; } 内 public int getY() { 容 return y; } public void setY(int y) { this.y = y; } } 三角形的变换 核心代码: 三角形点的录入: public void putPoint1() { MyPoint point1 = new MyPoint(); point1.setX(100); point1.setY(200); pointlist.add(point1); MyPoint point2 = new MyPoint(); point2.setX(20); point2.setY(40); pointlist.add(point2); MyPoint point3 = new MyPoint(); point3.setX(160); point3.setY(100); pointlist.add(point3); MyPoint point4 = new MyPoint(); point4.setX(100); point4.setY(200); pointlist.add(point4); }

根据点画三角形: if (num == 1) { for (int i = 1; i < pointlist.size(); i++) {// 根据给出的顶点画线 MyPoint p1 = pointlist.get(i); int x1 = p1.getX(); int y1 = p1.getY(); MyPoint p2 = pointlist.get(i - 1); int x2 = p2.getX(); int y2 = p2.getY(); g.drawLine(x1, y1, x2, y2); } }

三角形的缩小变换:

private void changePictureSize(MyPoint unchangedpoint, double sx, double sy) { for (MyPoint pb : pointlist) { pb.setX((int) (pb.getX() * sx + unchangedpoint.getX() * (1 - sx))); pb.setY((int) (pb.getY() * sy + unchangedpoint.getY() * (1 - sy))); } g.setColor(Color.BLUE); drawPicture(1); }

三角形关于特定直线的对称变换: private void changePictureLocation() { for (MyPoint pb : pointlist) { double x1 = (pb.getY() + 2 * pb.getX() + 0.75) / 2.5; double y1 = (pb.getY() + 2 * pb.getX() - 3) / 5.0; pb.setX((int) (x1 + (x1 - pb.getX()))); pb.setY((int) (y1 - (pb.getY() - y1))); } g.setColor(Color.BLUE); drawPicture(1); }

四边形的旋转变换:

四边形点的录入和绘画同三角形 四边形的旋转函数显示如下: private void spinPicture() { double r; r = 15 / 180.0 * 3.1415926;// 旋转150 for (MyPoint pb : pointlist2) {// 遍历多边形的顶点 double x1 = pb.getX() * Math.cos(r) - pb.getY() * Math.sin(r);// 根据度数和顶点值来确定改变的顶点 double y1 = pb.getX() * Math.sin(r) + pb.getY() * Math.cos(r); pb.setX((int) (x1)); pb.setY((int) (y1)); } g.setColor(Color.ORANGE); drawPicture(2); }

键盘的监听类:

class KeyMonitor extends KeyAdapter { public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_C://清空画布 panel.repaint(); break; case KeyEvent.VK_1://准备进行三角形的变换 putPoint1(); g.setColor(Color.RED); drawPicture(1); g.drawLine(0, 0, 0, 600); g.drawLine(0, 0, 600, 0); g.drawLine(-30, (int) (-63 / 4), 200, (int) (397 / 4)); break; case KeyEvent.VK_2://准备进行四边形的变换 putPoint2(); g.setColor(Color.MAGENTA); drawPicture(2); g.drawLine(0, 0, 0, 600); g.drawLine(0, 0, 600, 0); break; case KeyEvent.VK_3: BasicConstruct bc = new BasicConstruct(); bc.addMyBox(x, y, z, bc); break; case KeyEvent.VK_S://图形的缩小变换 changePictureSize(pointlist.get(0), 0.5, 0.5); break;

case KeyEvent.VK_L://图形的对称变换 changePictureLocation(); break; case KeyEvent.VK_T://四边形的旋转变换 spinPicture(); break; case KeyEvent.VK_E://复原3D图形 x = 0.1f; y = 0.1f; z = 0.1f; break; case KeyEvent.VK_X://X轴的错切变换 BasicConstruct bc0 = new BasicConstruct(); x = x + 0.1f;//x轴错切,改变x轴的比例, bc0.addMyBox(x, y, z, bc0);//长方体的绘制函数 break; case KeyEvent.VK_Y://Y轴的错切变换 BasicConstruct bc1 = new BasicConstruct(); y = y + 0.1f;//y轴错切,改变y轴的比例, bc1.addMyBox(x, y, z, bc1); break; case KeyEvent.VK_Z://Z轴的错切变换 BasicConstruct bc2 = new BasicConstruct(); z = z + 0.1f;//z轴错切,改变z轴的比例, bc2.addMyBox(x, y, z, bc2); break; default: ; } } }

3D图形的框架搭建 /*

* 绘制三维图形的类

* 里面包含了绘制长方体的方法和鼠标的监听事件 */

public class BasicConstruct extends JFrame { protected SimpleUniverse simpleU; protected BranchGroup rootBranchGroup; public BasicConstruct() { initial_setup(); }

/*

* 初始化步骤 */

protected void initial_setup() { getContentPane().setLayout(new BorderLayout());// 得到框架和设置布局 GraphicsConfiguration config = SimpleUniverse .getPreferredConfiguration();// 得到配置函数 Canvas3D canvas3D = new Canvas3D(config);// 创建3d图形的面板 getContentPane().add(\"Center\", canvas3D);// 把3d图形面板添加到框架上 simpleU = new SimpleUniverse(canvas3D);// 设置3d图形的画布形式 rootBranchGroup = new BranchGroup(); }

/*

* 设置3d画布的视角以及高光等参数 */

public void addDirectionalLight(Vector3f direction, Color3f color) { BoundingSphere bounds = new BoundingSphere(); bounds.setRadius(1000d); }

DirectionalLight lightD = new DirectionalLight(color, direction); lightD.setInfluencingBounds(bounds); rootBranchGroup.addChild(lightD);

/*

* 本次实验的核心函数 创建长方体的函数 需要长方体的长宽高比例以及颜色 */

public void addBox(float x, float y, float z, Color3f diffuse, Color3f spec) { Appearance app = new Appearance();// 设置长方体的视角以及绘制参数 Material mat = new Material();// 创建节点 mat.setDiffuseColor(diffuse);// 设置长方体的轮廓颜色和表面颜色 mat.setSpecularColor(spec); mat.setShininess(5.0f);// 超出范围则不显示

app.setMaterial(mat);

Box box = new Box(x, y, z, app);// 创建长方体 TransformGroup tg = new TransformGroup(); tg.addChild(box);

rootBranchGroup.addChild(tg);

}

}

tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); /*

* 创建鼠标事件,使长方体能够被移动和旋转 */

MouseRotate myMouseRotate = new MouseRotate(); myMouseRotate.setTransformGroup(tg);

myMouseRotate.setSchedulingBounds(new BoundingSphere()); rootBranchGroup.addChild(myMouseRotate);

MouseTranslate myMouseTranslate = new MouseTranslate(); myMouseTranslate.setTransformGroup(tg);

myMouseTranslate.setSchedulingBounds(new BoundingSphere()); rootBranchGroup.addChild(myMouseTranslate);

MouseZoom myMouseZoom = new MouseZoom(); myMouseZoom.setTransformGroup(tg);

myMouseZoom.setSchedulingBounds(new BoundingSphere()); rootBranchGroup.addChild(myMouseZoom);

public void finalise() { simpleU.addBranchGraph(rootBranchGroup); simpleU.getViewingPlatform().setNominalViewingTransform(); }

/*

* 封装类需要调用的函数,主要是整合3d长方体的创建 */

public void addMyBox(float x, float y, float z, BasicConstruct bc) { bc.setSize(1024, 768); bc.addBox(x, y, z, new Color3f(1, 0, 0), new Color3f(1, 0, 0)); bc.addDirectionalLight(new Vector3f(0f, 0f, -1), new Color3f(1f, 1f, 0f)); bc.finalise(); bc.show(); return; }

本次实验中图形的变换可以通过键盘来控制。 1、运行程序之后,点击“1”进入三角形的变换: 实验结果 2、点击“S”进行三角形的缩小变换: 如上图所示,蓝色的三角形为原三角形缩小后的三角形。 3、点击“L”键,进行三角形关于直线-2x+4y+3=0的对称变换: 如图所示,直线上方的三角形即为关于直线对称后得到的三角形。 4、点击“C”键,清空画布,进行四边形的变换: 5、点击“2”键,进行四边形的变换: 6、点击“T”键,进行四边形的旋转变换,旋转角度为15度: 7、点击“3”查看java3D的立方体: 用鼠标拖动即可对立方体进行旋转,查看其3D视图: 8、点击“X”键,对立方体进行X轴方向的错切: 9、点击“Y”键,对立方体进行Y轴方向的错切: 10、点击“Z”键,对立方体进行Z轴方向的错切: 本次实验让我了解并掌握了图形的基本几何变换,对于本次实验,有如下说明: 1、 本次实验继承了JFrame,并在程序中使用了JPanel,使得画笔的获得更为方便,可直接在函数中调用声明为成员变量的画笔,从而避免了作为参数传递的麻烦。 实验总2、 本次实验中运用了tanslate(int x,int y)函数,将图形上下文的点平移到当前坐标系中的点 (x, y)。便于实验结果的观察。 本次实验的不足在于: 结 改变大小的函数,对称变换的函数以及旋转变换的函数中均存在对double类型数的取整运算,使得实验结果存在必然的误差,在改变大小以及对称变换中体现的不明显,但是在旋转变换中误差很明显: 在旋转一周多时图形显示如下: 由上图可以看出图形变小了。旋转多周后效果更为明显: 给要进行取整运算的表达式加上0.5,这个问题仍然存在,这个旋转问题在本次实验中还没有找到更好的解决办法,希望在今后的学习中可以得到解决。 指导教师意见

签名: 年 月 日

因篇幅问题不能全部显示,请点此查看更多更全内容

Top