一文解析 Android 贝塞尔曲线
姓名:唐来宾 学号:17101223417
转载http://mp.weixin.qq.com/s/-jUIIcdnx-BBPgb5AGnbEA
【嵌牛导读】相信很多同学都知道“贝塞尔曲线”这个词,我们在很多地方都能经常看到。利用“贝塞尔曲线”可以做出很多好看的UI效果,本篇博客就让我们一起学习“贝塞尔曲线”。
【嵌牛鼻子】Android 贝塞尔曲线
【嵌牛鼻子】如何画贝塞尔曲线?
【嵌牛正文】
相信很多同学都知道“贝塞尔曲线”这个词,我们在很多地方都能经常看到。利用“贝塞尔曲线”可以做出很多好看的UI效果,本篇博客就让我们一起学习“贝塞尔曲线”。
1
贝塞尔曲线的原理
贝塞尔曲线是用一系列点来控制曲线状态的,这些点简单分为两类:
类型作用
数据点确定曲线的起始和结束位置
控制点确定曲线的弯曲程度
一阶贝塞尔曲线
一阶曲线是没有控制点的,仅有两个数据点(A 和 B),最终效果一个线段。
动态过程可以参照下图(贝塞尔曲线相关的动态演示图片来自维基百科)。
一阶曲线其实就是lineTo方法。
二阶贝塞尔曲线
在平面内任选 3 个不共线的点,依次用线段连接。
在第一条线段上任选一个点 D。计算该点到线段起点的距离 AD,与该线段总长 AB 的比例。
连接这两点 DE。
从新的线段 DE 上再次找出相同比例的点 F,使得 DF:DE = AD:AB = BE:BC。
到这里,我们就确定了贝塞尔曲线上的一个点 F。接下来,请稍微回想一下中学所学的极限知识,让选取的点 D 在第一条线段上从起点 A 移动到终点 B,找出所有的贝塞尔曲线上的点 F。所有的点找出来之后,我们也得到了这条贝塞尔曲线。
动态过程如下:
三阶贝塞尔曲线
控制点个数为 4 时,就是三阶的曲线
步骤都是相同的,只不过我们每确定一个贝塞尔曲线上的点,要进行三轮取点操作。如图,AE:AB = BF:BC = CG:CD = EH:EF = FI:FG = HJ:HI,其中点 J 就是最终得到的贝塞尔曲线上的一个点。
这样我们得到的是一条三次贝塞尔曲线。
动态图如下:
三阶曲线对应的方法是cubicTo
要绘制更复杂的曲线,控制点的增加也仅仅是线性的。这一特点使其不光在工业设计领域大展拳脚,就连数学基础不好的人也可以比较容易地掌握,比如大多数平面美术设计师们。
2
学习贝塞尔曲线函数
一阶曲线是一条线段,非常简单,不再进行介绍,都是path的基本用法。
二阶曲线:
首先,两个数据点是控制贝塞尔曲线开始和结束的位置,而控制点则是控制贝塞尔的弯曲状态
从上面的动态图可以看出,贝塞尔曲线在动态变化过程中有类似于橡皮筋一样的弹性效果,因此在制作一些弹性效果的时候很常用。
代码如下:
三阶曲线:
三阶曲线由两个数据点和两个控制点来控制曲线状态。
三阶曲线相比于二阶曲线可以制作更加复杂的形状,但是对于高阶的曲线,用低阶的曲线组合也可达到相同的效果,就是传说中的降阶。因此我们对贝塞尔曲线的封装方法一般最高只到三阶曲线。
降阶与升阶
类型释义变化
降阶在保持曲线形状与方向不变的情况下,减少控制点数量,即降低曲线阶数方法变得简单,数据点变多,控制点可能减少,灵活性变弱
升阶在保持曲线形状与方向不变的情况下,增加控制点数量,即升高曲线阶数方法更加复杂,数据点不变,控制点增加,灵活性变强
3
贝塞尔曲线实例
一般使用贝塞尔曲线的情况如下:
至于只需要一个静态的曲线图形的情况,用图片岂不是更好,大量的计算会很不划算。
如果是显示SVG矢量图的话,已经有相关的解析工具了(内部依旧运用的有贝塞尔曲线),不需要手动计算。
贝塞尔曲线的主要优点是可以实时控制曲线状态,并可以通过改变控制点的状态实时让曲线进行平滑的状态变化。
4
QQ红点的实现效果
qq的红点去除效果,其实就是用了两条贝塞尔曲线。
基本理论:只要在拖动的时候 去改变辅助点的Y,和固定圆的半径, 就可以出来效果。
创建画笔
绘制动圆和固定圆
获取两个圆之间的距离:
onDraw()方法绘制圆
处理onTouch()方法,让红点随手势动起来
修改onDraw()判断
isOutToRange和isDisappear分别为true和false的情况
5
漂浮的心
漂浮轨迹就是一条三阶贝塞尔曲线,结合属性动画中的估值器进行设置。
首先定义一个属性动画的估值器
之后自定义一个view可以生成爱心,添加透明度,缩放等动画和根据贝塞尔曲线改变其位置的属性动画。
初始化爱心图片和多个插值器等,到时随即选取
入场动画
贝塞尔曲线动画
结合动画添加爱心
6
弹性的圆
还有一个实例,就是特别出名的弹性的圆
将这个圆的动画效果拆解开看的画,可以分为5个状态。
这里写图片描述
这个动画效果的实现就是不同状态之间的转化加上水平位移的实现。
我们需要先了解一下如何用贝塞尔曲线画一个圆,因为我的做法是通过贝塞尔曲线来实现的。
就是所需要的数值c约等于0.551915024494f,具体可以参考这篇文章,http://spencermortensen.com/articles/bezier-circle/,那么这个c的值的作用,就是把图中的1理解为圆的半径,那么对应的另外个值就应该是半径乘以0.551915024494f。
坐标轴也就是Android中的坐标轴了,如果我们打算用贝塞尔曲线来画这么一个圆的话,我们需要知道这个圆的半径,以及图中的M的值,知道这两个值的话就能够知道图中12个点的坐标,知道坐标就能够用Path的cubicTo方法来使用贝塞尔曲线画出圆了。
这样我们就知道如何使用贝塞尔曲线来绘制一个圆了。也就是状态1和状态5我们都会绘制了,接下来看看状态2如何绘制。
状态2其实就是把右边的点向右移动点距离
状态3的实现就是在状态2的基础上修改了个值,一个是M的值加大,让圆看起来跟肥一点,还有就是圈住的那些点向右移动,做到居中。
实现如下:
来自:CSDN-伯努力不努力