计算机图形学:C++贝塞尔曲线(Bezier)的实现

计算机图形学:C++贝塞尔曲线(Bezier)的实现

  • 前言
    • 关于Bezier曲线的理解
    • 可执行程序

前言

初次学习这个Bezier曲线的时候,觉得课本的一些介绍乱七八糟,本着便于大家理解的原则,我就从便于大家理解的角度——递推算法角度介绍Bezier曲线。如果想通过这篇文章理解Bernstein基函数的,可以绕路了。
结尾附实现源码(vs2019 C++ EaxyX环境)

关于Bezier曲线的理解

首先需要简单了解一下Bezier曲线为什么要被发明出来——因为需要计算机绘制曲线,而没有系统有效的方法绘制出来,所以就有人研究出来了这个东西。(本人是这么理解的。。。)
那么,怎么有效画出来?其实就是下面两张ppt的事。
计算机图形学:C++贝塞尔曲线(Bezier)的实现_第1张图片

这个过程其实是动态的,
P 0 P 0 1 P 0 P 1 = t \tfrac{P_0P_0^1}{P_0P_1}=t P0P1P0P01=t

P 1 P 1 1 P 1 P 2 = t \tfrac{P_1P_1^1}{P_1P_2}=t P1P2P1P11=t

P 0 1 P 0 2 P 0 1 P 1 1 = t \tfrac{P_0^1P_0^2}{P_0^1P_1^1}=t P01P11P01P02=t

t ϵ [ 0 , 1 ] t\epsilon[0,1] tϵ[0,1]
t从0逐渐递增到1,这个过程完成,就成了我们所看到的曲线。
当然,这其实是最简单的Bezier曲线,这里大家可以思考一下,如果 P 2 P_2 P2向左下角延伸出一条线段 P 2 P 3 P_2P_3 P2P3,那么这个绘制过程会怎么样?
计算机图形学:C++贝塞尔曲线(Bezier)的实现_第2张图片
计算机图形学:C++贝塞尔曲线(Bezier)的实现_第3张图片
这个结果图我画的简单了点,对应的点没有标出来,读者自行体会。
同样,t的从0到1的递增能够画出了Bezier曲线
计算机图形学:C++贝塞尔曲线(Bezier)的实现_第4张图片
这张图就提供了怎么转成可执行源码的思路了。
我个人觉得递推算法是才是能够理解Bezier曲线的途径。

可执行程序

#include 
#include 
#include 
#include 
using namespace std;
class Point//简单写的一个Point的数据结构
{
public:
	int x, y;
	Point(int x1, int y1)
	{
		x = x1;
		y = y1;
	}
	Point()
	{
		x = 0;
		y = 0;
	}
	void Set(int x1, int y1)
	{
		x = x1;
		y = y1;
	}
};
int main()
{
	initgraph(1000, 1000);
	//简单画出一个六边形
	line(250, 50, 750, 50);
	line(750, 50, 1000, 300);
	line(1000, 300, 750, 550);
	line(750, 550, 250, 550);
	line(250, 550, 0, 300);
	line(0, 300, 250, 50);
	
	//把相应点初始化
	Point P[7];
	P[0].Set(250, 50);
	P[1].Set(750, 50);
	P[2].Set(1000, 300);
	P[3].Set(750, 550);
	P[4].Set(250, 550);
	P[5].Set(0,300);
	P[6].Set(250, 50);
	int n = 4;//P[0]-P[n-1]参与绘制Bezier曲线
	Point PO;
	double t;
	for (t = 0; t < 1; t += 0.000001)
	{
		//每一次运算都要重新赋一次初始值
		P[0].Set(250, 50);
		P[1].Set(750, 50);
		P[2].Set(1000, 300);
		P[3].Set(750, 550);
		//参照n的值,一直赋初始值到P[n-1]
		
		int x = n;
		while (1)
		{
			if (x == 1)
				break;
			for (int i = 0; i < x - 1; i++)
			{
				PO.x = ((1 - t) * P[i].x + t * P[i + 1].x);
				PO.y = ((1 - t) * P[i].y + t * P[i + 1].y);
				P[i] = PO;
			}
			x--;
		}
		putpixel(P[0].x, P[0].y, RED);
		//计算出比例系数为t时对应的Bezier曲线上的点,画出该点。
	}
	getchar();
}

执行结果:
计算机图形学:C++贝塞尔曲线(Bezier)的实现_第5张图片
程序写的比较原始,没有加工,没有写得规律很普适,但是简单理解应该是没问题了。

你可能感兴趣的:(c++,算法,几何学)