计算机图形学-实验4-掌握几何变换的原理
来源:互联网 发布:软件用户手册英文模板 编辑:程序博客网 时间:2024/06/06 06:55
实验四:(2学时)
一、 实验目的:
掌握几何变换的原理,尤其是复合变换
二、 实验内容:
1、利用OpenGL函数画一个三维物体;
2、运用齐次坐标,采用矩阵相乘的方式自己编程实现几何变换,不能直接调用OpenGL几何变换函数;
3、利用鼠标或键盘控制三维物体在屏幕上移动、旋转和放缩;
三、 实现效果及步骤(或流程)
1、利用OpenGL函数画一个三维物体;
实现方法:
(1)初始化时给八个坐标,坐标之间两两相连画线,代码如下:
// 将立方体的八个顶点保存到一个数组里面 static float vertex_list[][3] ={-0.5f, -0.5f, -0.5f,0.5f, -0.5f, -0.5f,-0.5f, 0.5f, -0.5f,0.5f, 0.5f, -0.5f,-0.5f, -0.5f, 0.5f,0.5f, -0.5f, 0.5f,-0.5f, 0.5f, 0.5f,0.5f, 0.5f, 0.5f,};// 将要使用的顶点的序号保存到一个数组里面 static const GLint index_list[][2] ={{ 0, 1 },{ 2, 3 },{ 4, 5 },{ 6, 7 },{ 0, 2 },{ 1, 3 },{ 4, 6 },{ 5, 7 },{ 0, 4 },{ 1, 5 },{ 7, 3 },{ 2, 6 }};//绘制立方体void DrawCube(void){int i, j;glBegin(GL_LINES);for (i = 0; i < 12; ++i) // 12 条线段{for (j = 0; j < 2; ++j) // 每条线段 2个顶点{glVertex3fv(vertex_list[index_list[i][j]]);}}glEnd();}
2、运用齐次坐标,采用矩阵相乘的方式自己编程实现几何变换,不能直接调用OpenGL几何变换函数;
实现方法:
(1)移动函数:
typedef GLfloat Matrix4x4[4][4];void matrix4x4SetIdentity(Matrix4x4 matIdent4x4) {GLint row, col;for (row = 0; row < 4; row++)for (col = 0; col < 4; col++) matIdent4x4[row][col] = (row == col);}//自定义平移函数void translate3D(GLfloat tx, GLfloat ty, GLfloat tz) {Matrix4x4 matTransl3D;matrix4x4SetIdentity(matTransl3D);matTransl3D[0][3] = tx;matTransl3D[1][3] = ty;matTransl3D[2][3] = tz;for (int i = 0; i < 8; i++){for (int j = 0; j < 3; j++){vertex_list[i][j] += matTransl3D[j][3];}}}
(2)旋转函数:
typedef GLfloat Matrix4x4[4][4];void matrix4x4SetIdentity(Matrix4x4 matIdent4x4) {GLint row, col;for (row = 0; row < 4; row++)for (col = 0; col < 4; col++) matIdent4x4[row][col] = (row == col);}//自定义旋转函数void rotate3D(GLfloat e, GLfloat rx, GLfloat ry, GLfloat rz){Matrix4x4 matRotate3D;matrix4x4SetIdentity(matRotate3D);if (rx == 1 && ry == 0 && rz == 0){matRotate3D[0][0] = 1;matRotate3D[1][1] = cos(e);matRotate3D[1][2] = sin(e);matRotate3D[2][1] = -sin(e);matRotate3D[2][2] = cos(e);for (int i = 0; i < 8; i++){vertex_list[i][0] = matRotate3D[0][0] * vertex_list[i][0];vertex_list[i][1] = matRotate3D[1][1] * vertex_list[i][1] + matRotate3D[1][2] * vertex_list[i][2];vertex_list[i][2] = matRotate3D[2][1] * vertex_list[i][1] + matRotate3D[2][2] * vertex_list[i][2];}}else if (rx == 0 && ry == 1 && rz == 0){matRotate3D[0][0] = cos(e);matRotate3D[0][2] = -sin(e);matRotate3D[1][1] = 1;matRotate3D[2][0] = sin(e);matRotate3D[2][2] = cos(e);for (int i = 0; i < 8; i++){vertex_list[i][0] = matRotate3D[0][0] * vertex_list[i][0] + matRotate3D[0][2] * vertex_list[i][2];vertex_list[i][1] = matRotate3D[1][1] * vertex_list[i][1];vertex_list[i][2] = matRotate3D[2][0] * vertex_list[i][0] + matRotate3D[2][2] * vertex_list[i][2];}}else if (rx == 0 && ry == 0 && rz == 1){matRotate3D[0][0] = cos(e);matRotate3D[0][1] = -sin(e);matRotate3D[1][0] = sin(e);matRotate3D[1][1] = cos(e);matRotate3D[2][2] = 1;for (int i = 0; i < 8; i++){vertex_list[i][0] = matRotate3D[0][0] * vertex_list[i][0] + matRotate3D[0][1] * vertex_list[i][1];vertex_list[i][1] = matRotate3D[1][0] * vertex_list[i][0] + matRotate3D[1][1] * vertex_list[i][1];vertex_list[i][2] = matRotate3D[2][2] * vertex_list[i][2];}}}
(3)缩放函数:
wcPt3D fixedPt = wcPt3D();typedef GLfloat Matrix4x4[4][4];void matrix4x4SetIdentity(Matrix4x4 matIdent4x4) {GLint row, col;for (row = 0; row < 4; row++)for (col = 0; col < 4; col++) matIdent4x4[row][col] = (row == col);}//自定义缩放函数void scale3D(GLfloat sx, GLfloat sy, GLfloat sz, wcPt3D fixedPt) {Matrix4x4 matScale3D;matrix4x4SetIdentity(matScale3D);matScale3D[0][0] = sx;matScale3D[0][3] = (1 - sx) * fixedPt.getx();matScale3D[1][1] = sy;matScale3D[1][3] = (1 - sy) * fixedPt.gety();matScale3D[2][2] = sz;matScale3D[2][3] = (1 - sz) * fixedPt.getz();for (int i = 0; i < 8; i++){vertex_list[i][0] = matScale3D[0][0] * vertex_list[i][0] + matScale3D[0][3] * vertex_list[i][3];vertex_list[i][1] = matScale3D[1][1] * vertex_list[i][1] + matScale3D[1][3] * vertex_list[i][3];vertex_list[i][2] = matScale3D[2][2] * vertex_list[i][2] + matScale3D[2][3] * vertex_list[i][3];}}
3、利用鼠标或键盘控制三维物体在屏幕上移动、旋转和放缩;
实现效果:
(1)鼠标左键拖拽可以移动图形。
(2)鼠标右键拖拽可以旋转图形。
(3)鼠标滚轮滚动可以缩放图形
实现代码如下:
void OnMouseMove(int x, int y){printf("x:%d,y:%d\n", x, y);if (LeftButtonIsDown == 1){x1 = x;y11 = 500 - y;tx = x1 - x0;ty = y11 - y00;tz = 0;}if (RightButtonIsDown == 1){x3 = x;y3 = 500 - y;rx = x3 - x2;ry = y3 - y2;rz = 0;}}void MouseFunc(int button, int state, int x, int y){if (button == GLUT_LEFT_BUTTON){if (state == GLUT_DOWN){if (LeftButtonIsDown == 0){x0 = x;y00 = 500 - y;LeftButtonIsDown = 1;}}else{LeftButtonIsDown = 0;}}if (button == GLUT_RIGHT_BUTTON){if (state == GLUT_DOWN){if (RightButtonIsDown == 0){x2 = x;y2 = 500 - y;RightButtonIsDown = 1;}}else{RightButtonIsDown = 0;}}if (button == GLUT_WHEEL_UP){zoom += 0.01;}if (button == GLUT_WHEEL_DOWN){zoom -= 0.01;}}
完整的项目源码如下:
// test4.cpp : 定义控制台应用程序的入口点。#include "stdafx.h"#include<GL/glut.h>#include<math.h>#define GLUT_WHEEL_UP 3#define GLUT_WHEEL_DOWN 4// 绘制立方体//参数static float rotate = 0.001;static float translate = 0.0001;static float PI = 3.14159;//鼠标按下时的坐标int x0, y00;//鼠标停下时的坐标int x1, y11;//鼠标是否按下int LeftButtonIsDown = 0;//鼠标按下时的坐标int x2, y2;//鼠标停下时的坐标int x3, y3;//鼠标是否按下int RightButtonIsDown = 0;//位移增量float tx = 0;float ty = 0;float tz = 0;//旋转增量float rx = 0;float ry = 0;float rz = 0;//缩放增量float zoom = 1;// 将立方体的八个顶点保存到一个数组里面 static float vertex_list[][3] ={-0.5f, -0.5f, -0.5f,0.5f, -0.5f, -0.5f,-0.5f, 0.5f, -0.5f,0.5f, 0.5f, -0.5f,-0.5f, -0.5f, 0.5f,0.5f, -0.5f, 0.5f,-0.5f, 0.5f, 0.5f,0.5f, 0.5f, 0.5f,};// 将要使用的顶点的序号保存到一个数组里面 static const GLint index_list[][2] ={{ 0, 1 },{ 2, 3 },{ 4, 5 },{ 6, 7 },{ 0, 2 },{ 1, 3 },{ 4, 6 },{ 5, 7 },{ 0, 4 },{ 1, 5 },{ 7, 3 },{ 2, 6 }};class wcPt3D {private:GLfloat x, y, z;public:wcPt3D() {x = y = z = 0.0;}void setCoords(GLfloat xCoord, GLfloat yCoord, GLfloat zCoord) {x = xCoord;y = yCoord;z = zCoord;}GLfloat getx() const { return x; }GLfloat gety() const { return y; }GLfloat getz() const { return z; }};wcPt3D fixedPt = wcPt3D();typedef GLfloat Matrix4x4[4][4];void matrix4x4SetIdentity(Matrix4x4 matIdent4x4) {GLint row, col;for (row = 0; row < 4; row++)for (col = 0; col < 4; col++) matIdent4x4[row][col] = (row == col);}//自定义平移函数void translate3D(GLfloat tx, GLfloat ty, GLfloat tz) {Matrix4x4 matTransl3D;matrix4x4SetIdentity(matTransl3D);matTransl3D[0][3] = tx;matTransl3D[1][3] = ty;matTransl3D[2][3] = tz;for (int i = 0; i < 8; i++){for (int j = 0; j < 3; j++){vertex_list[i][j] += matTransl3D[j][3];}}}//自定义旋转函数void rotate3D(GLfloat e, GLfloat rx, GLfloat ry, GLfloat rz){Matrix4x4 matRotate3D;matrix4x4SetIdentity(matRotate3D);if (rx == 1 && ry == 0 && rz == 0){matRotate3D[0][0] = 1;matRotate3D[1][1] = cos(e);matRotate3D[1][2] = sin(e);matRotate3D[2][1] = -sin(e);matRotate3D[2][2] = cos(e);for (int i = 0; i < 8; i++){vertex_list[i][0] = matRotate3D[0][0] * vertex_list[i][0];vertex_list[i][1] = matRotate3D[1][1] * vertex_list[i][1] + matRotate3D[1][2] * vertex_list[i][2];vertex_list[i][2] = matRotate3D[2][1] * vertex_list[i][1] + matRotate3D[2][2] * vertex_list[i][2];}}else if (rx == 0 && ry == 1 && rz == 0){matRotate3D[0][0] = cos(e);matRotate3D[0][2] = -sin(e);matRotate3D[1][1] = 1;matRotate3D[2][0] = sin(e);matRotate3D[2][2] = cos(e);for (int i = 0; i < 8; i++){vertex_list[i][0] = matRotate3D[0][0] * vertex_list[i][0] + matRotate3D[0][2] * vertex_list[i][2];vertex_list[i][1] = matRotate3D[1][1] * vertex_list[i][1];vertex_list[i][2] = matRotate3D[2][0] * vertex_list[i][0] + matRotate3D[2][2] * vertex_list[i][2];}}else if (rx == 0 && ry == 0 && rz == 1){matRotate3D[0][0] = cos(e);matRotate3D[0][1] = -sin(e);matRotate3D[1][0] = sin(e);matRotate3D[1][1] = cos(e);matRotate3D[2][2] = 1;for (int i = 0; i < 8; i++){vertex_list[i][0] = matRotate3D[0][0] * vertex_list[i][0] + matRotate3D[0][1] * vertex_list[i][1];vertex_list[i][1] = matRotate3D[1][0] * vertex_list[i][0] + matRotate3D[1][1] * vertex_list[i][1];vertex_list[i][2] = matRotate3D[2][2] * vertex_list[i][2];}}//double e = (180 * a) / PI;}//自定义缩放函数void scale3D(GLfloat sx, GLfloat sy, GLfloat sz, wcPt3D fixedPt) {Matrix4x4 matScale3D;matrix4x4SetIdentity(matScale3D);matScale3D[0][0] = sx;matScale3D[0][3] = (1 - sx) * fixedPt.getx();matScale3D[1][1] = sy;matScale3D[1][3] = (1 - sy) * fixedPt.gety();matScale3D[2][2] = sz;matScale3D[2][3] = (1 - sz) * fixedPt.getz();for (int i = 0; i < 8; i++){vertex_list[i][0] = matScale3D[0][0] * vertex_list[i][0] + matScale3D[0][3] * vertex_list[i][3];vertex_list[i][1] = matScale3D[1][1] * vertex_list[i][1] + matScale3D[1][3] * vertex_list[i][3];vertex_list[i][2] = matScale3D[2][2] * vertex_list[i][2] + matScale3D[2][3] * vertex_list[i][3];}}//绘制立方体void DrawCube(void){int i, j;glBegin(GL_LINES);for (i = 0; i < 12; ++i) // 12 条线段{for (j = 0; j < 2; ++j) // 每条线段 2个顶点{glVertex3fv(vertex_list[index_list[i][j]]);}}glEnd();}void renderScene(){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glMatrixMode(GL_MODELVIEW);//获取当前矩阵的单位矩阵,以后变化都基于这个坐标。glLoadIdentity();//将当前矩阵压入栈内。glPushMatrix();//平移translate3D((tx)*translate, (ty)*translate, 0);//旋转rotate3D(-rx*rotate, 0, 1, 0);rotate3D(ry*rotate, 1, 0, 0);// 缩放scale3D(zoom, zoom, zoom, fixedPt);//画笔颜色glColor3f(1, 1, 1);//画立方体DrawCube();//输出栈顶的矩阵glPopMatrix();//双缓冲交换glutSwapBuffers();//移动变量初始化tx = 0;ty = 0;tz = 0;//旋转变量初始化rx = 0;ry = 0;rz = 0;//缩放变量初始化zoom = 1;}void OnMouseMove(int x, int y){printf("x:%d,y:%d\n", x, y);if (LeftButtonIsDown == 1){x1 = x;y11 = 500 - y;tx = x1 - x0;ty = y11 - y00;tz = 0;}if (RightButtonIsDown == 1){x3 = x;y3 = 500 - y;rx = x3 - x2;ry = y3 - y2;rz = 0;}}void MouseFunc(int button, int state, int x, int y){if (button == GLUT_LEFT_BUTTON){if (state == GLUT_DOWN){if (LeftButtonIsDown == 0){x0 = x;y00 = 500 - y;LeftButtonIsDown = 1;}}else{LeftButtonIsDown = 0;}}if (button == GLUT_RIGHT_BUTTON){if (state == GLUT_DOWN){if (RightButtonIsDown == 0){x2 = x;y2 = 500 - y;RightButtonIsDown = 1;}}else{RightButtonIsDown = 0;}}if (button == GLUT_WHEEL_UP){zoom += 0.01;}if (button == GLUT_WHEEL_DOWN){zoom -= 0.01;}}void init(){DrawCube();}void main(int argc, char **argv){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);glutInitWindowPosition(100, 100);glutInitWindowSize(500, 500);glutCreateWindow("GLDemo");init();glutMouseFunc(MouseFunc);glutMotionFunc(OnMouseMove);//func:在程序空闲的时候就会被调用的函数的函数名。 glutIdleFunc(renderScene);glutMainLoop();}
1 0
- 计算机图形学-实验4-掌握几何变换的原理
- 几何变换---计算机图形学
- 计算机图形学 几何变换代码
- 计算机图形学—几何变换
- 计算机图形学-实验5-掌握Bezier样条曲面生成思想、复习基本图元绘制、交互操作和几何变换相关内容
- 计算机图形学(四)_几何变换_1_基本的二维几何变换(一)
- 计算机图形学(四)_几何变换_1_基本的二维几何变换(二)_旋转
- 计算机图形学(四)_几何变换_1_基本的二维几何变换(三)_缩放
- 计算机图形学(四)几何变换_5_三维空间的几何变换
- 计算机图形学(四)几何变换_5_三维空间的几何变换_1_三维平移
- 计算机图形学:基本二维几何变换
- 计算机图形学(三)二维几何变换
- 计算机图形学实验-几何图形的比例和旋转变换
- 《计算机图形学》实验三:图形变换
- 计算机图形学图形的变换
- 计算机图形学(四)几何变换_4_二维复合变换_4_二维刚体变换
- 计算机图形学(四)几何变换_4_二维复合变换_5_其他二维变换_1_反射
- 计算机图形学(四)几何变换_4_二维复合变换_5_其他二维变换_2_错切
- 机器学习实战:SVD图像压缩
- 记用jetty开发,部署到服务器后查询失败
- Android 6.0:Unable to add window android.view.ViewRootImpl$W@5e2d85a -- permission denied
- xcode8.3之后UILabel无法添加删除线
- android 调用系统相机进行拍照及照片的裁切
- 计算机图形学-实验4-掌握几何变换的原理
- Android WebRTC 音视频开发总结(三)-- 信令服务和媒体服务
- Model层attributes()方法和attributeLabels()
- Android CPU性能文件位置
- 普瑞马法则
- C++第五次实验--实验报告
- GPU渲染管线概述
- Qt中的打印操作
- 关于如何快速获取下载积分