From c7308a04d384e2f0c3ea0a1e614a7e8ff7c15215 Mon Sep 17 00:00:00 2001 From: biss Date: Tue, 12 May 2026 14:10:16 +0800 Subject: [PATCH] sy4 --- .gitignore | 1 + lab4/lab4.cpp | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 .gitignore create mode 100644 lab4/lab4.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea23616 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.dll \ No newline at end of file diff --git a/lab4/lab4.cpp b/lab4/lab4.cpp new file mode 100644 index 0000000..1ea02c9 --- /dev/null +++ b/lab4/lab4.cpp @@ -0,0 +1,109 @@ +#include // 引入 GLUT/OpenGL 头文件,提供窗口和绘图函数。 + +// 定义窗口宽度和高度。 +const int WIDTH = 800; // 定义窗口宽度为 800 像素。 +const int HEIGHT = 600; // 定义窗口高度为 600 像素。 + +struct Point { // 定义用于保存坐标点的结构体。 + double x; // 保存点的 x 坐标。 + double y; // 保存点的 y 坐标。 +}; // 结构体定义结束。 + +// 定义三次 Bezier 曲线的四个控制点。 +Point p0 = { -300.0, -100.0 }; // 定义第一个控制点。 +Point p1 = { 0.0, 200.0 }; // 定义第二个控制点。 +Point p2 = { 200.0, 300.0 }; // 定义第三个控制点。 +Point p3 = { 300.0, 100.0 }; // 定义第四个控制点。 + +Point bezier(double t) { // 根据参数 t 计算三次 Bezier 曲线上的点。 + double u = 1.0 - t; // 计算 1-t,便于代入 Bezier 曲线公式。 + + Point p; // 定义曲线上的当前点。 + p.x = u * u * u * p0.x + 3 * t * u * u * p1.x + 3 * t * t * u * p2.x + t * t * t * p3.x; // 根据三次 Bezier 公式计算 x 坐标。 + + p.y = u * u * u * p0.y + 3 * t * u * u * p1.y + 3 * t * t * u * p2.y + t * t * t * p3.y; // 根据三次 Bezier 公式计算 y 坐标。 + + return p; // 返回计算得到的曲线点。 +} + +void drawAxis() { // 定义绘制坐标轴的函数,便于观察控制点和曲线位置。 + glColor3f(0.5f, 0.5f, 0.5f); // 设置绘制颜色为灰色。 + glLineWidth(1.0f); // 设置线宽为 1 像素。 + + glBegin(GL_LINES); // 开始按线段方式提交顶点。 + glVertex2d(-400.0, 0.0); // 提交 x 轴左端点。 + glVertex2d( 400.0, 0.0); // 提交 x 轴右端点。 + glVertex2d(0.0, -200.0); // 提交 y 轴下端点。 + glVertex2d(0.0, 400.0); // 提交 y 轴上端点。 + glEnd(); // 结束坐标轴顶点提交。 +} + +void drawControlPolygon() { // 定义绘制控制多边形的函数。 + glColor3f(0.0f, 0.0f, 1.0f); // 设置绘制颜色为蓝色。 + glLineWidth(2.0f); // 设置线宽为 2 像素。 + + glBegin(GL_LINE_STRIP); // 开始按连续折线方式提交顶点。 + glVertex2d(p0.x, p0.y); // 提交第一个控制点。 + glVertex2d(p1.x, p1.y); // 提交第二个控制点。 + glVertex2d(p2.x, p2.y); // 提交第三个控制点。 + glVertex2d(p3.x, p3.y); // 提交第四个控制点。 + glEnd(); // 结束控制多边形顶点提交。 +} + +void drawBezierCurve() { // 定义绘制三次 Bezier 曲线的函数。 + glColor3f(1.0f, 1.0f, 0.0f); // 设置绘制颜色为黄色。 + glLineWidth(3.0f); // 设置线宽为 3 像素。 + + double dt = 1.0 / 10000.0; // 定义参数 t 每次增加的步长,步长越小曲线越平滑。 + + glBegin(GL_LINE_STRIP); // 开始按连续折线方式绘制曲线。 + for (double t = 0.0; t <= 1.0; t += dt) { // 从 0 到 1 逐步取点。 + Point p = bezier(t); // 计算当前参数对应的曲线点。 + glVertex2d(p.x, p.y); // 提交当前曲线点。 + } + glEnd(); // 结束曲线顶点提交。 +} + +void drawControlPoints() { // 定义绘制控制点的函数。 + glColor3f(1.0f, 0.0f, 0.0f); // 设置绘制颜色为红色。 + glPointSize(8.0f); // 设置控制点大小为 8 像素。 + + glBegin(GL_POINTS); // 开始按点方式提交顶点。 + glVertex2d(p0.x, p0.y); // 提交第一个控制点。 + glVertex2d(p1.x, p1.y); // 提交第二个控制点。 + glVertex2d(p2.x, p2.y); // 提交第三个控制点。 + glVertex2d(p3.x, p3.y); // 提交第四个控制点。 + glEnd(); // 结束控制点顶点提交。 +} + +void myDisplay() { // 定义窗口重绘时调用的显示函数。 + glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓冲区。 + + drawAxis(); // 绘制坐标轴。 + drawControlPolygon(); // 绘制控制多边形。 + drawBezierCurve(); // 绘制三次 Bezier 曲线。 + drawControlPoints(); // 绘制控制点。 + + glFlush(); // 强制执行所有尚未执行的 OpenGL 绘图命令。 +} + +void Init() { // 定义初始化函数。 + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // 设置背景颜色为黑色。 + glMatrixMode(GL_PROJECTION); // 切换到投影矩阵模式。 + glLoadIdentity(); // 将当前投影矩阵重置为单位矩阵。 + gluOrtho2D(-400.0, 400.0, -200.0, 400.0); // 设置二维正交投影范围。 +} + +int main(int argc, char** argv) { // 程序入口函数,接收命令行参数。 + glutInit(&argc, argv); // 初始化 GLUT。 + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // 设置显示模式为 RGB 颜色和单缓冲。 + glutInitWindowSize(WIDTH, HEIGHT); // 设置窗口大小为 WIDTH x HEIGHT。 + glutInitWindowPosition(100, 100); // 设置窗口初始显示位置。 + glutCreateWindow("实验3_03毕爽爽 三次Bezier曲线"); // 创建窗口并设置标题。 + + Init(); // 调用初始化函数。 + glutDisplayFunc(myDisplay); // 注册显示回调函数。 + + glutMainLoop(); // 进入 GLUT 事件处理主循环。 + return 0; +}