OpenGL——二维几何变换
平移、旋转、缩放的实现
#include<iostream>
#include <math.h>
#include<Windows.h>
#include <GL/glut.h> using namespace std; GLsizei winWidth = , winHeight = ; GLfloat xwcMin = 0.0, xwcMax = 225.0;
GLfloat ywcMin = 0.0, ywcMax = 225.0; class wcPt2D {
public:
GLfloat x, y;
}; typedef GLfloat Matrix3x3[][]; Matrix3x3 matComposite; const GLdouble pi = 3.14159; void init()
{
//窗口背景为白色
glClearColor(1.0, 1.0, 1.0, 0.0);
} void matrix3x3SetIdentity(Matrix3x3 matIdent3x3)
{
GLint row, col;
for (row = ; row < ; row++) {
for (col = ; col < ; col++) {
matIdent3x3[row][col] = (row == col);
}
}
} void matrix3x3PreMultiply(Matrix3x3 m1, Matrix3x3 m2)
{
GLint row, col;
Matrix3x3 matTemp; for (row = ; row < ; row++) {
for (col = ; col < ; col++) {
matTemp[row][col] = m1[row][] * m2[][col] + m1[row][] * m2[][col] +
m1[row][] * m2[][col];
}
} for (row = ; row < ; row++) {
for (col = ; col < ; col++) {
m2[row][col] = matTemp[row][col];
}
}
} void translate2D(GLfloat tx, GLfloat ty)
{
Matrix3x3 matTransl; matrix3x3SetIdentity(matTransl); matTransl[][] = tx;
matTransl[][] = ty; matrix3x3PreMultiply(matTransl, matComposite);
} void rotate2D(wcPt2D pivotPt, GLfloat theta)
{
Matrix3x3 matRot; matrix3x3SetIdentity(matRot); matRot[][] = cos(theta);
matRot[][] = -sin(theta);
matRot[][] = pivotPt.x * ( - cos(theta)) + pivotPt.y * sin(theta);
matRot[][] = sin(theta);
matRot[][] = cos(theta);
matRot[][] = pivotPt.y * ( - cos(theta)) - pivotPt.x * sin(theta); matrix3x3PreMultiply(matRot, matComposite);
} void scale2D(GLfloat sx, GLfloat sy, wcPt2D fixedPt)
{
Matrix3x3 matScale; matrix3x3SetIdentity(matScale); matScale[][] = sx;
matScale[][] = ( - sx) * fixedPt.x;
matScale[][] = sy;
matScale[][] = ( - sy) * fixedPt.y; matrix3x3PreMultiply(matScale, matComposite);
} void transformVerts2D(GLint nVerts, wcPt2D * verts)
{
GLint k;
GLfloat temp; for (k = ; k < nVerts; k++) {
temp = matComposite[][] * verts[k].x + matComposite[][] * verts[k].y + matComposite[][];
verts[k].y = matComposite[][] * verts[k].x + matComposite[][] * verts[k].y + matComposite[][];
verts[k].x = temp;
}
} void triangle(wcPt2D *verts)
{
glBegin(GL_TRIANGLES);
for (GLint k = ; k < ; k++) {
glVertex2f(verts[k].x, verts[k].y);
}
glEnd();
} void displayFcn()
{
GLint nVerts = ; wcPt2D verts[] = { {50.0,25.0},{150.0,25.0},{100.0,100.0} }; wcPt2D centroidPt; GLint xSum = , ySum = ; for (GLint k = ; k < nVerts; k++) {
xSum += verts[k].x;
ySum += verts[k].y;
} centroidPt.x = GLfloat(xSum) / GLfloat(nVerts);
centroidPt.y = GLfloat(ySum) / GLfloat(nVerts); wcPt2D pivPt, fixedPt;
pivPt = centroidPt;
fixedPt = centroidPt;
GLfloat tx = 0.0, ty = 100.0;
GLfloat sx = 0.5, sy = 0.5;
GLdouble theta = pi / ; glClear(GL_COLOR_BUFFER_BIT);
glColor3f(200.0 / 255.0, 200.0 / 255.0, 169.0 / 255.0);
triangle(verts); matrix3x3SetIdentity(matComposite); scale2D(sx, sy, fixedPt); transformVerts2D(nVerts, verts);
glColor3f(137.0 / 255.0, 190.0 / 255.0, 178.0 / 255.0);
triangle(verts); matrix3x3SetIdentity(matComposite);
rotate2D(pivPt, theta);
transformVerts2D(nVerts, verts);
glColor3f(69.0 / 255.0, 137.0 / 255.0, 148.0 / 255.0);
triangle(verts); matrix3x3SetIdentity(matComposite);
translate2D(tx, ty);
transformVerts2D(nVerts, verts);
glColor3f(178.0 / 255.0, 200.0 / 255.0, 187.0 / 255.0);
triangle(verts); glFlush();
} void winReshapeFcn(GLint newWidth, GLint newHeight)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(xwcMin, xwcMax, ywcMin, ywcMax);
glClear(GL_COLOR_BUFFER_BIT);
} int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(, ); glutInitWindowSize(winWidth, winHeight);
glutCreateWindow("二维几何变换");
init();
glutDisplayFunc(displayFcn);
glutReshapeFunc(winReshapeFcn);
glutMainLoop(); system("pause");
return ;
}
运行结果

OpenGL——二维几何变换的更多相关文章
- [opengl] 画一个可移动的自行车 二维几何变换(平移、旋转、缩放)
#include <cmath> #include "glut.h" #include "iostream" using namespace std ...
- [图形学] Chp8.4 OpenGL 二维观察函数——视口
这节有几个显示窗口的控制函数,可以调整视口,创建子窗口,最小化为图标,设置图标名称,隐藏显示等. gluOrtho2D (xwmin, xwmax, ywmin, ywmax); // 定义二维裁剪窗 ...
- 【opengl】OpenGL中三维物体显示在二维屏幕上显示的变换过程
转自:http://blog.sina.com.cn/s/blog_957b9fdb0100zesv.html 为了说明在三维物体到二维图象之间,需要经过什么样的变换,我们引入了相机(Camera)模 ...
- openGL实现二维图形和三维图形
openGL是一个强大的底层图形库,其命令最初的时候使用C语言实现的.openGL定义了一个图形程序接口,常用于制作处理三维图像,功能强大,调用方便,在图像处理十分受欢迎. 实现图形主要使用的是ope ...
- OpenGL屏幕二维坐标转化成三维模型坐标
我们把OpenGL里模型的三维坐标往二维坐标的转化称为投影,则屏幕上的二维坐标往三维坐标转化则可以称为反投影,下面我们来介绍一下反投影的方法. 主要是gluUnProject函数的使用,下面是代码: ...
- VC6下OpenGL 开发环境的构建外加一个简单的二维网络棋盘绘制示例
一.安装GLUT 工具包 GLUT 不是OpenGL 所必须的,但它会给我们的学习带来一定的方便,推荐安装. Windows 环境下的GLUT 本地下载地址:glut-install.zip(大小约为 ...
- OpenGL中的二维编程——从简单的矩形开始
一.OpenGL的组成 图元函数(primitive function)指定要生成屏幕图像的图元.包括两种类型:可以在二维.三维或者四维空间进行定义的几何图元,如多边形:离散实体:位图. 属性函数(a ...
- Win窗口坐标二维坐标与OpenGl的世界坐标系的之间的相互转换
Win窗口坐标二维坐标与OpenGl的世界坐标系的转换 几何处理管线擅长于使用视图和投影矩阵以及用于裁剪的视口把顶点的世界坐标变换为窗口坐标. 但是,在有些情况下,需要逆转这个过程.一种常见的情形是: ...
- VC、OpenGL、ArcGIS Engine开发的二维三维结合的GIS系统
一.前言 众所周知,二维GIS技术发展了近四十年,伴随着计算机软硬件以及关系型数据库的飞速发展,二维GIS技术已日臻完善.在对地理信息的分析功能上有着无可比拟的优势.一些宏观的地理信息,一维的地理信息 ...
随机推荐
- DAC Essentials
http://e2e.ti.com/blogs_/b/analogwire/archive/tags/DAC%2bEssentials DAC Essentials: A new blog serie ...
- AngularJS转换请求内容
在"AngularJS中转换响应内容"中,体验了如何转换响应内容.本篇来体验如何转换请求内容. 主页面通过onSend方法把request对象转递出去. <form name ...
- C# 备份、还原、拷贝远程文件夹
最近一直都很忙,非常抱歉好久没有写过博客了.最近遇到拷贝远程文件的一些工作,比如我们发布的web站点的时候,开发提供一个zip压缩包,我们需要上传到远程的服务器A,然后在部署(文件拷贝)到远程环境B和 ...
- 微软BI 之SSIS 系列 - Lookup 中的字符串比较大小写处理 Case Sensitive or Insensitive
开篇介绍 前几天碰到这样的一个问题,在 Lookup 中如何设置大小写不敏感比较,即如何在 Lookup 中的字符串比较时不区分大小写? 实际上就这个问题已经有很多人提给微软了,但是得到的结果就是 C ...
- eclipse core expression usage
http://codeandme.blogspot.com/2012/04/expression-examples.html We need to set checkEnabled on the vi ...
- redis内部数据结构深入浅出
最大感受,无论从设计还是源码,Redis都尽量做到简单,其中运用到的原理也通俗易懂.特别是源码,简洁易读,真正做到clean and clear, 这篇文章以unstable分支的源码为基准,先从大体 ...
- 如何在页面中获取到ModelAndView绑定的值
以下内容转自:https://blog.csdn.net/qq_16071145/article/details/51341052 springMVC中通过ModelAndView进行后台与页面的数据 ...
- django --- DetailView源码分析
[背景] 最近在看django官方文档的class-based-views这一节的时候一直不得要领,感觉自己清楚,但是回想起来又没有脉络:于是没有办法只 能是“暗中观察”django的源码了. 刚打开 ...
- php中cal_days_in_month不可用时的替代方法(计算一个月的天数)
在计算某个月中的天数时,由于PHP编译时没有加上--enable-calendar选项,会导致cal_days_in_month方法不可用. 这时,如果不能更改服务器的编译设置,可以通过以下方法实现该 ...
- Socket网络编程--聊天程序(4)
上一小节讲到可以实现多客户端与服务器进行通讯,对于每一个客户端的连接请求,服务器都要分配一个进程进行处理.对于多用户连接时,服务器会受不了的,而且还很消耗资源.据说有个select函数可以用,好像还很 ...