什么?贝塞尔曲线竟然可以用来描摹心仪的小姐姐!

什么是贝塞尔曲线?

​ 贝塞尔曲线于 1962 年,由法国工程师皮埃尔·贝济埃(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计,贝塞尔曲线最初由保尔·德·卡斯特里奥于1959年运用德卡斯特里奥算法开发,以稳定数值的方法求出贝塞尔曲线。

​ 贝塞尔曲线具有很多特殊的性质,在一些领域比如图形设计中应用十分广泛,贝塞尔曲线完全由其控制点决定其形状, n个控制点对应着n-1阶的贝塞尔曲线,并且可以通过递归的方式来绘制。

一阶曲线

在这里插入图片描述

一阶曲线很好理解, 就是根据t来的线性插值. P0P_0P0表示的是一个向量(x,y)(x ,y)(x,y), 其中xxxyyy是分别按照这个公式来计算的。
B1(t)=(1−t)P0+tP1,t∈[0,1] B_{1}(t)=(1-t) P_{0}+t P_{1}, t in[0,1] B1(t)=(1t)P0+tP1,t[0,1]
可以看到,一阶曲线是一条直线。

二阶曲线

既然前面提到递归,那么二阶必然和一阶有关系,

在这里插入图片描述

在平面上三个不共线的三点,依次用线段连接,分别取PaP_aPaPbP_bPb两点,使得P0Pa:PaP1=P1Pb:PbP2=tP_0P_a:P_aP_1=P_1P_b:P_bP_2=tP0Pa:PaP1=P1Pb:PbP2=t,此时PaPbP_aP_bPaPb又是一条直线,可以按照一阶方式来插值了:
Pa=(1−t)P0+tP1 P_a=(1-t) P_{0}+t P_{1} Pa=(1t)P0+tP1

Pb=(1−t)P1+tP2 P_b=(1-t) P_{1}+t P_{2} Pb=(1t)P1+tP2

B2(t)=(1−t)Pa+tPb=(1−t)2P0+2t(1−t)P1+t2P2,t∈[0,1] B_2(t)=(1-t) P_{a}+t P_{b}=(1-t)^{2} P_{0}+2 t(1-t) P_{1}+t^{2} P_{2}, t in[0,1] B2(t)=(1t)Pa+tPb=(1t)2P0+2t(1t)P1+t2P2,t[0,1]

三阶曲线

二阶的贝塞尔通过在控制点之间再采点的方式实现降阶, 每一次选点都是一次的降阶,三阶的也是同理:

在这里插入图片描述

这样通过给定的离散点就能确定它们之间的插值曲线了。

钢笔工具

贝塞尔曲线在图形设计的应用中,最典型的就是Photoshop中的钢笔工具。如下,中间一个节点,两边两个手柄,调节手柄的方向可以控制曲线的走向,调节手柄的长度可以控制曲线的弧度,也就是调节ttt的过程。

熟练运用之后就能绘制复杂的图形,然后上色即可。

在这里插入图片描述

使用python绘制图像

到这里开始切入正题了,前面提到既然贝塞尔曲线可以通过公式表示,那么一定可以通过python实现自动化操作。整体的思路就是给定一个位图图像,然后将其矢量化以保存矢量路径,然后读取路径使用贝塞尔曲线勾勒填充就可以了。

位图矢量化

位图与矢量图的一大区别就是位图图像进行处理,放大后会出现方块状,图片属于真彩色,图片会失真。位图图像善于重现颜色的细微层次,能够制作出色彩和亮度变化丰富的图像,可逼真地再现这个世界,文件庞大,不能随意缩放。矢量图中保存的是线条和图块的信息,也就是所谓的路径,在python中可以借助Potrace模块来完成矢量化的操作。

在这里插入图片描述

定义贝塞尔曲线

根据前面的知识定义贝塞尔曲线比较简单,这里使用粗暴的函数嵌套方式,感兴趣的可以另外改善。

在这里插入图片描述

对于复杂的图像我们一般使用三阶以上的曲线描摹,需要定义类似于画笔的操作,即绘制曲线至(x,y)点,

在这里插入图片描述

然后就是其他的线条操作。

绘图

前面位图中存取了路径信息,我们只需要根据相应的路径使用相应的绘制操作即可,如下

在这里插入图片描述

整个绘图过程可以采用python中的turtle模块,完成动画,整个过程约二三十分钟,一气呵成,用来描摹心仪的小姐姐最合适不过~,下面放上小姐姐的照片,

在这里插入图片描述

然后经过简单的剪辑配乐,就可以做成日常逗人开心的小视频了,点击下面链接即可观看,

用python画出南方菇凉~

代码链接:draw-picture-with-turtle

原文地址:https://www.cnblogs.com/hzcya1995/p/13281638.html