ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2022-03-01 23:32:21  阅读:289  来源: 互联网

标签:曲线 int double Bezier 贝塞尔 图形学 算法 pDC


一、实现方案

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

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

       定义:给定点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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有