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

news/2025/2/13 3:24:10/

程序截图

 

简单说明

这个函数就是

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


http://www.ppmy.cn/news/3657.html

相关文章

【刷题笔记】之牛客面试必刷TOP101(二分查找-I + 二维数组中的查找 + 寻找峰值 + 数组中的逆序对 + 旋转数组的最小数字 + 比较版本号)

目录 1. 二分查找-I 2. 二维数组中的查找 3. 寻找峰值 4. 数组中的逆序对 5. 旋转数组的最小数字 6. 比较版本号 1. 二分查找-I 题目链接&#xff1a;二分查找-I_牛客题霸_牛客网 (nowcoder.com) 题目要求&#xff1a; 上代码 import java.util.*;public class Solut…

easyExcel导出表头合并 不得不说真牛

有个导出单元格合并的任务&#xff0c;表头不规则合并格式&#xff0c;看得就烦&#xff0c;尤其是对于没玩儿过合并的我来说&#xff0c;任务放在哪里不知咋做&#xff0c;网上也看了一堆合并的方法&#xff0c;自己写注解来写的那些&#xff0c;麻烦得要命&#xff0c;我写一…

【2022.12.15】备战春招Day10——每日一题 + 34. 在排序数组中查找元素的第一个和最后一个位置 + 30. 二叉搜索树的最小绝对差

【每日一题】1945. 字符串转化后的各位数字之和 题目描述 给你一个由小写字母组成的字符串 s &#xff0c;以及一个整数 k 。 首先&#xff0c;用字母在字母表中的位置替换该字母&#xff0c;将 s 转化为一个整数&#xff08;也就是&#xff0c;‘a’ 用 1 替换&#xff0c;‘…

Elasticsearch版本升级实践、注意事项

版本关系 从官方文档看可以发现两个大版本升级需要关注到具体的版本&#xff0c;比如想从 5.x 版本升级到 7.x 版本&#xff0c;就必须先升级到 6.8 版本&#xff0c;再从 6.8 升级到 7.x 版本。 检查是否可以升级 1. 版本号确认 2. 通过API检查是否存在过期的用法 # ES 6.xG…

班级网页制作 HTML个人网页设计 我的班级网站设计与实现 大学生简单班级静态HTML网页设计作品 DIV布局班级网页模板代码 DW学生校园网站制作成品下载

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

建筑建材企业如何高效进行合同签署?数商云B2B系统推动企业合同签约规范化

建筑建材行业作为重要的材料工业&#xff0c;其主要产品包括建筑材料及制品、非金属矿及制品、无机非金属新材料三大门类&#xff0c;现广泛应用于建筑、军工、环保、高新技术产业和人民生活等领域&#xff0c;占国民生产总值的20&#xff05;左右&#xff0c;但目前建筑建材行…

Python自定义模块的创建与使用

文章目录一、前言二、模块的概述三、自定义模块附&#xff1a;python打包用户自定义模块一、前言 在Python提供了强大的模块支持&#xff0c;主要体现为不仅在Python标准库中包含了大量的模块&#xff08;称为标准模块&#xff09;&#xff0c;而且还有很多第三方模块&#xf…

JavaWeb语法二:Thread类的基本使用

目录 1.创建线程 1.2&#xff1a;run()和start()方法 1.3&#xff1a;Thread的几个常见属性 2.线程的有关操作 2.1&#xff1a;启动一个线程&#xff1a;start() 2.2&#xff1a;中断一个线程 2.2.1&#xff1a;使用自定义的变量来作为标志位 2.2.2&#xff1a;使用Thr…