编程语言
首页 > 编程语言> > 计算机图形学:三次Bezier曲线的绘制(算法原理及代码实现)

计算机图形学:三次Bezier曲线的绘制(算法原理及代码实现)

作者:互联网

一、实现方案

       贝塞尔曲线原理:贝塞尔曲线是计算机图形图像造型的基本工具,是图形造型运用得最多的基本线条之一。它通过控制曲线上的四个点(起始点、终止点以及两个相互分离的中间点)来创造、编辑图形。其中起重要作用的是位于曲线中央的控制线。这条线是虚拟的,中间与贝塞尔曲线交叉,两端是控制端点。移动两端的端点时贝塞尔曲线改变曲线的曲率(弯曲的程度);移动中间点(也就是移动虚拟的控制线)时,贝塞尔曲线在起始点和终止点锁定的情况下做均匀移动。注意,贝塞尔曲线上的所有控制点、节点均可编辑。

       具体实现通过贝塞尔公式推导:

       定义:给定点Po,P..... Pn,则n次贝塞尔曲线由下式给出:

       n次贝塞尔曲线的公式可由如下递归表达:

        进一步可以得到贝塞尔曲线的递推计算公式:

       所以,想要实现三次Bezier曲线的绘制,只需要令n=k,可得公式为:

       为了更好的通过计算机来实现此公式,通过相应的转换,可以得到三次Bezier曲线的矩阵,再通过此推导公式从t=0到t=1之间连续绘制100个点即可得到Bezier曲线。   

 

二、代码实现

 

//坐标点
struct Point
{
	double x, y;
};

int fac(int n) {
	if (n == 1 || n == 0)
		return 1;
	else
		return n * fac(n - 1);
}

double powi(double base, int n) {
	double res = 1;
	for (int i = 1; i <= n; ++i)
		res *= base;
	return res;
}

void DrawBezierCurve(Point* p, int n, CDC* pDC,int color) {
	double a, b;
	double temp, temp1, temp2, bi;
	for (double t = 0.0; t <= 1; t += 0.01) {
		a = 0.0; b = 0.0;
		for (int i = 0; i <= n; ++i) {
			temp = double(fac(n) / fac(i) / fac(n - i));
			temp1 = powi(t, i);
			temp2 = powi(1 - t, n - i);
			bi = temp * temp1 * temp2;
			a = a + bi * p[i].x;
			b = b + bi * p[i].y;
		}
		CPen m_newPen, * m_oldPen;
		//创建新画笔
		m_newPen.CreatePen(PS_SOLID, 2, color);
		//将新画笔选入设备上下文,并且保存旧画笔
		m_oldPen = pDC->SelectObject(&m_newPen);
		if (t == 0) {
           pDC->MoveTo(a, b);
		}
		else {
           pDC->LineTo(a, b);
		}
		pDC->SelectObject(m_oldPen);
	}
}

Ondraw代码:

Point p[4] = { {28,5},{30,20},{35.25},{40,5}};
	DrawBezierCurve(p,3, pDC,RGB(10,222,55));
	Line(pDC, p[0], p[1]);
	Line(pDC, p[1], p[2]);
	Line(pDC, p[2], p[3]);

三、代码结果

 

标签:曲线,int,double,Bezier,贝塞尔,图形学,算法,pDC
来源: https://blog.csdn.net/qq_55982881/article/details/123218926