OpenGL——二维几何变换

平移、旋转、缩放的实现

#include<iostream>
#include <math.h>
#include<Windows.h>
#include <GL/glut.h>

using namespace std;

GLsizei winWidth = 600, winHeight = 600;

GLfloat xwcMin = 0.0, xwcMax = 225.0;
GLfloat ywcMin = 0.0, ywcMax = 225.0;

class wcPt2D {
public:
    GLfloat x, y;
};

typedef GLfloat Matrix3x3[3][3];

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 = 0; row < 3; row++) {
        for (col = 0; col < 3; col++) {
            matIdent3x3[row][col] = (row == col);
        }
    }
}

void matrix3x3PreMultiply(Matrix3x3 m1, Matrix3x3 m2)
{
    GLint row, col;
    Matrix3x3 matTemp;

    for (row = 0; row < 3; row++) {
        for (col = 0; col < 3; col++) {
            matTemp[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] = matTemp[row][col];
        }
    }
}

void translate2D(GLfloat tx, GLfloat ty)
{
    Matrix3x3 matTransl;

    matrix3x3SetIdentity(matTransl);

    matTransl[0][2] = tx;
    matTransl[1][2] = ty;

    matrix3x3PreMultiply(matTransl, matComposite);
}

void rotate2D(wcPt2D pivotPt, GLfloat theta)
{
    Matrix3x3 matRot;

    matrix3x3SetIdentity(matRot);

    matRot[0][0] = cos(theta);
    matRot[0][1] = -sin(theta);
    matRot[0][2] = pivotPt.x * (1 - cos(theta)) + pivotPt.y * sin(theta);
    matRot[1][0] = sin(theta);
    matRot[1][1] = cos(theta);
    matRot[1][2] = pivotPt.y * (1 - cos(theta)) - pivotPt.x * sin(theta);

    matrix3x3PreMultiply(matRot, matComposite);
}

void scale2D(GLfloat sx, GLfloat sy, wcPt2D fixedPt)
{
    Matrix3x3 matScale;

    matrix3x3SetIdentity(matScale);

    matScale[0][0] = sx;
    matScale[0][2] = (1 - sx) * fixedPt.x;
    matScale[1][1] = sy;
    matScale[1][2] = (1 - sy) * fixedPt.y;

    matrix3x3PreMultiply(matScale, matComposite);
}

void transformVerts2D(GLint nVerts, wcPt2D * verts)
{
    GLint k;
    GLfloat temp;

    for (k = 0; k < nVerts; k++) {
        temp = matComposite[0][0] * verts[k].x + matComposite[0][1] * verts[k].y + matComposite[0][2];
        verts[k].y = matComposite[1][0] * verts[k].x + matComposite[1][1] * verts[k].y + matComposite[1][2];
        verts[k].x = temp;
    }
}

void triangle(wcPt2D *verts)
{
    glBegin(GL_TRIANGLES);
    for (GLint k = 0; k < 3; k++) {
        glVertex2f(verts[k].x, verts[k].y);
    }
    glEnd();
}

void displayFcn()
{
    GLint nVerts = 3;

    wcPt2D verts[3] = { {50.0,25.0},{150.0,25.0},{100.0,100.0} };

    wcPt2D centroidPt;

    GLint xSum = 0, ySum = 0;

    for (GLint k = 0; 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 / 2;

    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(50, 50);

    glutInitWindowSize(winWidth, winHeight);
    glutCreateWindow("二维几何变换");
    init();
    glutDisplayFunc(displayFcn);
    glutReshapeFunc(winReshapeFcn);
    glutMainLoop();

    system("pause");
    return 0;
}

运行结果

原文地址:https://www.cnblogs.com/farewell-farewell/p/9425153.html

时间: 2024-10-11 23:18:02

OpenGL——二维几何变换的相关文章

[图形学]Chapter 8.4 OpenGL 二维观察函数——视口

这节有几个显示窗口的控制函数,可以调整视口,创建子窗口,最小化为图标,设置图标名称,隐藏显示等. gluOrtho2D (xwmin, xwmax, ywmin, ywmax); // 定义二维裁剪窗口 glViewport(xvmin, yvmin, vpWidth, vpHeight); // 指定视口参数 其中,视口内的显示坐标由gluOrtho2D定义.如下例: 显示窗口为600*300,屏幕被glViewPort分割成4个视口,每块是300*150每个视口里的坐标是由glOrtho2D

4.4.1 二维复合矩阵编程实例

(a)变换前的三角形                 (b)变换后的三角形          (c)程序显示结果 #include <GL/glut.h> #include <stdlib.h> #include <math.h> /* 初始化显示窗口大小 */ GLsizei winWidth=600,winHeight=600; /* 设置世界坐标系的显示范围 */ GLfloat xwcMin=0.0,xwcMax=225.0; GLfloat ywcMin=0.

[OpenGL] 简单二维粒子系统——烟花,喷水,落叶

参考代码:http://download.csdn.net/detail/blue6333589/6785389 在这个代码的基础上扩展了二维粒子系统的框架,该系统由一个发射器类和一个粒子类组成,作为编程练习而言,我们只实现了最基本的粒子系统功能,但是已经可以做出一些效果了. 在这里,通过调节参数给出了在这个框架下烟花.喷水.落叶的代码,参考代码实现的是飘雪:只要在物理参数模拟和贴图选择上做得足够好,也可以实现火焰.爆炸等效果. 发射器 其中发射器类支持从点发射和从直线发射,暂时不支持曲线(编程

二维图形的几何变换【转】

转自:lab104_yifan http://blog.csdn.net/accelerator_/article/details/39253983 1.基本几何变换及变换矩阵 基本几何变换都是相对于坐标原点和坐标轴进行的几何变换,有平移.比例.旋转.反射和错切等. 1.1 平移变换 是指将p点沿直线路径从一个坐标位置移到另一个坐标位置的重定位过程.他是一种不产生变形而移动物体的刚体变换(rigid-body transformation),如下图所示. 图1-1 平移变换 推导: 求得平移变换

openGL实现二维图形和三维图形

openGL是一个强大的底层图形库,其命令最初的时候使用C语言实现的.openGL定义了一个图形程序接口,常用于制作处理三维图像,功能强大,调用方便,在图像处理十分受欢迎. 实现图形主要使用的是openGL的一个工具包:GLUT. GLUT (pronounced like the glut in gluttony) is the OpenGL Utility Toolkit, a window system independent toolkit for writing OpenGL prog

Win窗口坐标二维坐标与OpenGl的世界坐标系的转换

Win窗口坐标二维坐标与OpenGl的世界坐标系的转换 1. 首先明白Win环境的窗口二维坐标系表示 即,Win的屏幕坐标的坐标系表示如下:左上为坐标系原点,正右为X轴正方向, 正下方为Y轴正方向.    2. 在了解一下Opengl的视口坐标系 Opengl设置视口操作如下: glViewport(0,0,m_wide,m_heigth); 3. 关于opengl的世界坐标系,用户坐标系,模型坐标系可以查看博客 http://www.cnblogs.com/icmzn/p/5003600.ht

OpenGL(一)二维图形的绘制:图元、多边形、颜色插值、文本、查询与错误、状态的保存

图元三种基本类型:点.直线段.多边形.其他复杂的对象均是由这三种图元来构建. 点 void glPointsize(GLfloat size)  //对点尺寸状态变量进行设定,单位为像素,默认值1.0 注:glPointSize()不能放置在glBegin()和glEnd()函数之间. 直线 glBegin(mode) 绘制直线时,mode可取下列值: GL_LINES:glBegin()和glEnd()函数之间每两个连续顶点绘制一条线段. GL_LINE_STRIP:首尾相接的线段. GL_L

[计算机图形学 with OpenGL] Chapter8 习题8.12 NLN二维线段裁剪算法实现

Nicholl-Lee-Nicholl二维线段裁剪算法相对于Cohen-Sutherland和Liang-Barsky算法来说,在求交点之前进行了线段端点相对于几个区域的判断,可以确切的知道要求交点的边的信息. 此方法只在二维空间裁剪时使用,C-S和L-B裁剪方法则可应用到三维空间. 算法步骤: 1 先使用C-S裁剪算法的区域码判断方法,去除一部分在裁剪区域外面的线段.显示在完全在裁剪区域内的线段.其他不能判断的情况,采用NLN算法进行裁剪. 2 p1和p2若有一点在区域内,必要时交换端点以确保

openGL+VS2010的例程--立体四面体(二维)

说明:通过6条线段组合,构造一个立体四面体,是最基本的二维实现. 实现代码如下: #include <GL/glut.h> void init(void) { glClearColor(1.0, 1.0, 1.0, 0.0); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0, 200.0, 0.0, 150.0); } void lineSegment(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0