贝塞尔曲线原理、推导及Matlab实现

news/2024/7/7 9:02:17/文章来源:https://www.cnblogs.com/zbyisgudi/p/18284215

贝塞尔曲线原理、推导及Matlab实现

贝塞尔曲线原理、推导及Matlab实现

一、简介

贝塞尔曲线提出

在数学的数值分析领域中,贝塞尔曲线(English:Bézier curve)是计算机图形学中相当重要的参数曲线。更高维度的广泛化贝塞尔曲线就称作贝兹曲面,其中贝兹三角是一种特殊的实例。

贝塞尔曲线于1962年,由法国工程师皮埃尔·贝兹Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由保尔·德·卡斯特里奥于1959年运用德卡斯特里奥算法开发,以稳定数值的方法求出贝塞尔曲线。

贝塞尔曲线与F1的渊源

说到皮埃尔·贝兹,就不得不提他作为雷诺公司的一名工程师,曾引领了设计和制造业的转型,将它们从单纯使用数学和计算工具带向了计算机辅助设计和三维模型,同时是实体造型、几何模型和物理模型领域的奠定者之一。

而雷诺公司早期于1977年开始,作为车队和发动机供应商在不同时期里参加了F1(一级方程式赛事)。在1977年的最后五站比赛中,雷诺以厂队的身份踏进了F1比赛,并且将涡轮增压器引入其第一款赛车雷诺 RS01中却遭众人嘲笑,然而在法国的分站赢得胜利之后,不到两年时间,所有一流车队都改用涡轮发动机。在1992年雷诺凭英国车手文素和威廉士车队拿下史上第一个年度车队冠军,而接下来五年的年度车队冠军也都是使用雷诺发动机(除1995年是班尼顿,其余皆为威廉士),不过随着其在98年退出F1,雷诺在F1的霸业也宣告结束。雷诺在2000年接手贝纳通车队重返一级方程式赛车。在2002年,车队改名为雷诺一级方程式车队,更在2005年和2006年赛季中同时夺得车队和车手世界冠军。

现今雷诺公司旗下的F1车队为AlpineF1车队(法语:Alpine F1 Team),全名倍世AlpineF1车队(法语:BWT Alpine F1 Team)。本赛季Alpine车队的新赛车A524在赛季伊始便严重缺乏竞争力;赛季揭幕战巴林大奖赛上,排位赛中双车排名垫底在第一节即被淘汰,正赛17、18名带回。在沙特大奖赛,双车17、18位发车,正赛加斯利因变速箱问题退赛,奥康带回13名。位列厂队垫底,心疼他们的两名车手。

跑题了,赶紧回归正题。

二、原理

特性

贝塞尔曲线有如下特性:

  • 通过\(n\)个控制点\(P_1, P_2, P_3, ..., P_n\)控制曲线形状。
  • 曲线只经过起点\(P_1\)和终点\(P_n\).

构建贝塞尔曲线

  1. 一次曲线(线性):
    一次贝塞尔曲线由两个端点\(P_0\)\(P_1\)组成,曲线由线段直接连接这两个点,\(B(t)\)描述一条由\(P_0\)\(P_1\)的直线,可以视为一个\(P_0\)\(P_1\)的连续中间点\(Q_0\)


一次贝塞尔曲线演示.gif

线性贝塞尔曲线演示动画,t在[0,1]区间
  1. 二次曲线
    二次贝塞尔曲线由定点\(P_0, P_1, P_2\)的函数\(B(t)\)描述。为构建贝塞尔曲线,引入中间点\(Q_0, Q_1\)
    • \(P_0, P_1\)之间的连续点\(Q_0\),描述一条线性贝塞尔曲线;
    • \(P_1, P_2\)之间的连续点\(Q_1\),描述一条线性贝塞尔曲线;
    • \(Q_0, Q_1\)之间的连续点\(B(t)\),描述一条二次贝塞尔曲线。


二次贝塞尔曲线的结构.png

二次贝塞尔曲线的结构


二次贝塞尔曲线演示动画,t在[0,1]区间.gif

二次贝塞尔曲线演示动画,t在[0,1]区间
  1. 三次曲线
    对于三次曲线,由定点\(P_0, P_1, P_2, P_3\)的函数\(B(t)\)描述。可以加入三个可由线性贝塞尔曲线描述的中间点\(Q_0, Q_1, Q_2\),和两个由二次贝塞尔曲线描述的点\(R_0, R_1\)来描述:
    • \(P_0, P_1\)之间的连续点\(Q_0\),描述一条线性贝塞尔曲线;
    • \(P_1, P_2\)之间的连续点\(Q_1\),描述一条线性贝塞尔曲线;
    • \(P_2, P_3\)之间的连续点\(Q_2\),描述一条线性贝塞尔曲线;
    • \(Q_0, Q_1\)之间的连续点\(R_0\),描述一条二次贝塞尔曲线;
    • \(Q_1, Q_2\)之间的连续点\(R_1\),描述一条二次贝塞尔曲线;
    • \(R_0, R_1\)之间的连续点\(B(t)\),描述一条三次贝塞尔曲线。


三次贝塞尔曲线的结构.png

三次贝塞尔曲线的结构


三次贝塞尔曲线演示动画,t在[0,1]区间.gif

三次贝塞尔曲线演示动画,t在[0,1]区间
  1. 四次曲线
    对于四次曲线,由定点\(P_0, P_1, P_2, P_3, P_4\)的函数\(B(t)\)描述。可以加入四个可由线性贝塞尔曲线描述的中间点\(Q_0, Q_1, Q_2, Q_3\),三个由二次贝塞尔曲线描述的点\(R_0, R_1, R_2\),和两个由三次贝塞尔曲线描述的点\(S_0, S_1\)来描述:
    • \(P_0, P_1\)之间的连续点\(Q_0\),描述一条线性贝塞尔曲线;
    • \(P_1, P_2\)之间的连续点\(Q_1\),描述一条线性贝塞尔曲线;
    • \(P_2, P_3\)之间的连续点\(Q_2\),描述一条线性贝塞尔曲线;
    • \(P_3, P_4\)之间的连续点\(Q_3\),描述一条线性贝塞尔曲线;
    • \(Q_0, Q_1\)之间的连续点\(R_0\),描述一条二次贝塞尔曲线;
    • \(Q_1, Q_2\)之间的连续点\(R_1\),描述一条二次贝塞尔曲线;
    • \(Q_2, Q_3\)之间的连续点\(R_2\),描述一条二次贝塞尔曲线;
    • \(R_0, R_1\)之间的连续点\(S_0\),描述一条三次贝塞尔曲线;
    • \(R_1, R_2\)之间的连续点\(S_1\),描述一条三次贝塞尔曲线;
    • \(S_0, S_1\)之间的连续点\(B(t)\),描述一条四次贝塞尔曲线。


四次贝塞尔曲线的结构.png

四次贝塞尔曲线的结构


四次贝塞尔曲线演示动画,t在[0,1]区间.gif

四次贝塞尔曲线演示动画,t在[0,1]区间
  1. 高阶曲线
    由上文可知,为构建更高阶的曲线,需要引入更多的中间点。同理可推得五次曲线:


五次贝塞尔曲线演示动画,t在[0,1]区间.gif

五次贝塞尔曲线演示动画,t在[0,1]区间

构建贝塞尔曲线公式

  1. 一次曲线(线性):
    \(P_0\)的坐标为\((\alpha, \beta)\)\(P_1\)的坐标为\((\lambda, \mu)\),引入中间点\(Q_0\)的坐标为\((x, y)\),则有:

\[\frac{x - \alpha}{\lambda - x} = \frac{t}{1 - t} \]

可推得:

\[x = (1 - t)\alpha + t\lambda \tag1 \]

同理,可得:

\[\frac{y - \beta}{\mu - y} = \frac{t}{1 - t} \]

可推得:

\[y = (1 - t)\beta + t\mu \tag2 \]

整理可得:

\[\left( \begin{matrix} x \\ y \end{matrix} \right) =(1 - t) \left( \begin{matrix} \alpha \\ \beta \end{matrix} \right) + t \left( \begin{matrix} \lambda \\ \mu \end{matrix} \right) \tag3 \]

可将式\((3)\)简写为:

\[B(t) = (1 - t) P_0 + t P_1, t \in [0, 1] \tag4 \]

得到一次贝塞尔曲线公式。
2. 二次曲线
\(P_0, P_1\)上的中间点为\(Q_0\)\(P_1, P_2\)上的中间点为\(Q_1\)\(Q_0, Q_1\)上的中间点为\(R_0\)\(R_0\)即构建曲线的连续点。
带入式\((4)\)可得:

\[\begin{matrix} Q_0 = (1 - t) P_0 + t P_1 \\ Q_1 = (1 - t) P_1 + t P_2 \\ R_0 = (1 - t) Q_0 + t Q_1 \end{matrix} \tag5 \]

将式\((5)\)中的\(Q_0\)\(Q_1\)代入\(R_0\)中,可得二次贝塞尔曲线公式:

\[B(t) = (1 - t) ^ 2 P_0 + 2 t (1 - t) P_1 + t ^ 2 P_2, t \in [0, 1] \tag6 \]

  1. 三次曲线
    同理,通过引入中间点\(Q_0, Q_1, Q_2, R_0, R_1, S_0\),代入使用式\((6)\),可得三次贝塞尔曲线公式:

\[B(t) = (1 - t) ^ 3 P_0 + 3 t (1 - t) ^ 2 P_1 + 3 t ^ 2 (1 - t) P_2 + t ^ 3 P_3, t \in [0, 1] \tag7 \]

  1. 高阶曲线
    可以迭代得到四次、五次贝塞尔曲线的公式:

\[B(t) = (1 - t) ^ 4 P_0 + 4 t (1 - t) ^ 3 P_1 + 6 t ^ 2 (1 - t) ^ 2 P_2 + 4 t ^ 3 (1 - t) P_3 + t ^ 4 P_4, t \in [0, 1] \tag8 \]

\[B(t) = (1 - t) ^ 5 P_0 + 5 t (1 - t) ^ 4 P_1 + 10 t ^ 2 ( 1 - t) ^ 3 P_2 + 10 t ^ 3 (1 - t) ^ 2 P_3 + 5 t ^ 4 (1 - t) P_4 + t ^ 5 P_5, t \in [0, 1] \tag9 \]

三、推导

一般化

观察上文中\(1\)\(5\)阶贝塞尔曲线,发现其各项中的常数系数满足组合数规律,故对于\(n\)阶贝塞尔曲线,给出定点\(P_0, P_1, P_2, ..., P_n\),其贝塞尔曲线可用下式表示:

\[B(t) = \left( \begin{matrix} n \\ 0 \end{matrix} \right) (1 - t) ^ n t ^ 0 P_0 + \left( \begin{matrix} n \\ 1 \end{matrix} \right) (1 - t) ^ {n - 1} t ^ 1 P_1 + \cdots + \left( \begin{matrix} n \\ n - 1 \end{matrix} \right) (1 - t) ^ 1 t ^ {n - 1} P_{n - 1} + \left( \begin{matrix} n \\ n \end{matrix} \right) (1 - t) ^ 0 t ^ n P_n, t \in [0, 1] \tag{10} \]

可化简为:

\[B(t) = \sum_{i = 0}^\infty \left( \begin{matrix} n \\ i \end{matrix} \right) (1 - t) ^ {n - i} t ^ i P_i, t \in [0, 1] \tag{11} \]

式中组合数:

\[\left( \begin{matrix} n \\ i \end{matrix} \right) = \frac{n !}{i ! \cdot (n - i) !} \]

多项式表达

同时,式\((11)\)也可表示为:

\[B(t) = \sum_{i = 0}^\infty b_{i, n}(t) P_i, t \in [0, 1] \tag{12} \]

其中多项式:

\[b_{i, n}(t) = \left( \begin{matrix} n \\ i \end{matrix} \right) (1 - t) ^ {n - i} t ^ i, i = 0, 1, 2, \cdots, n \tag{13} \]

\((13)\)被称作\(n\)Bernsteain多项式

Bernsteain多项式
假设开展一个实验,其成功的概率为\(u\)。若连续进行这个实验\(n\)次,成功的次数恰好为\(i\)次,那么其成功概率是多少呢?
能够确定成功概率为:\(b_{i, n}(t) = \left( \begin{matrix} n \\ i \end{matrix} \right) (1 - t) ^ {n - i} t ^ i, i = 0, 1, 2, \cdots, n\).
这便是Bernsteain多项式。

四、应用(Matlab实现)

实现目标

  1. 能够进行控制点坐标的输入。
  2. 计算贝塞尔曲线。
  3. 绘制贝塞尔曲线及其控制点。

脚本编写

main.m(主函数,调用输入函数、贝塞尔曲线计算函数及绘制贝塞尔曲线)

%% 初始化
clc
clear%% 输入
n = input("请输入控制点个数:\n");
P = pos_input(n);%% 调用贝塞尔曲线计算函数
P = P';  % 坐标矩阵转置,便于曲线运算及绘图
[t, p] = bezier_curve(P, n - 1);  % 阶数为控制点个数 - 1%% 绘制贝塞尔曲线
plot(t, p, '-b');  % 绘制贝塞尔曲线
hold on;
plot(P(1,:), P(2,:), '-ro');  % 绘制控制点
title(sprintf('贝塞尔曲线 (阶数: %d)', n - 1));
xlabel('X');
ylabel('Y');
grid on;
legend('贝塞尔曲线', '控制点');
hold off;

bezier_curve.m(贝塞尔曲线函数,计算n阶贝塞尔曲线)

function [Px, Py] = bezier_curve(control_points, order)% 计算贝塞尔曲线上的点t = linspace(0, 1, 1000);  % 在[0, 1]范围内生成点curve = zeros(2, numel(t));  % 初始化曲线矩阵,numel函数用于获取数组元素的数目for i = 0 : ordercurve = curve + nchoosek(order, i) * ((1 - t) .^ (order - i)) .* ...(t .^ i) .* control_points(:, i + 1);  % 该计算公式即上文中式(11),nchoosek函数用于计算组合数endPx = curve(1, :);Py = curve(2, :);
end

pos_input.m(输入函数,输入控制点坐标)

function P = pos_input(I)% 输入贝塞尔曲线控制点 P = ones(I, 2);  % 初始化坐标矩阵 for i = 1 : IP(i, :) = input("请输入输入坐标点P" + num2str(i - 1) + "(以一维矩阵形式输入): \n");end
end

图像结果

六阶贝塞尔曲线

六阶贝塞尔曲线.png

十四阶贝塞尔曲线

十四阶贝塞尔曲线.png

五、参考

  1. 维基百科_贝塞尔曲线

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/738143.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

刘积仁的大健康“长跑”

软件是一个长命的产业,但软件企业的寿命都很短。懂得怕死,才能有机会活得长久。 这一次,刘积仁又为东软医疗找到了强大助力!中国通用技术(集团)控股有限责任公司(以下简称通用技术集团)所属资本公司战略投资东软集团在医疗健康领域资的创新业务公司——东软医疗,双方也由…

【AppStore】一文让你学会IOS应用上架Appstore

咱们国内现在手机分为两类,Android手机与苹果手机,现在用的各类APP,为了手机的使用安全,避免下载到病毒软件,官方都极力推荐使用手机自带的应用商城进行下载,但是国内Android手机品类众多,手机商城各式各样,做不到统一,所以Android的APP上架得一个一个平台去申请上架,…

关于airtest生成的报告中缺少poco语句问题

1、airtest生成的报告只显示airtest的相关操作,如果是poco和airtest-selenium的操作则不记录。因此需要在报告中引用插件。支持poco语句插件,poco.utils.airtest.report 支持airtest-selenium语句插件,airtest_selenium.report2、在IDE运行 .py 脚本报告生成的依据是脚本运行…

xshell7的下载ssh远程连接

1.下载地址家庭/学校免费 - NetSarang Website (xshell.com) 2.下载后一路next,来到主页面,我们来连接一下试一试吧,这里主机就是ifconfig得到的 3.用户名一般都是root密码是自己设置的那个 4.连接的时候注意比如我要连接Node1那么node1就要保持开启并却防火墙已经关闭 5.看一…

xhcms1.0

xhcms1.0 目录结构 admin --管理后台文件夹 css --存放css的文件夹 files --存放页面的文件夹 images --存放图片的文件夹 inc --存放网站配置文件的文件夹 install --网站进行安装的文件夹 seacmseditor --编辑器文件夹 te…

关于巴图自动化Profinet协议转Modbus协议网关模块怎么配置IP地址教学

Profinet协议和Modbus协议是工业通讯常用协议,通过巴图自动化PN转Modbus网关模块(BT-MDPN10)实现连接。常见的协议有:ModbusTCP协议,Profibus协议,Profibus DP协议,EtherCAT协议,EtherNET协议,CAN,CANOPEN等Profinet协议和Modbus协议是工业领域中常用的两种通讯协议,…

基础篇:Stable Diffusion 基础原理详述

【基础篇】Stable Diffusion 基础原理详述前言我认为学习 ComfyUI 应该先从理论学起。与传统绘图工具(如 Photoshop 或 Figma)相比,AI 绘图工具有着显著不同。首先,许多设置和操作在 AI 绘图工具中是非可视化的,这意味着即使你更改了某个配置,界面上也未必会有任何变化,…

微信云开发数据库连接

//.js文件const db = wx.cloud.database()Page({//页面的初始数据data: {dataObj:"" //定义对象dataObj}, //查询数据getData(){db.collection("pro1").where({ //pro1为数据库名author:"张三" …

Camstar里拿到Grid的行数据

两种方法: 1.GridDataMode属性为Geceric的:拿到的数据直接放在datatable里,并且赋值给grid,这里我把拿来的数据放在了一个集合里,测试用的 随便写写 2.GridDataMode属性为ItemList的:这里是用了一个集合去接收datatable的值,再把集合赋值给grid这里和第一种的区别是我没有…

MQTT专题

什么是Mqtt MQTT协议 全称是(Message Queuing Telemetry Transport),即消息队列遥测传输协议。 是一种基于发布/订阅(Publish/Subscribe)模式的轻量级通讯协议,并且该协议构建于TCP/IP协议之上,我们知道TCP协议本身就具有高可靠性的特点,因此基于其上的MQTT协议同样也…

安装visual studio失败,组策略阻止安装webview2

排查安装和升级问题 - Visual Studio | Microsoft Learn 需要修改注册表 ,将 InstallDefault值改为1注册表路径 HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\EdgeUpdate

appium 使用

refer to: python+appium2~inspector工具使用及定位操作元素~_哔哩哔哩_bilibili 1 APPium Inspector 可以查看Android应用的 包名 和activity 打开APP,且处于启动页面 Q1 noReset=True 设置每次APP启动 不重头 初始化环境 怎么实现呢 Q1 那我们现在用的是appium1 还是 appi…

7月11日云技术研讨会 | 车载信息安全全流程实施方案

7月11日,经纬恒润《车载信息安全全流程实施方案》云技术研讨会,与您相聚云端,不见不散! 伴随着汽车的智能网联化发展,网络攻击也逐渐渗透漫延至汽车领域,汽车行业面临着重大的信息安全挑战。此外,UNECE WP.29 R155和ISO/SAE 21434等标准也对汽车的信息安全提出了规…

基于全数字实时仿真的嵌入式DevOps解决方案

​为丰富浙江省信息技术应用创新(以下简称“信创”)产业生态,在全社会各领域形成示范效应,浙江省经信厅联合省密码管理局开展2023年浙江省深化信创典型案例评选工作。经过征集申报、专家评选、名单公示等程序,确定36个应用示范案例和24个典型解决方案。【典型解决方案】 基…

巴图自动化PN转Modbus RTU协议转换网关模块快速配置

巴图自动化推出Profinet转Modbus网关模块BT-MDPN10,实现Modbus和Profinet设备互联互通。配置简便,提高系统智能化和生产效率。工业领域中常用的通讯协议有:Profinet协议,Modbus协议,ModbusTCP协议,Profibus协议,Profibus DP协议,EtherCAT协议,EtherNET协议,CAN,CanO…

springboot+vue前后端分离项目-项目搭建7-服务器上安装部署

1.下载VMware(个人使用版),官网下载,需要先用邮箱注册,下载地址:https://support.broadcom.com/group/ecx/productdownloads?subfamily=VMware%20Workstation%20Pro 2.下载镜像dvd类型的,华为云官网下载,需要先注册,下载地址:https://mirrors.huaweicloud.com/mirro…

linux进程被杀掉日志,Linux进程突然被杀掉(OOM killer),查看系统日志

Linux进程被杀掉(OOM killer),查看系统日志 基本概念: Linux 内核有个机制叫OOM killer(Out Of Memory killer),该机制会监控那些占用内存过大,尤其是瞬间占用内存很快的进程,然后防止内存耗尽而自动把该进程杀掉。内核检测到系统内存不足、挑选并杀掉某个进程的过程可以参…

Salesforce开发入门指南:零基础学习宝典!

开发人员将Salesforce组织扩展到声明式配置之外,构建应用程序,进而优化业务运营。Salesforce开发人员通常会使用两种编程语言:Apex和JavaScript。 然而,Salesforce开发不仅仅只包括代码。为了在职业道路上脱颖而出,开发人员还需要了解声明性功能,将组织的设计和性能保持最…

Apache SeaTunnel社区首位学生Committer诞生!

采访对象 | 陈炳烨 采访人&编辑 | Debra Chen Apache SeaTunnel社区第一位学生Committer就此诞生!这位来自西安交通大学软件工程专业的同学从较为简单的文档修改工作,逐步深入到代码层面,到最后独立负责开发模块,为Apache SeaTunnel项目的发展添砖加瓦的同时,他本人也…