Bezier曲线的绘制

r(u)=∑iJn,i(u)Vir(u) = \sum_i{J_{n,i}(u)V_i}r(u)=∑i​Jn,i​(u)Vi​
Jn,i=Cniui(1−u)n−iJ_{n,i} = C^i_nu^i(1-u)^{n-i}Jn,i​=Cni​ui(1−u)n−i

1. 方法

  1. 输入n作为Bezier曲线的次数

  2. 手动在画布上点击n+1个点(未实现,采用了手动输入坐标点)

  3. 绘制控制多边形,即相邻两个点之间用直线连接

  4. 通过Bezier曲线函数绘制曲线

2. 导入相关程序包

# 导入相关包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pylab import xticks,yticks
import math
import randomplt.rcParams["font.sans-serif"]=["SimHei"] #设置字体
plt.rcParams["axes.unicode_minus"]=False #该语句解决图像中的“-”负号的乱码问题

3. 修改定义Bernstein基函数

Bernstein基函数绘制可见https://blog.csdn.net/weixin_45718987/article/details/124584407?spm=1001.2014.3001.5502

# 阶乘函数
def jc(x):return math.factorial(x)def Bernstein(n,m): u = np.linspace(0,1,m)  # m代表[0,1]上取多少个点J = pd.DataFrame() # 存储伯恩斯坦基函数的值for i in range(n+1):k = icolumn = 'C'+str(i)C_nk = jc(n)/(jc(k)*jc(n-k))J_nk = C_nk*pow(u,k)*pow(1-u,n-k)J[column] = J_nkreturn J

4. 定义Bezier曲线函数

# 输入n
def Bezier():n = int(input("请输入n(n为Bezier次数):"))m = int(input("请输入m(m为u的取值个数):"))x = []y = []for i in range(n+1):x1 = float(input("请输入第{0}个点的x坐标:".format(i+1)))y1 = float(input("请输入第{0}个点的y坐标:".format(i+1)))print("添加坐标点({0},{1})\n".format(x1,y1))x.append(x1)y.append(y1)J = Bernstein(n,m)# x = [1,2,3,4,5,6,7,7]# y = [1,1.5,1.5,0.5,0.5,1,0.8,0]X_bez = []Y_bez = []for i in range(m):  a = sum(J.iloc[i,:]*list(x))  # x为所有点x轴的值b = sum(J.iloc[i,:]*list(y))  # y为所有点y轴的值X_bez.append(a)Y_bez.append(b)# 绘制Bezier曲线fig = plt.figure(figsize=(10,8))fig.suptitle(str(n)+'次Bezier曲线',fontsize=16)plt.plot(x,y,marker='o',markerfacecolor='white')  # 画空心圆plt.plot(X_bez,Y_bez)  # 画空心圆plt.xticks(fontsize=14)plt.yticks(fontsize=14)# plt.axis([-1,8,-0.2,2])# plt.xticks(np.linspace(0,10,11))# plt.yticks(np.linspace(0,5,11))plt.show()

5. Bezier()函数调用绘制曲线

Bezier()
请输入n(n为Bezier次数):7
请输入m(m为u的取值个数):100
请输入第1个点的x坐标:1
请输入第1个点的y坐标:1
添加坐标点(1.0,1.0)请输入第2个点的x坐标:2
请输入第2个点的y坐标:2
添加坐标点(2.0,2.0)请输入第3个点的x坐标:3
请输入第3个点的y坐标:2
添加坐标点(3.0,2.0)请输入第4个点的x坐标:4
请输入第4个点的y坐标:0
添加坐标点(4.0,0.0)请输入第5个点的x坐标:5
请输入第5个点的y坐标:0
添加坐标点(5.0,0.0)请输入第6个点的x坐标:6
请输入第6个点的y坐标:1
添加坐标点(6.0,1.0)请输入第7个点的x坐标:7
请输入第7个点的y坐标:0.5
添加坐标点(7.0,0.5)请输入第8个点的x坐标:7
请输入第8个点的y坐标:-0.5
添加坐标点(7.0,-0.5)

6. 通过鼠标click方法在画布上选取坐标点方法

  • 封装为class,因为class中全局变量方便使用;
  • matplotlib中交互取点的方法是用canvas.mpl_connect,其下有许多鼠标或键盘的画布取点响应方式;
  • class中定义函数,注意添加self,用来继承类中的方法和对象,在类中一个函数func1(self)调用另一个函数func2(self)需要采用格式:self.func2();
  • 下面将1-5的Bezier曲线绘制封装至class中,并在类中定义鼠标取点方法
import matplotlib.pyplot as plt
import numpy as np
from numpy.random import rand
import pandas as pd
import math
import randomplt.rcParams["font.sans-serif"]=["SimHei"] #设置字体
plt.rcParams["axes.unicode_minus"]=False #该语句解决图像中的“-”负号的乱码问题class click_curve:# 在类中定义的带self的变量均为全局变量def __init__(self,n,m,ax):self.ax = axself.m = mself.n = nself.x = []self.y = []self.i = 0self.cid = self.ax.figure.canvas.mpl_connect('button_press_event', self)def jc(self,a):  # 阶乘return math.factorial(a)def Bernstein(self): u = np.linspace(0,1,self.m)  # m代表[0,1]上取多少个点J = pd.DataFrame() # 存储伯恩斯坦基函数的值for i in range(self.n+1):  # 输入n个点,n不为次数k = icolumn = 'C'+str(i)C_nk = self.jc(self.n)/(self.jc(k)*self.jc(self.n-k))J_nk = C_nk*pow(u,k)*pow(1-u,self.n-k)J[column] = J_nkreturn J# 输入ndef Bezier(self):# 调用Bernstein基函数J = self.Bernstein()X_bez = []Y_bez = []for i in range(self.m): a = sum(J.iloc[i,:]*list(self.x))  # x为所有点x轴的值b = sum(J.iloc[i,:]*list(self.y))  # y为所有点y轴的值X_bez.append(a)Y_bez.append(b)self.ax.plot(self.x,self.y,'b')  # 连线self.ax.plot(X_bez,Y_bez,'r')  # 画曲线print('success')self.ax.figure.canvas.draw()def __call__(self,event):if event.inaxes != None:if event.button==1 and self.i < self.n+1:self.i+=1#     plt.ax.scatter(event.xdata, event.ydata)self.x.append(event.xdata)self.y.append(event.ydata)print("输入坐标点为:({0:.2f},{1:.2f})".format(event.xdata, event.ydata))self.ax.plot(event.xdata, event.ydata, 'bo',markerfacecolor='white')self.ax.text(event.xdata+0.05, event.ydata+0.05,"({0:.2f},{1:.2f})".format(event.xdata, event.ydata))self.ax.figure.canvas.draw()elif self.i >= self.n+1:print("绘图结束")print("x取值:{0}".format(self.x))print("y取值:{0}".format(self.y))self.Bezier()print("end")returnelse:print("出界了")# def click1(self):#     self.ax.figure.canvas.mpl_connect('button_press_event', self.click)def main():    n = int(input("请输入次数:"))x = input("请输入你希望的X轴区间(用空格隔开):").split(" ")y = input("请输入你希望的Y轴区间(用空格隔开):").split(" ")m = int(input("请输入m(m为u的取值个数):"))print("\n请在画布上依次点击{0}个点".format(n+1))x1 = []y1 = []for i in range(len(x)):x1.append(int(x[i]))y1.append(int(y[i]))fig = plt.figure()ax1 = fig.add_subplot(111)plt.xlim(x1[0],x1[1])plt.ylim(y1[0],y1[1])plt.title("{0}次Bezier曲线".format(n))plt.yticks(fontsize=14)plt.xticks(fontsize=14)click_curve(n,m,ax1)# test.click1()plt.show()if __name__ == '__main__':main()
  • 取n=3,x∈[0,5],y∈[0,5],m=100n=3, x\in[0,5],y\in[0,5],m=100n=3,x∈[0,5],y∈[0,5],m=100,得到绘图过程图如下所示:
请输入次数:3请输入你希望的X轴区间(用空格隔开):0 5请输入你希望的Y轴区间(用空格隔开):0 5请输入m(m为u的取值个数):100请在画布上依次点击4个点
输入坐标点为:(0.70,1.80)
输入坐标点为:(1.67,3.84)
输入坐标点为:(3.73,3.94)
输入坐标点为:(2.47,2.84)
绘图结束
x取值:[0.6955645161290323, 1.6733870967741937, 3.729838709677419, 2.469758064516129]
y取值:[1.7980011531808577, 3.8435243403530928, 3.939622745119574, 2.841355262074078]
success
end

交互取点



【Python】Bezier曲线的绘制相关推荐

  1. bezier 曲线的绘制 matlab实现

    Bezier曲线的定义如下: 下面用matlab实现Bezier曲线的绘制: 1.绘制二维bezier曲线代码如下: function [X,Y]=bezier2(x,y) %用法: %bezier( ...

  2. 计算机图形学:三次Bezier曲线的绘制(算法原理及代码实现)

    一.实现方案 贝塞尔曲线原理:贝塞尔曲线是计算机图形图像造型的基本工具,是图形造型运用得最多的基本线条之一.它通过控制曲线上的四个点(起始点.终止点以及两个相互分离的中间点)来创造.编辑图形.其中起重 ...

  3. 计算机图形学:Bezier曲线的绘制

    1.实验目的 掌握Bezier曲线的定义原理及绘制过程 定义: 贝塞尔曲线(Bezier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线.一般的矢量图形软件通过它来精确画出 ...

  4. Bezier曲线曲面绘制

    知识点: Bezier曲面性质 Bezier曲线简单理解 代码参考:https://blog.csdn.net/wpxu08/article/details/70208395 曲线 #include ...

  5. qt下bezier曲线的绘制(C++)

    <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255) ...

  6. [1106]python bezier(贝塞尔)曲线

    文章目录 三阶贝塞尔曲线 python bezier曲线 首先简单了解一下什么是贝塞尔曲线(余弦函数曲线我就不多说了哈!),贝塞尔曲线又称贝兹曲线,是法国工程师皮埃尔.贝塞尔于1962年发表.贝塞尔曲 ...

  7. 计算机图形学 实验7 《复杂图形绘制-Bezier曲线与Hermite曲线》

    计算机图形学 实验7 <复杂图形绘制-Bezier曲线与Hermite曲线> 一.实验目的 学习样条曲线的绘制. 二.实验内容 1.绘制Bezier曲线: 2.绘制Hermite曲线. 三 ...

  8. js实现三次bezier曲线的拼接

    要实现bezier曲线的拼接首先要实现bezier曲线的绘制.绘制有两个方法: 利用bezier曲线的定义写算法,生成bezier曲线. 有兴趣的同学可以进去看看: [一次二次三次bezier曲线的计 ...

  9. python绘制等距曲线_python应用之猪肉价格曲线的绘制

    python应用之猪肉价格曲线的绘制 刘巍巍 大家这学期和我一起去食堂的时候,有没有这样的感觉--猪肉居然成了稀奇东西!!!食堂开始大量用鸡肉和鸭肉来代替猪肉.一到菜市场去看,居然猪肉都支持分期付款了 ...

最新文章

  1. python恶搞代码-搞笑的程序猿:看看你是哪种Python程序员
  2. java中读取文件的方法
  3. mysql行转列sql函数_SQL 将行转化为列实现列的动态更新
  4. wxWidgets:wxDragImage类用法
  5. 【数字逻辑设计】Logisim构建抢答环节电路
  6. git管理工具_使用包管理工具
  7. 基于python的图像变换(翻转、平移、缩放、旋转、仿射和透视变换)
  8. 4-2-在Servlet中解决中文输出乱码问题
  9. python逢7跳过_python实现逢七拍腿小游戏的思路详解
  10. 论文阅读:BASNet:Boundary-Aware Salient Object Detection
  11. 文本编辑器Typora软件免费版本下载及其用法
  12. macOS安装yarn
  13. oracle wish as,虚拟语气:wish、if only和as if的用法
  14. linux启动mysql失败,Fatal error: Can‘t open and lock privilege tables: Table ‘mysql.host‘ doesn‘t exist
  15. 长安大学有没有MATLAB,长安大学公路学院研究生导师:韩万水
  16. v-for 遍历数组数字
  17. 曲面触摸传感器设计的挑战
  18. 【memcached】可视化memcache监控工具memcachephp安装与使用
  19. 谱聚类(spectral clustering)及其实现详解
  20. 【论文】CVPR、ICCV等会议及地点

热门文章

  1. Vod Vlc Playlist
  2. 期货是赚谁的钱(期货赚的钱是从哪里来的)
  3. hive架构介绍、SQL引擎与NoSQL引擎的对比
  4. C++ fstream类移动读写指针和字节数形式获取该指针位置(seekp、seekg、tellg、tellp)
  5. 全国计算机等级考试忘了准考证号码怎么查询
  6. 程序员入门第一个程序
  7. html expires缓存,expires
  8. 政务服务供给侧的业务协同、数据共享
  9. 护士常用计算机,临床护理中常见数值一览表,护士必备哦!
  10. HTML中单引号和双引号区别