在Android开发和面试中(尤其是一些中高级岗位面试),面试官可能会问你自定义控件的详细内容,我们知道自定义控件这一块涉及到的内容很多,回答的越多越深入,那么面试的印象会更好。自定义控件涉及的内容比如测量和绘制、事件分发的处理、动画效果的渲染与实现,当然还有不得不提的贝赛尔曲线(实际上一些面试官自己都不是很理解二阶贝塞尔、三阶贝塞尔曲线等概念)。
一些朋友看到以歪果仁大佬名字定义的一些计算公式、定理就头大(比如梅涅劳斯(Menelaus)定理、塞瓦(Ceva)定理等),不得不承认我也是。本着《士兵突击》不抛弃不放弃的精神,因此就算是在难啃的骨头我们也要坚持啃下来!所以本篇文章主要介绍的是贝赛尔曲线的基本概念、在Android的应用场景以及一些思考。不考虑篇幅的情况下力求将概念和理解写的详细。
贝赛尔曲线的前世今生:
贝塞尔曲线,这个命名规则一眼看上去大概是一个叫贝塞尔的数学家发明的。但,贝塞尔曲线依据的最原始的数学公式,是在1912年在数学界广为人知的伯恩斯坦多项式。简单理解,伯恩斯坦多项式可以用来证明,在[ a, b ] 区间上所有的连续函数都可以用多项式来逼近,并且收敛性很强,也就是一致收敛。再简单点,就是一个连续函数,你可以将它写成若干个伯恩斯坦多项式相加的形式,并且,随着 n→∞,这个多项式将一致收敛到原函数,这个就是伯恩斯坦斯的逼近性质。
时光荏苒岁月如梭,镜头切换到了1959年。当时就职于雪铁龙的法国数学家 Paul de Casteljau 开始对伯恩斯坦多项式进行了图形化的尝试,并且提供了一种数值稳定的德卡斯特里奥(de Casteljau) 算法。(多数理论公式是建立在大量且系统的数学建模基础之上研究的规律性成果)根据这个算法,就可以实现 通过很少的控制点,去生成复杂的平滑曲线,也就是贝塞尔曲线。
但贝塞尔曲线的声名大噪,不得不提到1962年就职于雷诺的法国工程师皮埃尔·贝塞尔(Pierre Bézier),他使用这种方法来辅助汽车的车体工业设计(最早计算机的诞生则是为了帮助美国海军绘制弹道图),并且广泛宣传(典型的理论联系实际并获得成功的示例),因此大家称为贝塞尔曲线 。
贝赛尔曲线的数学理论:
既然贝赛尔曲线的本质是通过数学计算公式去绘制平滑的曲线,那就可以通过数学工具进行实际求证以及解释说明。当然对其进行数学求证就没必要了,因为这些伟大的数学家们已经做过了,这里只是解释说明:
- 步骤一:在平面内选3个不同线的点并且依次用线段连接。如下所示..
3点连线
-
步骤二:在AB和BC线段上找出点D和点E,使得 AD/AB = BE/BC
AD/AB = BE/BC
-
步骤三:连接DE,在DE上寻找点F,F点需要满足:DF/DE = AD/AB = BE/BC
DF/DE = AD/AB = BE/BC
-
步骤四:最最重要的!根据DE线段和计算公式找出所有的F点,记住是所有的F点,然后将其这些点连接起来。那,连接规则是什么?以上图为例,第一个连接点是A-F,第二连接点是A-F1(这个F1必须满足DF1/DE = AD/AB = BE/BC)以此类推,直到最后连接上C点,下面上一个动图加深理解:
贝塞尔曲线
可能有些朋友还是不理解,那么这个GIF我截下其中的一张图说明,如下图:
示例说明
动图里的P0、P1、P2分别代表的是上图的:P0 == A;P1 == B;P2 == C。那么这个黑色点,代表的就是F点,绿色线段的2个端点(P0-P1线段上的绿色点,代表是就是D点,P0-P2线段上的绿色点,代表是就是E点)。线段上面点的获取,必须要满足等比关系。
关于贝赛尔曲线的基本数学理论大概就是上面的内容。两个线段根据等比关系找点的贝塞尔曲线,一般也称为二阶贝塞尔曲线。
贝赛尔曲线的N阶拓展(三阶贝塞尔与N阶贝塞尔曲线)
刚才说到,上面的贝赛尔曲线一般称为二阶贝塞尔曲线,既然是二阶贝塞尔曲线,那肯定有三阶贝塞尔曲线、四阶贝赛尔曲线等等。其实三阶贝塞尔与四阶贝赛尔曲线以及N阶贝赛尔曲线曲线的规则都是一样的,都是先在线段上找点,这个点必须要满足等比关系,然后依次连接,下面是三阶贝赛尔曲线的解释说明:
-
步骤一:三阶贝赛尔曲线,简单理解就是在平面内选4个不同线的点并且依次用线段连接(也就是三条线)。如下所示
四点三线
-
步骤二:同二阶贝塞尔曲线一样首先需要在线段上找对应的点(E、F、G),对应的点必须要符合等比的计算规则,计算规则如下:AE/AB = BF/BC = CG/CD;找到对应的点以后接着依次链接EF、FG;接着在EF、FG线段上面继续找点H、I,对应的点依旧要符合等比的计算规则,也就是 EH/EF = FI/FG;最后连接H、I线段,在HI线段上面继续找点J、点J的计算规则需要符合:EH/EF = FI/FG = HJ/HI
三阶贝赛尔曲线找点
-
步骤三:重复步骤二的动作,找到所有的J点,依次将J点连接起来,这样最终完成了三阶贝赛尔曲线。
J点依次连线
整一个三阶贝赛尔曲线的动作加起来就是下面的一张动图:
三阶贝塞尔
那么四阶贝赛尔曲线的实现步骤也是一样的,平面上先选取5个点(5点4线)、依次选点(满足等比关系)、依次连接、根据计算规则找到所有的点(逐个连接)。。。。。。
四阶贝赛尔曲线
貌似都是从二阶贝塞尔曲线说起的,那么一阶贝赛尔又是怎么样的?一阶贝赛尔如图:
一阶贝赛尔
可以看到一阶贝赛尔是一条直线!因此,N阶贝赛尔不仅可以画平滑的曲线也可以画直线,因此自定义控件画直线又多了一种可选择的方式,但是一般用贝赛尔主要是画曲线,这里只是提供了一种别的解决思路;另外,在Android属性动画,系统为我们提供了一个PathInterpolator插值器。这个PathInterpolator里面就有贝塞尔曲线的身影。有兴趣的小伙伴也可以去了解一下。
未完待续。。。
如果这篇文章对您有开发or学习上的些许帮助,希望各位看官留下宝贵的star,谢谢。
Ps:著作权归作者所有,转载请注明作者, 商业转载请联系作者获得授权,非商业转载请注明出处(开头或结尾请添加转载出处,添加原文url地址),文章请勿滥用,也希望大家尊重笔者的劳动成果。
----------------------------------------------------------------
作者:FrancisZhao
链接:https://www.zhihu.com/question/29565629/answer/1184466425
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这篇是刚刚新鲜出炉的B样条曲线,建议大家看完本篇的贝塞尔再看这个B样条。
FrancisZhao:在B-spline中,如何理解knot和breakpoint?彼此之间联系和区别是什么?www.zhihu.com
最近正在研究贝塞尔曲线. 在学习之际也把自己的思路写下来.
下面的链接可以拖拽贝塞尔的点, 先感受一下贝塞尔曲线的圆润.
Animated Bézier Curveswww.jasondavies.com
贝塞尔曲线的历史:
贝塞尔曲线于 1962 年,由法国工程师皮埃尔·贝济埃(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计,贝塞尔曲线最初由保尔·德·卡斯特里奥于1959年运用德卡斯特里奥算法开发,以稳定数值的方法求出贝塞尔曲线.
贝塞尔曲线有着很多特殊的性质, 在图形设计和路径规划中应用都非常广泛, 我就是想在路径规划中
贝塞尔曲线完全由其控制点决定其形状, n个控制点对应着n-1阶的贝塞尔曲线,并且可以通过递归的方式来绘制. 画重点了啊: 递归
一阶曲线:
对于一阶贝塞尔曲线为我们可以看到是一条直线,通过几何知识,很容易根据t的值得出线段上那个点的坐标:
一阶曲线就是很好理解, 就是根据t来的线性插值. P0表示的是一个向量 [x ,y], 其中x和y是分别按照这个公式来计算的.
二阶贝塞尔:
既然重点是递归, 那么二阶贝塞尔必然和一阶有关系.
在平面内任选 3 个不共线的点,依次用线段连接。在第一条线段上任选一个点 D。计算该点到线段起点的距离 AD,与该线段总长 AB 的比例。
根据上一步得到的比例,从第二条线段上找出对应的点 E,使得 AD:AB = BE:BC。
这时候DE又是一条直线了, 就可以按照一阶的贝塞尔方程来进行线性插值了, t= AD:AE
这时候就可以推出公式了.
推公式的主图
对应着上图绿色线段的左端点
对应着上图绿色线段的右端点
对应着绿色线段的一阶贝塞尔曲线(线性插值)
整理一下公式, 得到二阶贝塞尔公式
三阶贝塞尔曲线:
二阶的贝塞尔通过在控制点之间再采点的方式实现降阶, 每一次选点都是一次的降阶.
四个点对应是三次的贝塞尔曲线. 分别在 AB BC CD 之间采EFG点, EFG三个点对应着二阶贝塞尔, 在EF FG之间采集HI点来降阶为一阶贝塞尔曲线.
高阶贝塞尔曲线:
高阶的贝塞尔可以通过不停的递归直到一阶
贝塞尔曲线 公式
可以通过递归的方式来理解贝塞尔曲线, 但是还是给出公式才方便计算的.
仔细看可以发现, 贝塞尔的参数B是二项式(t+(1-t))^n = (1)^n的展开公式. 划重点了: 系数是二项式的展开. 后面的很多的贝塞尔曲线的性质都可以用这个来解释
贝塞尔曲线的导数
变化一下贝塞尔公式:
和上文中的公式相同, 但是有一些字母的替换, 表达习惯不同
控制点是独立的, 因此求导是直接对u就行求导, 就是仅仅对参数项B进行求导.
定义: Q0=n*(P1-P0), Q0=n*(P2-P1), Q0=n*(P3-P2),...Qn-1=n*(Pn-Pn-1), . 如果我们把Q当做一组新的控制点, 那么原贝塞尔的导数可以写成如下:
导数还是贝塞尔曲线, 只不过是控制点是原来控制点的组合而已.
This derivative curve is usually referred to as the hodograph of the original Bézier curve. 贝塞尔的导数可以理解为原贝塞尔的速度曲线.(瞎翻译的)
七阶贝塞尔曲线和其导数曲线(六阶贝塞尔曲线)
以此类推:
可以得出一个很有趣的结论, 贝塞尔曲线的导数还是贝塞尔曲线.
贝塞尔曲线的性质
1 各项系数之和为1.
这个很好理解,因为是系数是二项式的展开(t+(1-t))^n = (1)^n非负性. 好理解, 二项式的展开啊
2 对称性
第i项系数和倒数第i项系数相同, 从二项式的展开来思考,这个也好理解
3 递归性
递归性指其系数满足下式:
这个好理解, 因为我们就是从递归来理解贝塞尔曲线的
4 凸包性质
贝塞尔曲线始终会在包含了所有控制点的最小凸多边形中, 不是按照控制点的顺序围成的最小多边形. 这点大家一定注意. 这一点的是很关键的,也就是说可以通过控制点的凸包来限制规划曲线的范围,在路径规划是很需要的一个性质.
5端点性质
第一个控制点和最后一个控制点,恰好是曲线的起始点和终点.这一点可以套用二项式展开来理解,t=1或者0的时候,相乘二项式的系数,出了初始点或者末尾点,其余的都是0.
6一阶导数性质
假设上图中贝塞尔的t是由左到右从0到1增加的,那么贝塞尔曲线在t=0时的导数是和P0P1的斜率(导数)是相同,t=1时的导数是和P3P4的斜率(导数)是相同
这一点的性质可以用在贝塞尔曲线的拼接,只要保证三点一线中的中间点是两段贝塞尔曲线的连接点,就可以保证两端贝塞尔曲线的导数连续连续.导数连续是曲线的G1连续. 如果保证C1连续呢?
如果不懂G1和C1连续的意义, 先看我之前写的这篇文章.
FrancisZhao:曲线篇: 曲线的几何连续和参数连续zhuanlan.zhihu.com
如果保证两段贝塞尔拼接曲线的曲率连续呢?控制点要怎么排布呢?
这就非常的复杂了, 建议直接参考下文:
Bezier曲线的拼接及其连续性 - 图文 - 百度文库wenku.baidu.com
转载请注明出处:http://blog.csdn.net/tianhai110
Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线。 曲线定义:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。 1962年,法国数学家Pierre Bézier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名,称为贝塞尔曲线。