当前位置: 首页 > news >正文

C语言画贝塞尔曲线的函数

程序截图

 

简单说明

这个函数就是

void drawBezierCurve(COLORREF color, const unsigned int len, ...)

color 是贝塞尔曲线的颜色,len 是画出贝塞尔曲线所需要的点的个数,最少 1 个,不要乱传。之后的参数传的就是画出贝塞尔曲线要的点,数据类型为 Vec2。

这个函数实现的基础是参数方程,用参数方程将一条直线转化为一个参数的方程,如:

A * x + B * y + C=0 可以转化为 x = x0 - B * t;y = y0 + A * t,x0、y0 为直线上任意一个点的横纵坐标值,t 为未知参数。

对于一条线段,可以根据线段上两个端点转化为参数方程:

x = x0 + (x1 - x0) * t

y = y0 + (y1 - y0) * t

t ∈ [0, 1]

将这条线段分为 CURVEPIECE 份,t 从 0 到 1 一份一份地加,就能得到这条线段上均匀分布的 CURVEPIECE 个点。

贝塞尔曲线就是对 n 个点连线组成的 n 条(线段上对应份的点)的连线的 (n - 1) 条(线段的对应份点)的连线的……直到最后 1 条线段上(对应份点的连线)。

这个曲线的算法如果用递归的话可能会占用很大内存,毕竟每一轮的点的值都保存下来了,我这里用循环做,空间占用只有两轮内点的值。

代码实现


// 程序:画贝塞尔曲线的函数
// 编译环境:Visual Studio 2019,EasyX_20211109
//


#include <graphics.h>
#include <conio.h>
using namespace std;

// 画贝塞尔曲线的函数,包括这个 Vec2 结构体
struct Vec2
{
	double x, y;
};
void drawBezierCurve(COLORREF color, const unsigned int len, ...)
{
	if (len <= 0) return;

	va_list list;
	va_start(list, len);
	Vec2* temp = new Vec2[len];
	for (int i = 0; i < len; i++)
		temp[i] = va_arg(list, Vec2);
	va_end(list);

	if (len == 1)
	{
		putpixel(temp->x, temp->y, color);
		return;
	}

	Vec2* parent = nullptr, * child = nullptr;
	Vec2 lastPoint = temp[0];
	setlinecolor(color);
	for (double LineNum = 0; LineNum < 1 + 1.0 / 100; LineNum += 1.0 / 100)
	{
		int size = len;
		parent = temp;
		while (size > 1)
		{
			child = new Vec2[size - 1];
			for (int i = 0; i < size - 1; i++)
			{
				child[i].x = parent[i].x + (parent[i + 1].x - parent[i].x) * LineNum;
				child[i].y = parent[i].y + (parent[i + 1].y - parent[i].y) * LineNum;
			}
			if (parent != temp)delete[] parent;
			parent = child;
			size--;
		}
		line(lastPoint.x, lastPoint.y, parent->x, parent->y);
		lastPoint.x = parent->x;
		lastPoint.y = parent->y;
		delete[] parent;
		parent = nullptr;
		child = nullptr;
	}
	delete[] temp;
}

int main()
{
	initgraph(640, 480);

	Vec2 a = { 100, 80 };
	Vec2 b = { 540, 80 };
	Vec2 c = { 540, 400 };
	Vec2 d = { 100, 400 };

	setlinecolor(BLUE);
	line(a.x, a.y, b.x, b.y);
	line(b.x, b.y, c.x, c.y);
	line(c.x, c.y, d.x, d.y);

	drawBezierCurve(RED, 4, a, b, c, d);

	_getch();
	closegraph();
	return 0;
}

点击链接加入群聊【C语言/C++编程学习基】:

小鱼快来啊的个人空间-小鱼快来啊个人主页-哔哩哔哩视频哔哩哔哩小鱼快来啊的个人空间,提供小鱼快来啊分享的视频、音频、文章、动态、收藏等内容,关注小鱼快来啊账号,第一时间了解UP注动态。编程学习群:724050348 每天分享一个编程小游戏~C/C++游戏源码素材及各种安装包, 私信不常看!https://space.bilibili.com/1827181878?spm_id_from=333.1007.0.0

相关文章:

  • 电脑重装系统后卡顿怎么办?教你快速解决电脑卡顿问题
  • 2022,itbird的年终总结报告
  • java面试强基(22)
  • [ vulhub漏洞复现篇 ] struts2远程代码执行漏洞s2-059(CVE-2019-0230)
  • 不愧是阿里资深架构师,这本“分布式架构笔记”写得如此透彻明了
  • 小程序canvas 缩放/拖动/还原/封装和实例--开箱即用
  • 【MySQL】数据库基础知识汇总和增删改查操作
  • TCP/IP 网络原理【TCP篇】
  • python实现新年倒计时代码
  • vscode执行npm install 报错(npm ERR! code 128...raphael.git...)的解决办法
  • 深度学习炼丹-超参数设定和网络训练
  • 使用小爱同学语音控制电脑关机 - Winform C#
  • 左值和右值
  • 【LeetCode题目详解】(一)27.原地移除元素、88.合并两个有序数组
  • 【檀越剑指大厂—Nginx】Nginx篇
  • Nacos配置管理
  • 【C进阶】第十篇——数据在内存中的存储
  • Qt实现全局鼠标事件监听器-Windows
  • 基于LEACH和HEED的WSN路由协议研究与改进(Matlab代码实现)
  • JDBC连接数据库详解~
  • 民营经济促进法出台,自今年5月20日起施行
  • 神十九飞船已撤离空间站,计划于今日中午返回东风着陆场
  • 中信银行一季度净利195.09亿增1.66%,不良率持平
  • 何立峰出席驻沪中央金融机构支持上海建设国际金融中心座谈会并讲话
  • 神舟十九号载人飞船因东风着陆场气象原因推迟返回
  • 日本希望再次租借大熊猫,外交部:双方就相关合作保持密切沟通