计算机图形学:Bezier曲线的绘制

2023-11-17

1.实验目的
掌握Bezier曲线的定义原理及绘制过程

定义:
贝塞尔曲线(Bezier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。

2. 实验要求:
利用OpenGL实现一个三次Bezier曲线,任意输入四个控制点,绘制出对应的贝塞尔曲线;并通过鼠标调整控制点(随机变化或沿某种图案变化)让曲线动态显示。

3.实验代码(部分)
需要先安装glut库

#include<GL/glut.h>
#include<GL/GL.h>
#include<math.h>
void mouseClick(int button, int state, int x, int y)
{
	if (button == GLUT_LEFT_BUTTON)  
	{
		if (state == GLUT_DOWN) {
			if (mask == -1) {
				for (int i = 0; i < 4; i++)
				{
					float mouse_x = (x - 200) / 200.0f, mouse_y = (200 - y) / 200.0f;
					float dis = sqrt((mouse_x - ctrl_points[i][0]) * (mouse_x - ctrl_points[i][0]) + (mouse_y - ctrl_points[i][1]) * (mouse_y - ctrl_points[i][1]));
					if (dis < 0.1f) mask = i;
				}

			}

		}
		else if (state == GLUT_UP)
			mask = -1;
	}
}

deCateljau算法:
在C++中,Bezier曲线常使用deCateljau算法生成,其思想就是每一次都遍历相邻的控制点,根据给定参数t在两相邻控制点形成的线段上取一个新的控制点。这样,每遍历一遍之前的控制点后生成的新控制点会更加逼近Bezier曲线,且控制点的数量减1,当最后只剩一个控制点时,可以将这个控制点视为Bezier曲线上的点。

void de_Cateljau(int n, GLfloat list[][2])
{
	float R_x[4];
	float R_y[4];

	int k = 0;
	for (double t = 0.0; t <= 1; t += 0.1)
	{
		for (int i = 0; i < n; i++) {
			R_x[i] = ctrl_points[i][0];
			R_y[i] = ctrl_points[i][1];

		}
		
		for (int i = 1; i < n; i++)
		{
			for (int j = 0; j < n - i; j++)
			{
				R_x[j] = (1 - t) * R_x[j] + t * R_x[j + 1];
				R_y[j] = (1 - t) * R_y[j] + t * R_y[j + 1];
			}
			
		}
		list[k][0] = R_x[0];
		list[k][1] = R_y[0];
		k++;
	}
}

绘制函数:

void display() {
	glClearColor(1.0, 1.0, 1.0, 1.0);//(R,G,B,alpha)自己设置
	glClear(GL_COLOR_BUFFER_BIT);//当前可写的颜色缓冲

	glPointSize(3);  
	glColor3f(0.530.510.78);
	for (int i = 0; i < 4; i++) {
		glBegin(GL_POINTS);//把每个顶点作为一个点进行处理,顶点n定义了点n,绘制N个点。
		glVertex2fv(&ctrl_points[i][0]);
		glEnd();

	}

	glColor3f(0.530.510.78);
	glBegin(GL_LINE_STRIP);//绘制从第一个顶点到最后一个顶点依次相连的一组线段,第n和n+1个顶点定义了线段n,绘制n-1条线段
	for (int i = 0; i < 4; i++) {
		glVertex2fv(&ctrl_points[i][0]);

	}
	glEnd();

	GLfloat pos_list[11][2] = { 0 };
	de_Cateljau(4, pos_list);

	glColor3f(1.0, 1.0, 0.0);
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i < 11; i++) {
		glVertex2fv(pos_list[i]);//指定顶点

	}
	glEnd();
	glFlush();//强制刷新缓冲,保证绘图命令将被执行

}

4.结果样例图
在这里插入图片描述
可以拖动任意点改变bezier曲线的形状。完整源码点这里获取。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算机图形学:Bezier曲线的绘制 的相关文章

  • EF Core Group By 翻译支持条件总和

    听说 EF Core 2 1 将支持翻译小组 我感到非常兴奋 我下载了预览版并开始测试它 但发现我在很多地方仍然没有得到翻译分组 在下面的代码片段中 对 TotalFlagCases 的查询将阻止翻译分组工作 无论如何 我可以重写这个以便我
  • 线性/非线性纹理映射扭曲的四边形

    In my 上一个问题 https stackoverflow com questions 10832909 quad strip texturing distortion 已经确定 当对四边形进行纹理化时 面被分解为三角形 并且纹理坐标以
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 为什么当实例化新的游戏对象时,它没有向它们添加标签? [复制]

    这个问题在这里已经有答案了 using System Collections using System Collections Generic using UnityEngine public class Test MonoBehaviou
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况

随机推荐