概述

贝塞尔曲线于1962,由法国工程师皮埃尔·贝塞尔所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由Paul de Casteljau于1959年运用de Casteljau演算法开发,以稳定数值的方法求出贝兹曲线。
在计算机图形学中贝赛尔曲线的运用也很广泛,Photoshop中的钢笔效果,Flash5的贝塞尔曲线工具,在软件GUI开发中一般也会提供对应的方法来实现贝赛尔曲线。

线性公式

给定点P0、P1,线性贝兹曲线只是一条两点之间的直线。这条线由下式给出:
B(t) = P0 + (P1 - P0) * t = (1 - t) * P0 + t * P1, t ∈ [0, 1]
且其等同于线性插值。

二次方公式

二次方贝兹曲线的路径由给定点P0、P1、P2的函数B(t)追踪:
B(t) = (1 - t)^2 * P0 + 2t * (1 - t) * P1 + t^2 * P2, t ∈ [0,1]
TrueType字型就运用了以贝兹样条组成的二次贝兹曲线。

百度百科 详细资料

Android上实现贝赛尔曲线

在Android实现贝赛尔曲线,要借助android.graphics.Path,其中绘制贝赛尔曲线的方法在Api v1就已经提供了,下面来认识一下吧。

初识Path类

1
2
3
4
5
Path.moveTo(float x, float y) // Path的初始点
Path.lineTo(float x, float y) // 线性公式的贝赛尔曲线, 其实就是直线
Path.quadTo(float x1, float y1, float x2, float y2) // 二次方公式的贝赛尔曲线
Path.cubicTo(float x1, float y1, float x2, float y2, float x3, float y3) // 三次方公式的贝赛尔曲线
...

这是上面是Java层调用的代码,最终调用的是Skia库的一系列方法,Skia是一个C++2D向量图形处理函数库,感兴趣的可以继续深入研究研究。

绘制贝赛尔曲线

BezierView

1
2
3
4
5
6
7
8
9
10
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); mPath.moveTo(100, 100);
mPath.cubicTo(800, 100, 100, 800, 800, 800);
// 一共四个点,(100, 100)和(800, 800)分别为起点和终点,(800, 100)和(100, 800)为操作点 canvas.drawPath(mPath, mPaint);
}

实现一个BezierEvaluator

BezierEvaluator
实现一个三次方贝赛尔曲线Evaluator,已知公式为:
B(t) = P0 * (1-t)^3 + 3 * P1 * t * (1-t)^2 + 3 * P2 * t^2 * (1-t) + P3 * t^3 代码如下:

BezierEvaluator.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class BezierEvaluator implements TypeEvaluator<PointF> {

    private PointF points[];

    public BezierEvaluator(PointF... points) {
if (points.length != 4) {
throw new IllegalArgumentException("只演示三次方贝赛尔曲线");
}
this.points = points;
} @Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
// B(t) = P0 * (1-t)^3 + 3 * P1 * t * (1-t)^2 + 3 * P2 * t^2 * (1-t) + P3 * t^3 float t = fraction;
float one_t = 1.0f - t; PointF P0 = points[0];
PointF P1 = points[1];
PointF P2 = points[2];
PointF P3 = points[3]; float x = (float) (P0.x * Math.pow(one_t, 3) + 3 * P1.x * t * Math.pow(one_t, 2) + 3 * P2.x * Math.pow(t, 2) * one_t + P3.x * Math.pow(t, 3));
float y = (float) (P0.y * Math.pow(one_t, 3) + 3 * P1.y * t * Math.pow(one_t, 2) + 3 * P2.y * Math.pow(t, 2) * one_t + P3.y * Math.pow(t, 3)); PointF pointF = new PointF(x, y); return pointF;
} }

一种ViewPager指示器的实现

Morning Routine 中有个ViewPager的指示器效果,非常炫酷,类似于下图,是怎么实现的呢?其实也用到了贝塞尔曲线。

DropPagerIndicator

先绘制两个圆

1
2
canvas.drawCircle(leftCircleX, mHeight / 2, leftCircleRadius, mPaint);
canvas.drawCircle(rightCircleX, mHeight / 2, rightCircleRadius, mPaint);

再绘制两个圆中间的部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private void drawModeBend(Canvas canvas) {
float middleOffset = (leftCircleX - rightCircleX) / (mPoints.get(1).x - mPoints.get(0).x) * (mHeight / 10); mPath.reset(); mPath.moveTo(rightCircleX, mHeight / 2); mPath.lineTo(rightCircleX, mHeight / 2 - rightCircleRadius); mPath.cubicTo(rightCircleX,
mHeight / 2 - rightCircleRadius, rightCircleX + (leftCircleX - rightCircleX) / 2.0F,
mHeight / 2 + middleOffset, leftCircleX,
mHeight / 2 - leftCircleRadius); mPath.lineTo(leftCircleX, mHeight / 2 + leftCircleRadius); mPath.cubicTo(leftCircleX,
mHeight / 2 + leftCircleRadius, rightCircleX + (leftCircleX - rightCircleX) / 2.0F,
mHeight / 2 - middleOffset, rightCircleX,
mHeight / 2 + rightCircleRadius); mPath.close();
canvas.drawPath(mPath, mPaint);
}

圆和中间颜色不同用来看看
换成一样的,看起来还不错

然后加上Property Animation即可,了解 Property Animation

博客Demo代码:https://github.com/gavinliu/BeautifulOfBezier

结语

贝赛尔曲线能非常方便的绘制光滑的曲线,加以运用可以实现很多复杂的效果,实现的时候多和设计师沟通,设计师使用的PS中的钢笔其实也就是贝赛尔曲线,了解下设计师是如何绘制的,自己用代码来实现思路就很明了。

Android - Animation 贝塞尔曲线之美的更多相关文章

  1. Android中贝塞尔曲线的绘制方法

    贝塞尔曲线,很多人可能不太了解,什么叫做贝塞尔曲线呢?这里先做一下简单介绍:贝塞尔曲线也可以叫做贝济埃曲线或者贝兹曲线,它由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋.一般的矢量图形软件常 ...

  2. OpenGL 实践之贝塞尔曲线绘制

    说到贝塞尔曲线,大家肯定都不陌生,网上有很多关于介绍和理解贝塞尔曲线的优秀文章和动态图. 以下两个是比较经典的动图了. 二阶贝塞尔曲线: 三阶贝塞尔曲线: 由于在工作中经常要和贝塞尔曲线打交道,所以简 ...

  3. Android 利用二次贝塞尔曲线模仿购物车加入物品抛物线动画

    Android 利用二次贝塞尔曲线模仿购物车加入物品抛物线动画 0.首先.先给出一张效果gif图. 1.贝塞尔曲线原理及相关公式參考:http://www.jianshu.com/p/c0d7ad79 ...

  4. Android仿苹果版QQ下拉刷新实现(二) ——贝塞尔曲线开发"鼻涕"下拉粘连效果

    前言 接着上一期Android仿苹果版QQ下拉刷新实现(一) ——打造简单平滑的通用下拉刷新控件 的博客开始,同样,在开始前我们先来看一下目标效果: 下面上一下本章需要实现的效果图: 大家看到这个效果 ...

  5. Android 贝塞尔曲线解析

    相信很多同学都知道"贝塞尔曲线"这个词,我们在很多地方都能经常看到.利用"贝塞尔曲线"可以做出很多好看的UI效果,本篇博客就让我们一起学习"贝塞尔曲线 ...

  6. 从Android动画到贝塞尔曲线

    基础知识: 动画通过连续播放一系列画面,给视觉造成连续变化的图画.很通俗的一种解释.也很好理解.那么我们先来一个案例看看. 动画案例:百度贴吧小熊奔跑 效果: topic.gif 代码: <?x ...

  7. android 利用Path.cubicTo 画 贝塞尔曲线

    Path.cubicTo void android.graphics.Path.cubicTo(float x1, float y1, float x2, float y2, float x3, fl ...

  8. Android 贝塞尔曲线 折线图

    1.贝塞尔曲线:http://baike.baidu.com/view/60154.htm,在这里理解什么是贝塞尔曲线 2.直接上图: 3.100多行代码就可以画出贝塞尔曲线,直接上代码 packag ...

  9. Android 自定义View高级特效,神奇的贝塞尔曲线

    效果图 效果图中我们实现了一个简单的随手指滑动的二阶贝塞尔曲线,还有一个复杂点的,穿越所有已知点的贝塞尔曲线.学会使用贝塞尔曲线后可以实现例如QQ红点滑动删除啦,360动态球啦,bulabulabul ...

随机推荐

  1. Mylyn

    Mylyn(旧称Mylar)是eclipse的一个插件,用于将任务管理和上下文管理无缝集成到Eclipse中.1. 安装 下载相应的Mylyn zip包,解压缩开就是两个文件夹:features和pl ...

  2. .vimrc快捷键设置

    $ cat ~/.vimrc,centos7是在/etc/vimrc文件中配置. nmap <C-_>s :cs find s <C-R>=expand("<c ...

  3. XMPP个人信息展示

    在现阶段的通信服务中.各种标准都有,因此会出现无法实现相互连通,而XMPP(Extensible Message and presence Protocol)协议的出现.实现了整个及时通信服务协议的互 ...

  4. QT 入门 -QApplication QPushButton QDialog Ui类型的手工使用

    QT 1.工具 assistant  帮助文档 qtconfig  QT配置工具 qmake     QT的make与项目文件智能创建工具 uic          UI界面的设计文件的编译工具 mo ...

  5. Android Texting(2)Testing Fundamentals 测试基础篇

    Testing Fundamentals The Android testing framework, an integral part of the development environment, ...

  6. JSP TAG

    Jsp tag 能够灵活的将公共JSP代码模块化,类似<jsp:include page="./include.jsp"></jsp:include>等等. ...

  7. iOSAPP启动时实现加载广告

    现在很多APP在启动的时候都在加载广告,现在也很流行,主要是盈利啊.笔者也做了很多关于广告的事情.现在记录下自己在APP启动的时候,怎么加载广告的. 下面总结下广告加载的三种方式 1.现在很多APP的 ...

  8. 素数环(C - 暴力求解)

    素数环(暴力)(紫书194页) Description   A ring is composed of n (even number) circles as shown in diagram. Put ...

  9. Eclipse使用技巧总结(一)

    一.建立工作空间 如上图所示,可以建立新的工作空间,或者切换工作空间. 二.导入导出工作空间配置 三.设置行号 如图,用鼠标在坐变阴影部分右击弹出菜单,选中Show Line Numbers一项. 四 ...

  10. js中的总结汇总(以后的都收集到这篇)

    点1:js中的比较字符串是否相等,js中是用"=="这个来判断是否相等,这点跟java中不一样,java中是.equals()这种方法. 在之前写的ajax的demo中,因为用了. ...