6Luffy6

导航

计算机图形学实验1

欢迎大家访问我其他博客网站(微信公众号、掘金、csdn、博客园),都是同名(极客三刀流)

前言:下面任务为实验课要求之一,借助网上的学习资料、AI的辅助最终完成

参考资料

计算机图形学实验五:OpenGL下的几何变换_opengl二维几何变换-CSDN博客

任务

画一个三角形

画一个三角形,然后自己构造矩阵,不使用 glTranslate、glRotate和 glScale,而是使用 OpenGL 的 gIMutMatrixf 函数实现该三角形的平移、旋转和缩放。

效果

2.1. 平移

GLfloat translateMatrix[16] = {
    1.0f, 0.0f, 0.0f, 0.0f, // 第一列
    0.0f, 1.0f, 0.0f, 0.0f, // 第二列
    0.0f, 0.0f, 1.0f, 0.0f, // 第三列
    tx,  ty,  tz,  1.0f     // 第四列 (平移向量)
};
  • tx:控制沿 X 轴的平移(左右方向)。
  • ty:控制沿 Y 轴的平移(上下方向)。
  • tz:控制沿 Z 轴的平移(前后方向)。

2.2. 缩放

GLfloat translateMatrix[16] = {
    sx,  0.0f, 0.0f, 0.0f, // 第一列
    0.0f, sy,  0.0f, 0.0f, // 第二列
    0.0f, 0.0f, sz,  0.0f, // 第三列
    0.0f, 0.0f, 0.0f, 1.0f  // 第四列
};
  • sx:控制沿 X 轴的缩放比例。
  • sy:控制沿 Y 轴的缩放比例。
  • sz:控制沿 Z 轴的缩放比例。

2.3. 旋转

   GLfloat rotateMatrix[16] = {
        cos(rad), -sin(rad), 0.0f, 0.0f,
        sin(rad), cos(rad),  0.0f, 0.0f,
        0.0f,     0.0f,      1.0f, 0.0f,
        0.0f,     0.0f,      0.0f, 1.0f
    };

2.4. 完整代码

#include <GL/glut.h>
#include <math.h>
#include<windows.h>
#include<stdio.h>
#include <iostream>
using namespace std;
#define PI 3.14159265358979323846
#define DEG_TO_RAD (PI/180.0)  //角度转为弧度的参数

// 定义全局变量存储平移偏移量
float translateX = 0.0f;
float translateY = 0.0f;
float rotateAngle = 0.0f;  // 旋转角度
float scaleFactor = 1.0f;

void init(void)
{
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(-5.0, 5.0, -5.0, 5.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
}

void drawTriangle(void) //绘制中心在原点的三角形
{
    glBegin(GL_POLYGON); //顶点指定需要按逆时针方向
    glVertex2f(1.0f, 0.0f);//右点
    glVertex2f(0.0f, 1.0f);//上点
    glVertex2f(-1.0f, 0.0f);//左点
    glEnd();
}
void display() {
    glClear(GL_COLOR_BUFFER_BIT); //清空

    glLoadIdentity();        //将当前矩阵设为单位矩阵
    glColor3f(1.0f, 0.0f, 0.0f);//红色

    // 定义一个平移矩阵(向右平移0.5单位)
    GLfloat translateMatrix[16] = {
        1.0f, 0.0f, 0.0f, 0.0f, // 第一列
        0.0f, 1.0f, 0.0f, 0.0f, // 第二列
        0.0f, 0.0f, 1.0f, 0.0f, // 第三列
        translateX, translateY, 0.0f, 1.0f  // 第四列
    };

    // 定义旋转矩阵(绕Z轴旋转)
    float rad = rotateAngle * DEG_TO_RAD;
    GLfloat rotateMatrix[16] = {
        cos(rad), -sin(rad), 0.0f, 0.0f,
        sin(rad), cos(rad),  0.0f, 0.0f,
        0.0f,     0.0f,      1.0f, 0.0f,
        0.0f,     0.0f,      0.0f, 1.0f
    };

    // 定义缩放矩阵
    GLfloat scaleMatrix[16] = {
        scaleFactor, 0.0f,       0.0f, 0.0f,
        0.0f,       scaleFactor, 0.0f, 0.0f,
        0.0f,       0.0f,       1.0f, 0.0f,
        0.0f,       0.0f,       0.0f, 1.0f
    };


    // 将当前矩阵与平移矩阵相乘
    glMultMatrixf(translateMatrix);
    glMultMatrixf(rotateMatrix);
    
    
    glMultMatrixf(scaleMatrix);
    drawTriangle();

    glFlush();
}

// 键盘事件处理函数
void specialKeys(int key, int x, int y) {
    switch (key) {
    case GLUT_KEY_UP:
        translateY += 0.1f;
        break;
    case GLUT_KEY_DOWN:
        translateY -= 0.1f;
        break;
    case GLUT_KEY_LEFT:
        translateX -= 0.1f;
        break;
    case GLUT_KEY_RIGHT:
        translateX += 0.1f;
        break;
    }
    glutPostRedisplay(); // 触发重绘
}

// 普通键盘回调函数(A/D键)
void keyboard(unsigned char key, int x, int y) {
    if (key == 'a' || key == 'A') {
        rotateAngle -= 5.0f;
    }
    if (key == 'd' || key == 'D') {
        rotateAngle += 5.0f;
    }
    glutPostRedisplay(); // 触发重绘
}

// 鼠标滚轮回调函数
void mouseWheel(int wheel, int direction, int x, int y) {
    if (direction == GLUT_DOWN) {
        switch(wheel) {
            case 3: 
                scaleFactor *= 1.2f;
                break;
            case 4:
                scaleFactor *= 0.8f;
                break;
        }
    }

    if (scaleFactor < 0.1f) scaleFactor = 0.1f;
    if (scaleFactor > 5.0f) scaleFactor = 5.0f;
    glutPostRedisplay(); // 触发重绘
    
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(50, 100);
    glutInitWindowSize(600, 600);
    glutCreateWindow("绘制三角形");

    init();
    glutDisplayFunc(display);
    
    // 注册特殊键回调函数
    glutSpecialFunc(specialKeys);

    glutKeyboardFunc(keyboard);//普通键
    
    glutMouseFunc(mouseWheel);

    glutMainLoop();
    return 0;
}

posted on 2025-04-01 21:39  极客三刀流  阅读(24)  评论(0)    收藏  举报