图形的几何变换也就是将图形的顶点的坐标进行变换后,根据新的顶点进行绘制的几何图形。

几何变换操作的过程是将变换矩阵M作用于齐次坐标点P生成新的坐标点P´,即P´=M·P。

//缩放
void scale2D(GLfloat sx, GLfloat sy, int x, int y) {Matrix matScale;setMatrixIdentity(matScale);//得到一个单位矩阵matScale[0][0] = sx;matScale[0][2] = (1 - sx) * x;matScale[1][1] = sy;matScale[1][2] = (1 - sy) * y;matrixpreMultiply(matScale, Composite);//两个矩阵相乘
}

//平移
void translate2D(GLfloat tx, GLfloat ty) {Matrix matTransl;setMatrixIdentity(matTransl);//设置为单位矩阵matTransl[0][2] = tx;matTransl[1][2] = ty;matrixpreMultiply(matTransl, Composite);//矩阵相乘
}

//旋转
void rotate2D(int x, int y, float theta) {theta = theta / 180 * PI;Matrix matRot;setMatrixIdentity(matRot);//得到单位矩阵matRot[0][0] = cos(theta);matRot[0][1] = -sin(theta);matRot[0][2] = x * (1 - cos(theta)) + y * sin(theta);matRot[1][0] = sin(theta);matRot[1][1] = cos(theta);matRot[1][2] = y * (1 - cos(theta)) - x * sin(theta);matrixpreMultiply(matRot, Composite);矩阵相乘
}

上代码:

#include<gl/glut.h>
#include<iostream>
#include<cmath>
#include<vector>
#define PI 3.14159265358using namespace std;
struct position {//存储所有点double x;double y;
};
typedef GLfloat Matrix[3][3];
Matrix Composite;//复合矩阵
vector<position> xy;//存储顶点
position tmp;
//r,d,v,g分别为平移,绘制多边形,旋转,缩放
#define TRANSLATE 0
#define DRAWPOLYGON 1
#define ROTATE 2
#define SCALE 3
int tran_x, tran_y;
int _xtmp, _ytmp;//作为缩放变量用
int mode = DRAWPOLYGON;//默认为绘制模式//该方法将矩阵设为单位矩阵
void setMatrixIdentity(Matrix mat) {GLint row, col;for (row = 0;row < 3;row++) {for (col = 0;col < 3;col++)mat[row][col] = (row == col);}
}
//进行全局的初始化
void init() {glClearColor(1.0, 1.0, 1.0, 1.0);//设置绘制窗口颜色为白色glClear(GL_COLOR_BUFFER_BIT);//清除窗口显示内容/*设置为投影类型模式和其他观察参数*/glPointSize(3.0f);glColor3f(1.0, 0.0, 0.0);//设置颜色为红glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0, 800, 650, 0);setMatrixIdentity(Composite);
}
//矩阵相乘
void matrixpreMultiply(Matrix m1, Matrix m2) {GLint row, col;Matrix tmp;for (row = 0;row < 3;row++) {for (col = 0;col < 3;col++) {tmp[row][col] = m1[row][0] * m2[0][col] + m1[row][1] *m2[1][col] + m1[row][2] * m2[2][col];}}for (row = 0;row < 3;row++) {for (col = 0;col < 3;col++) {m2[row][col] = tmp[row][col];}}
}
//平移
void translate2D(GLfloat tx, GLfloat ty) {Matrix matTransl;setMatrixIdentity(matTransl);//设置为单位矩阵matTransl[0][2] = tx;matTransl[1][2] = ty;matrixpreMultiply(matTransl, Composite);
}
//旋转
void rotate2D(int x, int y, float theta) {theta = theta / 180 * PI;Matrix matRot;setMatrixIdentity(matRot);matRot[0][0] = cos(theta);matRot[0][1] = -sin(theta);matRot[0][2] = x * (1 - cos(theta)) + y * sin(theta);matRot[1][0] = sin(theta);matRot[1][1] = cos(theta);matRot[1][2] = y * (1 - cos(theta)) - x * sin(theta);matrixpreMultiply(matRot, Composite);
}
//缩放
void scale2D(GLfloat sx, GLfloat sy, int x, int y) {Matrix matScale;setMatrixIdentity(matScale);matScale[0][0] = sx;matScale[0][2] = (1 - sx) * x;matScale[1][1] = sy;matScale[1][2] = (1 - sy) * y;matrixpreMultiply(matScale, Composite);
}
//复合矩阵
void transformVerts2D() {GLfloat tmp;for (int i = 0;i < xy.size();i++) {tmp = Composite[0][0] * xy[i].x + Composite[0][1] * xy[i].y + Composite[0][2];xy[i].y = Composite[1][0] * xy[i].x + Composite[1][1] * xy[i].y + Composite[1][2];xy[i].x = tmp;}DrawPicture();setMatrixIdentity(Composite);
}
//绘制多边形
void DrawPicture() {//  glEnable(GL_POLYGON_STIPPLE);glPolygonMode(GL_BACK, GL_LINE);//设置反面为线性模式glPolygonMode(GL_FRONT, GL_LINE);//设置正面为线性模式glClear(GL_COLOR_BUFFER_BIT);//清除窗口显示内容glBegin(GL_POLYGON);for (unsigned int i = 0;i < xy.size();i++) {glVertex2f(xy[i].x, xy[i].y);}glEnd();glFlush();
}
//鼠标拖动后根据选择做相应的移动
void Drawmouse(int x, int y) {float ssx = 1, ssy = 1;switch (mode){//q,w,e,rcase TRANSLATE:translate2D(x - tran_x, y - tran_y);transformVerts2D();tran_x = x;tran_y = y;break;case DRAWPOLYGON:break;case ROTATE:if (x <= _xtmp && y >= _ytmp)rotate2D(tran_x, tran_y, -8);elserotate2D(tran_x, tran_y, 8);transformVerts2D();_xtmp = x;_ytmp = y;break;case SCALE:/*不等比例缩放*/if (x > _xtmp) {ssx += 0.1f;}else if (x < _xtmp && ssx>0) {ssx -= 0.1f;}if (y < _ytmp) {ssy += 0.1f;}else if (y > _ytmp && ssy > 0) {ssy -= 0.1f;}/*等比例缩放*/if(x<=_xtmp&&y>=_ytmp){ssx-=0.1f;ssy-=0.1f;}else{ssx+=0.1f;ssy+=0.1f;}scale2D(ssx, ssy, tran_x, tran_y);transformVerts2D();_xtmp = x;_ytmp = y;break;default:break;}
}
//监听鼠标状态并回应相应的移动
void mymouse(int button, int state, int x, int y) {if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {switch (mode){          case TRANSLATE://平移tran_x = x;tran_y = y;break;case DRAWPOLYGON://画图tmp.x = x;tmp.y = y;xy.push_back(tmp);//将一个新的点加到vector的最后面DrawPicture();break;case ROTATE://旋转tran_x = x;tran_y = y;_xtmp = x;_ytmp = y;break;case SCALE://缩放tran_x = x;tran_y = y;break;default:break;}}
}
//监听键盘输入选择不同的移动
void myKeyboardUp(unsigned char key, int x, int y) {switch (key){case 'r':mode = TRANSLATE;break;case 'd':mode = DRAWPOLYGON;break;case 'v':mode = ROTATE;break;case 'g':mode = SCALE;break;default:break;}
}
void myDisplay() {glFlush();
}
void mymenu(int id) {if (id == 0)mode = 0;else if (id == 1)mode = 1;else if (id == 2)mode = 2;else if (id == 3)mode = 3;
}
//主函数
int main(int argc, char ** argv) {glutInit(&argc, argv);//初始化glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置绘制模式glutInitWindowPosition(500, 300);glutInitWindowSize(800, 650);glutCreateWindow("实验4.二维图形的变换");//创建窗口int id = glutCreateMenu(mymenu);//添加菜单//以下为菜单添加条目glutAddMenuEntry("TRANSLATE", 0);glutAddMenuEntry("DRAWPOLYGON", 1);glutAddMenuEntry("ROTATE", 2);glutAddMenuEntry("SCALE", 3);glutAttachMenu(GLUT_RIGHT_BUTTON);//把菜单和鼠标右键关联起来:菜单的显示方式:鼠标右键init();//进行初始化glutDisplayFunc(myDisplay);glutMouseFunc(mymouse);//鼠标监听回调函数glutMotionFunc(Drawmouse);//鼠标拖动glutKeyboardUpFunc(myKeyboardUp);//键盘弹起状态glutMainLoop();//循环调用与事件相关的函数
}

测试:

运行出来的图形窗口点击右键,出来菜单,如下点击选择画图并在窗口点击绘制的图形的顶点的位置:

继续右键选择平移:

继续点击右键选择 旋转:

继续点击右键选择缩放:

图形学实验:简单几何体的平移,缩放,旋转等几何变换,进行图形化交互相关推荐

  1. [Python从零到壹] 三十八.图像处理基础篇之图像几何变换(平移缩放旋转)

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  2. qgraphicsview鼠标移动图片_交互式QGraphicsView(平移/缩放/旋转)-阿里云开发者社区...

    简述 Graphics View提供了一个平台用于大量自定义 2D 图元的管理与交互框架包括一个事件传播架构支持场景 Scene 中的图元 Item 进行精确的双精度交互功能.Item 可以处理键盘事 ...

  3. C语言数字图像处理---1.5图像基本变换之平移缩放旋转

    本篇作为新年到来前的最后一篇,提前祝大家新年快乐! 图像几何变换又叫做图像基本变换,主要包括图像平移.图像缩放和图像旋转几个部分,当然还有图像镜像等简单的内容.图像基本变换是图像处理的基本内容,是学习 ...

  4. 变换矩阵_平移 缩放 旋转及统一变换

    1. 位移(translation) 对于一个三维坐标(x, y, z),我们想让它往x轴正方向移动1个单位,往y轴正方向移动1个单位,往z轴正方向移动1个单位,则可以让它加上一个向量(1, 1, 1 ...

  5. 线性代数:矩阵变换图形(三维平移缩放旋转)

    紧接上一篇:http://blog.csdn.net/yinhun2012/article/details/79544205 这篇博文我只是准备对上一篇博文的内容进行扩展,因为上一篇我写完二维xy仿射 ...

  6. 计算机模拟数学实验动画,计算机图形学实验-简单动画的实现、三维图形变换.docx...

    安徽大学计算机实验教学中心PAGE 安徽大学计算机实验教学中心 PAGE 1 学号 专业 姓名 实验日期2018.12.11 教师签字 成绩 实验报告 [实验名称]简单动画的实现.三维图形变换 [实验 ...

  7. iOS图片添加平移/缩放/旋转多个手势

    // // UIImageView+Utils.h // OpenWorkr // // Created by 冰凉的枷锁 on 2017/3/6. // Copyright © 2017年 Eden ...

  8. opengl矩阵变换与平移缩放旋转

    2019独角兽企业重金招聘Python工程师标准>>> 坐标系: 1.右手坐标系 2.左手坐标系 左手坐标系是X轴向右,Y轴向上,Z轴向前,右手坐标系的Z轴正好相反,是指向" ...

  9. C++-矩阵运算-Eigen-几何矩阵变换-常见几何参数求解-平移-缩放-旋转-仿射变换-垂足-面积-周长-方向角-按目标点和距离移动当前点

    文章目录 1.矩阵运算规律 1.1.矩阵相乘结合律 1.2.矩阵相乘交换律 1.3.矩阵转置 1.4.矩阵的逆 2.仿射变换 2.1.平移变换 Translation 2.2.缩放变换 Scale 2 ...

最新文章

  1. ubuntu彻底卸载mysql并且重新安装
  2. scanf函数和cin的区别、类的数组、C++排序函数
  3. CSS三栏自适应布局,左中右,上中下
  4. Mysql小练习(2)
  5. 《从零开始学ASP.NET CORE MVC》:ASP.NET Core 中的 Main方法(5)
  6. html5 video修改默认样式,HTML5中将video设置为背景的方法
  7. 电视盒安装php,全志a20安卓电视盒子安装可道云kodexplorer服务-编译安装php7.3+nginx...
  8. chrome 控制台信息获取 python_通过chrome浏览器控制台(Console)进行PHP Debug的方法
  9. python scrapy框架爬虫_Python Scrapy爬虫框架
  10. 为什么使用接口编程{转载}
  11. 算法图解学习笔记02之选择排序
  12. Linux设置封包报头的函数,GitHub - LinuxDigger/RTMP
  13. ARP的***与防护
  14. 二元函数连续与偏导数存在的关系_偏导数存在(二元函数连续性怎么判断)
  15. 【Unity】UI面板:倒计时器
  16. HTC Desire Z刷recovery刷机教程
  17. 知名插画师走尺,带你走进“薪”世界
  18. yum命令下载安装包及依赖包
  19. 我来教你如何组装一个注册中心?
  20. 要玩大数据,没有数据怎么玩?这里推荐一些33款开源爬虫软件给大家。

热门文章

  1. python如何导入模块中的类_python导入模块中类的方法
  2. 亚马逊代运营公司主要提供的七点核心服务项目
  3. mysql优化的一些奇淫技巧
  4. vuejs倒计时功能
  5. 360网站安全提示"X-Frame-Options头未设置"怎么解决
  6. Laravel框架上传文件到OSS
  7. ROS机器人RIKIBOT硬件介绍
  8. python爬虫接口_爬虫与API(上)
  9. tauri简单教程——以Flash应用为例
  10. SPPnet学习笔记