1. 原理解释(均匀节点)

  • 对于给定Bezier曲线上的插值点PiP_iPi,通过Pi=r(ui)=∑j=0nJn,j(ui)VP_i = r(u_i)=\sum_{j=0}^n{J_{n,j}(u_i)V}Pi=r(ui)=j=0nJn,j(ui)V;
  • 其中V=[V0,V1,⋯,Vn]V=[V_0,V_1,\cdots,V_n]V=[V0,V1,,Vn],称ViV_iVi型值点P=[P1,P2,⋯,Pn]P = [P_1,P_2,\cdots,P_n]P=[P1,P2,,Pn],且PiP_iPi为给定值,而uiu_iui[0,1][0,1][0,1]范围内的一个节点,在本程序中我们认为uiu_iui均匀节点,即n次Bezier曲线在[0,1][0,1][0,1]上有n+1个节点,例n=4,u=[0,0.25,0.5,0.75,1]n=4,u = [0,0.25,0.5,0.75,1]n=4,u=[0,0.25,0.5,0.75,1]
  • 由Bezier曲线的端点性质可以知道曲线在端点处型值点插值点为同一个点。
  • 结果展示:

    bezier反解作图

2. 原理解释(非均匀节点)

3. Jupyter程序

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import mathplt.rcParams["font.sans-serif"]=["SimHei"] #设置字体
plt.rcParams["axes.unicode_minus"]=False #该语句解决图像中的“-”负号的乱码问题
# 阶乘函数
def jc(x):return math.factorial(x)def Bernstein(n,m): u1 = np.linspace(0,1,n+1)  # u1 代表插值点对应的均匀点 uiu2 = np.linspace(0,1,m)  # m 代表画曲线时 u 的取点数量J1 = pd.DataFrame() # 存储伯恩斯坦基函数在给定 u1 下系数矩阵J2 = pd.DataFrame() # 存储为绘制曲线的系数矩阵for i in range(n+1):k = icolumn = 'C'+str(i)C_nk = jc(n)/(jc(k)*jc(n-k))J_nk1 = C_nk*pow(u1,k)*pow(1-u1,n-k)J_nk2 = C_nk*pow(u2,k)*pow(1-u2,n-k)J1[column] = J_nk1J2[column] = J_nk2J1 = np.around(np.matrix(J1).I,2)   # 将伯恩斯坦基函数取逆后截取两位小数
#     print(J1,J2)return J1,J2
# 输入n
def Bezier_inverse():n = int(input("请输入n(n为Bezier次数):"))m = int(input("请输入m(m为u的取值个数):"))print("请输入{0}个插值点".format(n+1))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)J1,J2 = Bernstein(n,m)  # J1为一个 n+1*n+1 的矩阵X_con = []  # 存储控制点的坐标Y_con = []X_bez = []Y_bez = []X_con = J1*np.matrix(x).T  # 计算控制点的X值Y_con = J1*np.matrix(y).T  # 计算控制点的Y值for i in range(m):  a = sum(J2.iloc[i,:]*X_con.T.tolist()[0])  # x为所有点x轴的值b = sum(J2.iloc[i,:]*Y_con.T.tolist()[0])  # 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_con,Y_con,marker='o',markerfacecolor='white')  # 画空心圆plt.plot(x,y,'ro')plt.plot(X_bez,Y_bez)  # 画空心圆plt.xticks(fontsize=14)plt.yticks(fontsize=14)plt.show()

4. 封装至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): u1 = np.linspace(0,1,self.n+1)u2 = np.linspace(0,1,self.m)  # m代表[0,1]上取多少个点J1 = pd.DataFrame() # 存储伯恩斯坦基函数在给定u1下的的值J2 = pd.DataFrame() # 存储为给定u的值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_nk1 = C_nk*pow(u1,k)*pow(1-u1,self.n-k)J_nk2 = C_nk*pow(u2,k)*pow(1-u2,self.n-k)J1[column] = J_nk1J2[column] = J_nk2J1 = np.around(np.matrix(J1).I,2)return J1,J2# 输入ndef Bezier_inverse(self):# 调用Bernstein基函数J1,J2 = self.Bernstein()X_con = []  # 存储控制点的坐标Y_con = []X_bez = []  # 存储Bezier曲线上的所有点Y_bez = []X_con = J1*np.matrix(self.x).T  # 计算控制点的X值Y_con = J1*np.matrix(self.y).T  # 计算控制点的Y值for i in range(self.m): a = sum(J2.iloc[i,:]*X_con.T.tolist()[0])  # x为所有点x轴的值b = sum(J2.iloc[i,:]*Y_con.T.tolist()[0])  # y为所有点y轴的值X_bez.append(a)Y_bez.append(b)self.ax.plot(X_con,Y_con,marker='o',markerfacecolor='white')  # 画空心圆# 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_inverse()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 = []  # 存储figure的x轴区间y1 = []  # 存储figure的y轴区间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()

【Python】Bezier曲线插值反解控制顶点相关推荐

  1. Bezier曲线插值拟合

    基本原理 传统的插值方法是经过所有的给定点而形成的光滑曲线,但随着给定点的变多,简单曲线的求解过程也变得越来越繁琐和不易计算并且会产生一些误差,例如龙格现象,而Bezier曲线与传统插值方法不一样,他 ...

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

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

  3. 用MATLAB画Bezier曲线

    关于Bezier曲线 给定n+1个空间向量Pi∈R3(i=0,1,⋯ ,n),称n次参数曲线段给定n+1个空间向量P_i\in \mathbb{R^3}(i=0,1,\cdots,n),称n次参数曲线 ...

  4. Bezier曲线(附Python实现代码)

    上一讲讲解了伯恩斯坦多项式,现在就开始对Bezier曲线进行研究.Bezier曲线采用伯恩斯坦多项式作为基函数. 首先,我们定义Bezier曲线的表达式: C(t)=∑k=0nPkBkn(t)(1)\ ...

  5. 【Python】Bezier曲线的绘制

    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 ...

  6. Bezier曲线简介

    Bezier曲线简介 Bezier曲线,又有人叫贝赛尔曲线,贝兹曲线,在计算机绘图中经常被用到,由于前些天事件要用到这个,所以就研究了下. 有了参考资料,其实也不是很复杂. 曲线的介绍(转自维基百科, ...

  7. 机器人曲线插值拟合算法研究现状简述

    混沌无形 混沌系统是世界本质,无形之中存在规律.机器人智能化发展从线性过渡到混沌,本号将分享机器人全栈技术(感知.规划.控制:软件.机械.硬件等). 38篇原创内容 公众号 [文末提供原文PDF免费下 ...

  8. Bezier曲线切割

    贝塞尔曲线 目标:在unity中展示Bezier曲线. 贝塞尔曲线原理 用代码实现 bezier数学公式 Bezier公式(一般参数公式) 注解: 阶贝兹曲线可如下推断.给定点P0.P1.-.Pn,其 ...

  9. Bezier曲线快速相交计算(含代码)

    Bezier曲线快速相交计算 背景介绍 算法思路 解释和分析 示例 参考资料 背景介绍 很多时候,需要计算曲线段与曲线段是否有交点.常规的思路是直接联立方程求解.不过,直接求方程的解这种思路通常在计算 ...

最新文章

  1. php中static和self的区别
  2. 招聘面试的套路和原则
  3. [python爬虫] BeautifulSoup和Selenium简单爬取知网信息测试
  4. Virtual Box中Centos虚拟机设置静态IP
  5. spring mvc xss html,note/SpringMvc防御XSS实践.md at master · yangc91/note · GitHub
  6. Echarts-地图扩展-标准geoJson格式扩展地图-例子
  7. 随机效应估算与固定效应估算_纯电动汽车的电池价格,可以怎么估算?
  8. python UI自动化无界面运行
  9. 雷赛服务器信号er020,雷赛配合松下电机做三轴,xy轴到位信号的问题
  10. 从苏宁电器到卡巴斯基(第二部)第09篇:我在卡巴的日子 IX
  11. Word实现奇数页眉为一级标题文字,偶数页眉为论文标题
  12. Java字符串(超超超详细)
  13. .Net插件编程模型:MEF和MAF
  14. C语言实现成绩等级判别
  15. php无法获取操作系统信息,如何获取操作系统信息
  16. 【计算机毕业设计】基于微信小程序的校园跑腿系统
  17. win11 眼睛保护色
  18. win7系统忘记登陆密码的五种解决方法(图文)
  19. 3Dmax+blend+WPF综合运用
  20. 易语言局域网 php 控制,易语言控制端源码,易语言被控制源码,易语言局域网远程控制源码...

热门文章

  1. 乐视手机插电信卡显示无服务器,乐视手机1支持电信卡吗?乐视手机1支持联通卡吗?...
  2. 小项目之猜数字小游戏(剪刀,石头,布)
  3. Android Studio程序打包步骤
  4. J9数字论:以太坊合并?以太坊合并又会带来哪些影响?
  5. ​深圳文交所区块链应用基地叫停风波:业务调整还是另有隐情
  6. android 拖动控件删除,Android学习------拖动删除(仿微信朋友圈拖动删除)
  7. python3爬虫之访问量、点击率数据的爬取分析
  8. Linux嵌入式学习——c语言选择结构设计
  9. 元气森林讲出新的“可乐味”故事?
  10. 学Python的目的