说起来贝氏曲线,咱们可能首先会想到上面这个男人:
图1. 一位不愿走漏姓名的英国球员
但实际上咱们说的不是这个叫贝克汉姆的英国男人,而是另外一个人,就是上面这个叫“ 皮埃尔·贝塞尔 ”(Pierre Bézier)的法国男人:
图2. 皮埃尔·贝塞尔
贝塞尔论起知名度,兴许不如小贝,但说起对人类的奉献,那可是杠杠的,驰名的“ 贝塞尔曲线 ”就出自他之手。1962年,贝塞尔发表了贝塞尔曲线的相干实践钻研,过后在雷诺公司工作的他,次要使用贝塞尔曲线进行汽车设计。说到这里可能还是有很多人没明确贝塞尔曲线到底是什么,看一下上面这个图,大家就明确了。
图3. 设计中用到的贝赛尔曲线
在Photoshop等多种设计软件中,画曲线时次要用到的是就是贝赛尔曲线,就是相似于上图中的这个曲线,设计师们能够通过管制两头的控制点来画出本人须要的曲线。新近设计师们想要用电脑画出一条直线灰常简略,但要画出一条平滑的曲线却十分难,而贝塞尔曲线的诞生,让大家用电脑绘制出一条平滑曲线成为了事实,这也就是贝塞尔曲线的最大用处。
而明天咱们就来说一下最简略的二阶贝塞尔曲线的推导,并用 matplotlib 进行展现。(实际上最简略的是一阶,但因为其只有一条直线,所以没有什么理论用处,就疏忽了)
咱们先来理解一下二阶贝赛尔曲线的原理。如果连在一起的两条线段AB和BC,如下图:
图4. 二阶贝赛尔曲线原理图 1
当初AB上取一点D,BC上取一点E,使得AD/AB=BE/BC,如下图:
图5. 二阶贝赛尔曲线原理图 2
而在线段DE上还要求一点F,使得DF/DE=AD/AB=BE/BC,如下图:
图6. 二阶贝赛尔曲线原理图 3
而当D在AB上一直挪动,E在BC上一直挪动,造成的F点的轨迹便是一条曲线,这条曲线就是二阶贝塞尔曲线。这就是明天咱们要推导并演示的曲线。
上面间接用Python代码来展现一下。首先还是导入各种包:
import numpy as np import matplotlib.pyplot as plt from matplotlib import animation
因为咱们用的是matplotlib来做的演示,所以要设置一下matplotlib的后端,也就是显示方式。这一行代码最好独自应用,否则容易生效,所以把它独自列出来:
%matplotlib
这是十分重要的一步,这一步能让matplotlib在绘图时弹出一个新窗口,而不是在原窗口间接绘制,因为原窗口无奈显示动画,这里用了ipython的magic 命令,也就是在一个命令后面加上“%”。在这里阐明一下,笔者用的是win7零碎,开发工具为Anaconda最新版,能够间接去Anaconda官网下载。
因为咱们要用到A、B、C三个点,所以要设置一下三个点坐标。A点坐标为x1和y1,B点为x2和y2,C点为x3和y3,再设置一个区间内点的个数dots_num,这个dots_num前面会有解释。所有这些变量的值都能够随便设定,但有一些要求,因为笔者把绘图的坐标系设定在100,也就是x轴和y轴的范畴都是0—100,所以下面三个点的坐标都不要超过这个范畴,而dots_num的数量尽可能大一些,做动画时更连贯一些,所以下面这些参数的设置如下:
x1=10 y1=80 x2=50 y2=10 x3=90 y3=80 dots_num=100
接下来是取得贝塞尔曲线的轨迹的函数:
def two_degree_bc(x1=10, y1=80, x2=50, y2=10, x3=90, y3=80, dots_num=100): #bezier curve global xt, yt, x_dots12, x_dots23, y_dots12, y_dots23 xt = [] #指标点的x坐标 yt = [] #指标点的y坐标 x_dots12 = np.linspace(x1, x2, dots_num) #线段AB的x坐标 y_dots12 = np.linspace(y1, y2, dots_num) #线段AB的y坐标 x_dots23 = np.linspace(x2, x3, dots_num) #线段BC的x坐标 y_dots23 = np.linspace(y2, y3, dots_num) #线段BC的y坐标 for i in range(dots_num): #取得指标点的轨迹 x = x_dots12[i] + (x_dots23[i]-x_dots12[i])*i / (dots_num-1) y = y_dots12[i] + (y_dots23[i]-y_dots12[i])*i / (dots_num-1) xt.append(x) yt.append(y)
这里的xt和yt是两个list,就是用来寄存指标点的x坐标和y坐标,而x_dots12和y_dots12别离是线段AB的x和y坐标,x_dots23和y_dots23别离是线段BC的x和y坐标,这四个是numpy的array格局,所有这些数据都设置成全局变量。而从下面的代码中咱们能够看到变量dots_num的作用是在线段AB和BC上取这么多的点,而后用这些点推导指标点的坐标,点的数量越多,指标点的坐标也就越多,绘制进去的曲线也就更平滑。
接下来是动画函数,这个函数前面再解释:
def run(i): art1.set_data(x_dots12[i], y_dots12[i]) art2.set_data(x_dots23[i], y_dots23[i]) art3.set_data([x_dots12[i], x_dots23[i]], [y_dots12[i], y_dots23[i]]) art4.set_data(xt[i], yt[i]) return art1,art2,art3,art4
最初就是绘制动画了,代码如下:
two_degree_bc() #学生成指标点的轨迹 fig, ax = plt.subplots(figsize=(8,8)) ax.set_aspect(1) #让两个坐标轴等比例 plt.xlim([0,100]) #设置坐标轴范畴 plt.ylim([0,100]) ax.plot([x1, x2], [y1, y2], color='#3e82fc') #绘制AB线段 ax.plot([x2, x3], [y2, y3], color='#3e82fc') #绘制BC线段 ax.plot(xt,yt,color='orange') #绘制指标曲线 art1, = ax.plot(x_dots12[0], y_dots12[0], color='green', marker='o') #不能用scatter,因为失去的对象不是一个list,是一个object art2, = ax.plot(x_dots23[0], y_dots23[0], color='green', marker='o') art3, = ax.plot([x_dots12[0], x_dots23[0]], [y_dots12[0], y_dots23[0]], color = 'purple') #plot失去的后果是一个list,只蕴含一个元素,即一个形态object art4, = ax.plot(xt[0], yt[0], color='red', marker='o') ani = animation.FuncAnimation( fig, run, frames=range(100), interval=2, save_count=50) plt.show()
这里首先运行two_degree_bc()函数失去指标点的轨迹,而后绘制AB、BC线段以及指标曲线,这些都是动态图。接着从变量art1开始就是绘制动画的局部了。这部分比较复杂,一共有art1、art2、art3和art4这四个变量,其别离对应线段AB、BC、DE和指标曲线的挪动轨迹,点在这四个轨迹上挪动,能力造成动画。而要生成动画,就要用到animation的办法FuncAnimation,其含有多个参数,fig就是咱们绘图的那个画布,run就是咱们生成动画时运行的函数,frames是帧画面,其每一帧画面蕴含了这些挪动轨迹中的一个点所对应的动态图,把这些点的轨迹也就是每一帧连起来就是动画轨迹,frames个别是一个sequence,也就是蕴含多个变量,每个变量都赋值给run函数,run函数利用这个参数生成一个动态图,这么多动态图连起来就是动画,这和咱们在电影或电视中看到的动画片是一样情理。interval是帧之间的工夫距离,200代表0.2秒,这个能够随便设定。save_count=50是把帧缓存起来用于回放,缓存帧的数量越多,回放越晦涩,这个影响不大,随便设定。
上面再说一下运行动画的函数run的作用,能够看到run一共有5行代码,前4行代码是绘图代码,最初一个是返回参数的代码,前4行中每一行都代表了后面咱们说过的点的轨迹, art1是线段AB上的点,用set_data(x_dots12[i], y_dots12[i])办法就生成了一个对应的帧,变量i就是后面讲的frames里的一个参数,生成的这个帧返回给FuncAnimation,让其用于间断播放,这就造成了动画。前面art2、art3和art4的情理是一样的。生成的动画成果的动态截图如下:
图7. 二阶贝赛尔曲线动态成图
最初再放上一个动图,让咱们在一个深V的静止中完结本次话题:
图8. 二阶贝赛尔曲线动静示意图
二阶贝塞尔曲线的推导绝对还容易一些,而三阶甚至更高阶的推导就简单一点,笔者目前正在钻研三阶贝赛尔曲线,当前会给大家分享一下。
残缺代码曾经上传:
https://gitee.com/leonmovie/two_degree_bc
有须要的能够去自行下载。
作者简介:小李子,数据分析爱好者,善于数据可视化,比拟关注机器学习畛域,心愿能和业内敌人多学习交换
——
欢送搜寻及关注: Crossin的编程教室
这里还有更多精彩。一起学,走得远