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

贝塞尔曲线原理

文章目录

  • 一、 低阶贝塞尔曲线
    • 1.一阶贝塞尔曲线
    • 2. 二阶贝塞尔曲线
    • 3. 三阶贝塞尔曲线

一、 低阶贝塞尔曲线

1.一阶贝塞尔曲线

如下图所示, P 0 ​ P_0​ P0, P 1 ​ P_1​ P1 是平面中的两点,则 B ( t ) B ( t ) B(t) 代表平面中的一段线段。
在这里插入图片描述
考虑这样一条曲线方程
B ( t ) = P 0 ​ + ( P 1 ​ − P 0 ​ ) t = ( 1 − t ) P 0 ​ + t P 1 \begin{align} B(t)=P_0​+(P_1​−P_0​)t=(1−t)P_0​+tP_1 \end{align} B(t)=P0+(P1P0)t=(1t)P0+tP1
一阶曲线很好理解, 就是根据 t t t来的线性插值, t t t的取值范围为 [ 0 , 1 ] [ 0 , 1 ] [0,1]

python实现

# 保存动图时用,pip install celluloid
from celluloid import Camera 
import numpy as np
import matplotlib.pyplot as plt
P0=np.array([0,0])
P1=np.array([1,1])
fig=plt.figure(1)
camera = Camera(fig)
x =[]
y=[]
for t in np.arange(0,1,0.01):plt.plot([P0[0],P1[0]],[P0[1],P1[1]],'r')p1_t=(1-t)*P0+t*P1x.append(p1_t[0])y.append(p1_t[1])# plt.plot(x,y,c='b')plt.scatter(x,y,c='b')# plt.pause(0.001)camera.snap()
animation = camera.animate()
animation.save('一阶贝塞尔.gif')

matlab实现

from celluloid import Camera  # 保存动图时用,pip install celluloid
import numpy as np
import matplotlib.pyplot as plt
P0=np.array([0,0])
P1=np.array([1,1])
fig=plt.figure(1)
camera = Camera(fig)
x =[]
y=[]
for t in np.arange(0,1,0.01):plt.plot([P0[0],P1[0]],[P0[1],P1[1]],'r')p1_t=(1-t)*P0+t*P1x.append(p1_t[0])y.append(p1_t[1])# plt.plot(x,y,c='b')plt.scatter(x,y,c='b')# plt.pause(0.001)camera.snap()
animation = camera.animate()
animation.save('一阶贝塞尔.gif')

2. 二阶贝塞尔曲线

对于二阶贝塞尔曲线,需要3个控制点,假设分别为 P 0 P_0 P0 P 1 P_1 P1 P 2 P_2 P2​。 P 0 P_0 P0 P 1 P_1 P1 ​构成一阶 P 1 , 1 ​ ( t ) P_{1,1}​(t) P1,1(t) P 1 P_1 P1​和 P 2 P_2 P2​​也构成一阶 P 1 , 2 ​ ( t ) P_{1,2}​(t) P1,2(t),即:
{ P 1 , 1 ​ ( t ) = ( 1 − t ) P 0 ​ + t P 1 P 1 , 2 ​ ( t ) = ( 1 − t ) P 1 + t P 2 \begin{equation} \left\{ \begin{array}{} P_{1,1}​(t)=(1−t)P_0​+tP_1 \\ P_{1,2}​(t)=(1−t)P_1+tP_2 \\ \end{array} \right. \end{equation} {P1,1(t)=(1t)P0+tP1P1,2(t)=(1t)P1+tP2
在生成的两个一阶点 P 1 , 1 ​ ( t ) P_{1,1}​(t) P1,1(t) P 1 , 2 ​ ( t ) P_{1,2}​(t) P1,2(t)基础上,可以生成二阶贝塞尔点 P 2 ​ ( t ) P_2​(t) P2(t):
P 2 ​ ( t ) = ( 1 − t ) P 1 , 1 ​ + t P 1 , 2 ​ = ( 1 − t ) 2 P 0 ​ + 2 t ( 1 − t ) P 1 ​ + t 2 P 2 \begin{align} P_2​(t)=(1−t)P_{1,1}​+tP_{1,2}​=(1−t)^2P_0​+2t(1−t)P_1​+t^2P_2 \end{align} P2(t)=(1t)P1,1+tP1,2=(1t)2P0+2t(1t)P1+t2P2
在这里插入图片描述
python实现

from celluloid import Camera  # 保存动图时用,pip install celluloid
import numpy as np
import matplotlib.pyplot as plt
P0 = np.array([0, 0])
P1 = np.array([1,1])
P2 = np.array([2, 1])
fig = plt.figure(2)
camera = Camera(fig)x_2 = []
y_2 = []
for t in np.arange(0, 1, 0.01):plt.cla()plt.plot([P0[0], P1[0]], [P0[1], P1[1]], 'k')plt.plot([P1[0], P2[0]], [P1[1], P2[1]], 'k')p11_t = (1-t)*P0+t*P1p12_t = (1-t)*P1+t*P2p2_t = (1-t)*p11_t+t*p12_tx_2.append(p2_t[0])y_2.append(p2_t[1])plt.scatter(x_2, y_2, c='r')plt.plot([p11_t[0],p12_t[0]],[p11_t[1],p12_t[1]],'g')plt.title("t="+str(t))plt.pause(0.001)
#     camera.snap()
# animation = camera.animate()
# animation.save('2阶贝塞尔.gif')

matlab实现

clc;
clear;
close all;
%% 二次贝塞尔曲线
P0=[0,0];
P1=[1,1];
P2=[2,1];
P=[P0;P1;P2];
figure(2);
plot(P(:,1),P(:,2),'k');
MakeGif('二次贝塞尔曲线.gif',1);
hold onscatter(P(:,1),P(:,2),200,'.b');
for t=0:0.01:1P_t_1=(1-t) * P0 + t * P1;P_t_2=(1-t) * P1 + t * P2;P_t_3=(1-t) * P_t_1 + t * P_t_2;m1=scatter(P_t_1(1),P_t_1(2),300,'g');m2=scatter(P_t_2(1),P_t_2(2),300,'g');m3=plot([P_t_1(1),P_t_2(1)],[P_t_1(2),P_t_2(2)],'g','linewidth',2);scatter(P_t_3(1),P_t_3(2),300,'.r');  stringName = "二次贝塞尔曲线:t="+num2str(t);title(stringName);MakeGif('二次贝塞尔曲线.gif',t*100+1);delete(m1);delete(m2);delete(m3);
end

3. 三阶贝塞尔曲线

在这里插入图片描述
三阶贝塞尔曲线有4个控制点,假设分别为 P 0 P_0 P0 P 1 P_1 P1 P 2 P_2 P2 P 3 P_3 P3 P 0 P_0 P0 P 1 P_1 P1 P 1 P_1 P1 P 2 P_2 P2 P 2 P_2 P2 P 3 P_3 P3 分别构成一阶 P 1 , 1 ​ ( t ) P_{1,1}​(t) P1,1(t) P 1 , 2 ​ ( t ) P_{1,2}​(t) P1,2(t) P 1 , 3 ​ ( t ) P_{1,3}​(t) P1,3(t),即:
{ P 1 , 1 ​ ( t ) = ( 1 − t ) P 0 ​ + t P 1 P 1 , 2 ​ ( t ) = ( 1 − t ) P 1 + t P 2 P 1 , 3 ​ ( t ) = ( 1 − t ) P 2 + t P 3 \begin{equation} \left\{ \begin{array}{} P_{1,1}​(t)=(1−t)P_0​+tP_1 \\ P_{1,2}​(t)=(1−t)P_1+tP_2 \\ P_{1,3}​(t)=(1−t)P_2+tP_3 \\ \end{array} \right. \end{equation} P1,1(t)=(1t)P0+tP1P1,2(t)=(1t)P1+tP2P1,3(t)=(1t)P2+tP3
在生成的三个一阶点 P 1 , 1 ​ ( t ) P_{1,1}​(t) P1,1(t) P 1 , 2 ​ ( t ) P_{1,2}​(t) P1,2(t) P 1 , 3 ​ ( t ) P_{1,3}​(t) P1,3(t)基础上,可以生成两个二阶贝塞尔点 P 2 , 1 ​ ( t ) P_{2,1}​(t) P2,1(t) P 2 , 2 ​ ( t ) P_{2,2}​(t) P2,2(t)
{ P 2 , 1 ​ ( t ) = ( 1 − t ) P 1 , 1 ​ + t P 1 , 2 ​ P 2 , 2 ​ ( t ) = ( 1 − t ) P 1 , 2 ​ + t P 1 , 3 ​ \begin{equation} \left\{ \begin{array}{} P_{2,1}​(t)=(1−t)P_{1,1}​+tP_{1,2}​ \\ P_{2,2}​(t)=(1−t)P_{1,2}​+tP_{1,3}​\\ \end{array} \right. \end{equation} {P2,1(t)=(1t)P1,1+tP1,2P2,2(t)=(1t)P1,2+tP1,3
在生成的两个二阶点 P 2 , 1 ​ ( t ) P_{2,1}​(t) P2,1(t) P 2 , 2 ​ ( t ) P_{2,2}​(t) P2,2(t)基础上,可以生成三阶贝塞尔点 P 3 ( t ) P_3(t) P3(t):
P 3 ​ ( t ) = ( 1 − t ) P 2 , 1 + t P 2 , 2 ​ = ( 1 − t ) 3 P 0 ​ + 3 t ( 1 − t ) 2 P 1 ​ + 3 t 2 ( 1 − t ) P 2 + t 3 P 3 \begin{align} P_3​(t)=(1−t)P_{2,1}+tP_{2,2}​=(1−t)^3P_0​+3t(1−t)^2P_1​+3t^2(1-t)P_2+t^3P_3 \end{align} P3(t)=(1t)P2,1+tP2,2=(1t)3P0+3t(1t)2P1+3t2(1t)P2+t3P3

python实现

from celluloid import Camera  # 保存动图时用,pip install celluloid
import numpy as np
import matplotlib.pyplot as pltP0 = np.array([0, 0])
P1 = np.array([1, 1])
P2 = np.array([2, 1])
P3 = np.array([3, 0])
fig = plt.figure(3)
camera = Camera(fig)x_2 = []
y_2 = []
for t in np.arange(0, 1, 0.01):plt.cla()plt.plot([P0[0], P1[0]], [P0[1], P1[1]], 'k')plt.plot([P1[0], P2[0]], [P1[1], P2[1]], 'k')plt.plot([P2[0], P3[0]], [P2[1], P3[1]], 'k')p11_t = (1-t)*P0+t*P1p12_t = (1-t)*P1+t*P2p13_t = (1-t)*P2+t*P3p21_t = (1-t)*p11_t+t*p12_tp22_t = (1-t)*p12_t+t*p13_tp3_t = (1-t)*p21_t+t*p22_tx_2.append(p3_t[0])y_2.append(p3_t[1])plt.scatter(x_2, y_2, c='r')plt.plot([p11_t[0], p12_t[0]], [p11_t[1], p12_t[1]], 'b')plt.plot([p12_t[0], p13_t[0]], [p12_t[1], p13_t[1]], 'b')plt.plot([p21_t[0], p22_t[0]], [p21_t[1], p22_t[1]], 'r')plt.title("t="+str(t))plt.pause(0.001)
#     camera.snap()
# animation = camera.animate()
# animation.save('3阶贝塞尔.gif')

matlab实现

clc;
clear;
close all;
P0=[0,0];
P1=[1,1];
P2=[2,1];
P3=[3,0];
P=[P0;P1;P2;P3];
figure(3);
plot(P(:,1),P(:,2),'k');
MakeGif('三次贝塞尔曲线.gif',1);
hold on
scatter(P(:,1),P(:,2),200,'.b');for t=0:0.01:1P_t_1=(1-t) * P0 + t * P1;P_t_2=(1-t) * P1 + t * P2;P_t_3=(1-t) * P2 + t * P3;ssP_t_4=(1-t) * P_t_1 + t * P_t_2;P_t_5=(1-t) * P_t_2 + t * P_t_3;P_t_6=(1-t) * P_t_4 + t * P_t_5;m1=scatter(P_t_1(1),P_t_1(2),300,'g');m2=scatter(P_t_2(1),P_t_2(2),300,'g');m3=scatter(P_t_3(1),P_t_3(2),300,'g');m4=scatter(P_t_4(1),P_t_4(2),300,'m');m5=scatter(P_t_5(1),P_t_5(2),300,'m');m6=plot([P_t_1(1),P_t_2(1),P_t_3(1)],[P_t_1(2),P_t_2(2),P_t_3(2)],'g','linewidth',2);m7=plot([P_t_4(1),P_t_5(1)],[P_t_4(2),P_t_5(2)],'m','linewidth',2);scatter(P_t_6(1),P_t_6(2),300,'.r');  stringName = "三次贝塞尔曲线:t="+num2str(t);title(stringName);MakeGif('三次贝塞尔曲线.gif',t*100+1);delete(m1);delete(m2);delete(m3);delete(m4);delete(m5);delete(m6);delete(m7);
end

相关文章:

贝塞尔曲线原理

文章目录 一、 低阶贝塞尔曲线1.一阶贝塞尔曲线2. 二阶贝塞尔曲线3. 三阶贝塞尔曲线 一、 低阶贝塞尔曲线 1.一阶贝塞尔曲线 如下图所示, P 0 ​ P_0​ P0​​, P 1 ​ P_1​ P1​​ 是平面中的两点,则 B ( t ) B ( t ) B(t) 代表平面中的一段线段。…...

3D个人简历网站 4.小岛

1.模型素材 在Sketchfab上下载狐狸岛模型,然后转换为素材资源asset,嫌麻烦直接在网盘链接下载素材, Fox’s islandshttps://sketchfab.com/3d-models/foxs-islands-163b68e09fcc47618450150be7785907https://gltf.pmnd.rs/ 素材夸克网盘&a…...

创建型:原型模式

目录 1、核心思想 2、实现方式 2.1 基本结构 2.2 代码示例(Java) 3、适用场景 4、new与clone实际场景建议 1、核心思想 目的:通过复制(克隆)现有对象来创建新对象,而不是通过new关键字实例化。对于那…...

浅谈“量子计算应用:从基础原理到行业破局”

量子计算应用:从基础原理到行业破局 引言:量子计算为何成为科技革命新引擎? 量子计算利用量子力学原理(叠加态、纠缠态、量子干涉)突破经典计算的极限,在特定领域可实现指数级加速。根据中研普华预测,2025年全球量子计算市场规模将突破80亿美元,2035年可达8117亿美元。…...

Java面试攻略:从Spring Boot到微服务架构的深入探讨

Java面试攻略:从Spring Boot到微服务架构的深入探讨 场景设定 在一家知名互联网大厂的会议室里,资深面试官王老师正在对一位求职者谢飞机进行技术面试。谢飞机是一位幽默风趣的程序员,他的回答有时让人捧腹大笑。 第一轮:核心技…...

关于文件分片的介绍和应用

文件分片,顾名思义,就是将一个大文件分割成多个小的文件块(chunk)。每个文件块都是原始文件的一部分,并可以通过特定的方式将这些小文件块重新组装成原始文件。 1. 基本原理: 文件分片从底层来看,主要是对…...

Tapered Off-Policy REINFORCE_ 如何为LLM实现稳定高效的策略优化?

Tapered Off-Policy REINFORCE: 如何为LLM实现稳定高效的策略优化? 在大语言模型(LLM)的微调领域,强化学习(RL)正成为提升复杂任务性能的核心方法。本文聚焦于一篇突破性论文,其提出的Tapered …...

使用lvm进行磁盘分区

使用lvm进行磁盘分区 目的: 使用/dev/vdb创建一个5g的逻辑卷挂载到/mnt/lvmtest 前提: /dev/vdb是一块干净的空磁盘,数据会被清空!!! 1. 创建物理卷(PV): pvcreate /dev/sdb2. 验证&#xf…...

[Java实战]Spring Boot整合Elasticsearch(二十六)

[Java实战]Spring Boot整合Elasticsearch(二十六) 摘要:本文通过完整的实战演示,详细讲解如何在Spring Boot项目中整合Elasticsearch,实现数据的存储、检索和复杂查询功能。包含版本适配方案、Spring Data Elasticsea…...

图像分割(1)U-net

一、整体结构 虽然说是几年前的产品,但是现在还在用,因为深度学习很多时候越是简单的网络用起来效果越好,而且一般是目标比较小的时候产生的分割问题。u-net的优势就是网络结构简单,适合小目标分割,所以一直用到现在&a…...

数位和:从定义到编程实现

1. 定义 ​数位和​(Digit Sum)是指一个数的每一位数字相加的总和。例如: 123 的数位和:1 2 3 645 的数位和:4 5 9 2. 计算方法 计算数位和的通用步骤: ​提取每一位数字​:从右到左&…...

2025抓包工具Reqable手机抓包HTTPS亲测简单好用-快速跑通

前言 自安卓7.0高版本系统不在信任用户证书,https抓包方式市面查找方法太过复杂手机要root等,前置条件要求太高太复杂,看的头痛,今天一台电脑按步骤操作完即可抓包https,给大家搞定抓包https问题。支持直接编辑修改请求参…...

使用 Auto-Keras 进行自动化机器学习

使用 Auto-Keras 进行自动化机器学习 了解自动化机器学习以及如何使用 auto-keras 完成它。如今,机器学习并不是一个非常罕见的术语,因为像 DataCamp、Coursera、Udacity 等组织一直在努力提高他们的效率和灵活性,以便将机器学习的教育带给普…...

python 自动化教程

文章目录 前言整数变量​字符串变量​列表变量​算术操作​比较操作​逻辑操作​if语句​for循环遍历列表​while循环​定义函数​调用函数​导入模块​使用模块中的函数​启动Chrome浏览器​打开网页​定位元素并输入内容​提交表单​关闭浏览器​发送GET请求获取网页内容​使…...

简单使用Slidev和PPTist

简单使用Slidev和PPTist 1 简介 前端PPT制作有很多优秀的工具包,例如:Slidev、revealjs、PPTist等,Slidev对Markdown格式支持较好,适合与大模型结合使用,选哟二次封装;revealjs适合做数据切换&#xff0c…...

RISC-V 开发板 MUSE Pi Pro V2D图像加速器测试,踩坑介绍

视频讲解: RISC-V 开发板 MUSE Pi Pro V2D图像加速器测试,踩坑介绍 今天测试下V2D,这是K1特有的硬件级别的2D图像加速器,参考如下文档,但文档中描述的部分有不少问题,后面会讲下 https://bianbu-linux.spa…...

人工智能100问☞第26问:什么是贝叶斯网络?

贝叶斯网络是基于有向无环图和条件概率表构建的概率图模型,用于表达变量间的条件依赖关系并进行不确定性推理。 一、通俗解释 想象你玩侦探游戏,要通过零散线索推理真相。贝叶斯网络就像一张"因果关系地图"——用箭头把事件连起来,并标注每个事件发生的概率。比…...

c++多线程debug

debug demo 命令行查看 ps -eLf|grep cam_det //查看当前运行的轻量级进程 ps -aux | grep 执行文件 //查看当前运行的进程 ps -aL | grep 执行文件 //查看当前运行的轻量级进程 pstree -p 主线程ID //查看主线程和新线程的关系 查看线程栈结构 pstack 线程ID 步骤&…...

如何畅通需求收集渠道,获取用户反馈?

要畅通需求收集渠道、有效获取用户反馈,核心在于多样化反馈入口、闭环反馈机制、用户分层管理、反馈数据结构化分析等四个方面。其中,多样化反馈入口至关重要,不同用户有不同的沟通偏好,只有覆盖多个反馈路径,才能捕捉…...

标准库、HAl库和LL库(PC13初始化)

标准库 (Standard Peripheral Library) c #include "stm32f10x.h"void GPIO_Init_PC13(void) {GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_InitStruct.GPIO_Pin GPIO_Pin_13;GPIO_InitStruct.GPIO_Mode GPIO_…...

LangGraph深度解析:构建持久化、可观测的智能体工作流

一、项目概述与技术定位 1.1 LangGraph核心价值 LangGraph是由LangChain团队推出的开源框架(GitHub仓库:https://github.com/langchain-ai/langgraph),专为构建持久化、状态化的智能体工作流设计。作为LangChain生态系统的战略补充,它解决了传统LLM应用在以下方面的关键…...

设备预测性维护的停机时间革命:中讯烛龙如何用AI重构工业设备管理范式

在工业4.0的智能化浪潮中,非计划停机每年吞噬企业3%-8%的产值。中讯烛龙预测性维护系统通过多模态感知矩阵分布式智能体的创新架构,实现设备健康管理的范式跃迁,帮助制造企业将停机时间压缩70%以上。本文将深度解析技术实现路径与行业级实践方…...

day29 python深入探索类装饰器

目录 一、类装饰器的初步理解 二、类装饰器与函数装饰器的对比 三、类装饰器的实现与应用 (一)为类添加日志功能 (二)动态方法绑定的两种方式 四、手动调用装饰器:类的“后天改造” 五、总结与展望 一、类装饰器…...

Python数据分析三剑客:NumPy、Pandas与Matplotlib安装指南与实战入门

Python数据分析三剑客:NumPy、Pandas与Matplotlib安装指南与实战入门 1. 引言 Python数据分析生态:NumPy、Pandas、Matplotlib是数据科学领域的核心工具链。适用场景:数值计算、数据处理、可视化分析(如金融分析、机器学习、科研…...

二:操作系统之进程控制块(PCB)

进程的身份证与状态记录:深入理解进程控制块 (PCB) 在我们之前的博客中,我们探讨了进程是什么——程序的一次执行实例,以及进程在其生命周期中会经历的各种状态(新建、就绪、运行、等待、终止)。我们知道,…...

Spring-Beans的生命周期的介绍

目录 1、Spring核心组件 2、Bean组件 2.1、Bean的定义 2.2、Bean的生命周期 1、实例化 2、属性填充 3、初始化 4、销毁 2.3、Bean的执行时间 2.4、Bean的作用域 3、常见问题解决方案 4、与Java对象区别 前言 关于bean的生命周期,如下所示: …...

Android 自定义悬浮拖动吸附按钮

一个悬浮的拨打电话按钮,使用CardViewImageView可能会出现适配问题,也就是图片显示不全,出现这种问题,就直接替换控件了,因为上述的组合控件没有FloatingActionButton使用方便,还可以有拖动和吸附效果不是更…...

通过串口设备的VID PID动态获取串口号(C# C++)

摘要 本篇文章主要介绍分别通过C#和C++使用设备VID PID如何动态获取COM口 目录 1 简述 2 VID PID查看方式 3 C#实现通过串口设备的VID PID动态获取串口号 3.1 辅助类实现 3.2 调用实例 4 C++实现通过串口设备的VID PID动态获取串口号 4.1 辅助类实现 4.2 调用实例 1 简…...

[创业之路-361]:企业战略管理案例分析-2-战略制定-使命、愿景、价值观的失败案例

一、失败案例 1、使命方面的失败案例 真功夫创业者内乱:真功夫在创业过程中,由于股权结构不合理,共同创始人及公司大股东潘宇海与实际控制人、董事长蔡达标产生管理权矛盾。双方在公司发展方向、管理改革等方面无法达成一致,导致…...

Window远程连接Linux桌面版

Window远程连接Linux桌面版 卸载RealVNC Server 一、确认是否安装了 VNC Server 先检查是否已安装: which vncserver # 或 dpkg -l | grep vnc # 或 rpm -qa | grep vnc二、在 Debian / Ubuntu 上卸载(.deb 安装) 1. 卸载 RealVNC Serve…...