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

贝塞尔曲线原理

文章目录

  • 一、 低阶贝塞尔曲线
    • 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
http://www.xdnf.cn/news/510463.html

相关文章:

  • Android studio Could not move temporary workspace
  • 使用AI 生成PPT 最佳实践方案对比
  • ChatGPT:OpenAI Codex—一款基于云的软件工程 AI 代理,赋能 ChatGPT,革新软件开发模式
  • window自带截图快捷键
  • C++学习:六个月从基础到就业——C++20:范围(Ranges)基础
  • 【OpenCV基础 1】几何变换、形态学处理、阈值分割、区域提取和脱敏处理
  • MLLM常见概念通俗解析(一)
  • 【基于Spring Boot 的图书购买系统】深度讲解 用户注册的前后端交互,Mapper操作MySQL数据库进行用户持久化
  • 如何利用内网穿透实现Cursor对私有化部署大模型的跨网络访问实践
  • 【图像生成大模型】CogVideoX-5b:开启文本到视频生成的新纪元
  • lvs-dr部署
  • c++学习之--- list
  • C语言链表的操作
  • 数字人技术的核心:AI与动作捕捉的双引擎驱动(210)
  • defer关键字:延迟调用机制-《Go语言实战指南》
  • 8.1UDP点对点聊天小项目
  • 软件架构之--论微服务的开发方法1
  • 软件工程各种图总结
  • 数据库MySQL基础2
  • 【回溯 剪支 状态压缩】# P10419 [蓝桥杯 2023 国 A] 01 游戏|普及+
  • Java大厂面试:从Web框架到微服务技术的场景化提问与解析
  • FAST-DDS源码分析PDP(一)
  • NoSQL实战指南:MongoDB与Redis企业级开发实战
  • Vue 3 动态 ref 的使用方式(表格)
  • 【Linux高级全栈开发】2.1.3 http服务器的实现
  • AI:NLP 情感分析
  • Filament引擎(一) ——渲染框架设计
  • 中级网络工程师知识点7
  • 课外活动:需了解的海象运算符(:=)
  • HTTPS的工作过程