关于贝塞尔曲线的故事
时间:2022-04-22
本文章向大家介绍关于贝塞尔曲线的故事,主要内容包括概述、公式、如何应用?、用手势画光滑的曲线、总结、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
概述
- 在开始本故事的之前,先来介绍下故事的背景。话说几百年前,从天而降一座神山,远远看去像一天光滑的丝带,它的名字叫做:“贝塞尔曲线"。有大法师预言登上这座神山可以发现天地大秘但是前途艰险。
定义
- 摘自百科 贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。 “贝赛尔曲线”是由法国数学家Pierre Bézier所发明,由此为计算机矢量图形学奠定了基础。它的主要意义在于无论是直线或曲线都能在数学上予以描述。
公式
- 由于应用用到主要以二阶贝塞尔曲线为主,贴下二阶的公式: 二次方公式 二次方贝兹曲线的路径由给定点P0、P1、P2的函数B(t):
如何应用?
- 为了前往"贝塞尔曲线山",向那些从前登上神山的老前辈请教;
所需的Android知识
- 画笔(paint),路径(path),画布(canvas)类的api要熟悉
- View绘制的生命周期 简单来看:测量-measure 摆放-layout 绘制-draw
- Android触摸事件 这里需要了解onTouchEvent方法可以捕捉到触屏的事件
用手势画光滑的曲线
- 路途艰险,在这里我碰到了大白虎,史前巨兽猛犸象,海天鲲鹏,经历了生死考验终于登上神山,恍然大悟,天地大秘原来在此。
- 让我们想一想画东西需要什么?答案:一块白板,一只笔。
- 这里的关键是手势与光滑,处理手势的话就是前面讲的重写Android触摸事件,聪明的你一定想到了通过二阶贝塞尔曲线去做到光滑。
- 画一条二阶贝塞尔曲线需要3个点,两个数据点一个控制点,那么手势落下的点--起始点(x1,y1)与不断移动的手的触点是数据点,控制点需要自己创造,那线段的中点是最好计算的,假设第一个手滑动到的点(x2,y2),那么中点就是((x1+x2)/2,(y1+y2)/2)。
- 重写Android触摸事件需要捕捉MOVE类型与DOWN类型的事件,DOWN类型的事件中需要记录起始点的位置,而MOVE类型事件需要缓冲上一次移动的位置。
- 1.声明控制点,曲线,起始点,以及判定滑动的距离
private Paint controlPaint;
private Path mCurrentPath;
private float startPointX;
private float startPointY;
//画贝塞尔曲线的标识--可以自定义值
private float offset = ViewConfiguration.get(getContext()).getScaledTouchSlop();
- 2.初始化画笔与路径
public PaintBeSaiErView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
//建立路径
mCurrentPath = new Path();
//绘制时抗锯齿
controlPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
//设置画笔样式
controlPaint.setStyle(Paint.Style.STROKE);
//设置画笔的粗细
controlPaint.setStrokeWidth(8);
//设置画笔颜色
controlPaint.setColor(Color.RED);
}
- 3.重写onTouchEvent,记录手势起始点与移动位置并绘制贝塞尔曲线,通过
invalidate方法
更新UI视图
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
//为了方便测试,每次下落之前清空路径
mCurrentPath.reset();
float x = event.getX();
float y = event.getY();
startPointX = x;
startPointY = y;
//移动到起始点
mCurrentPath.moveTo(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
float curX= event.getX();
float curY= event.getY();
float preX= startPointX;
float preY= startPointY;
if(Math.abs(preX-curX)>=offset||Math.abs(preX-curY)>=offset) {
mCurrentPath.quadTo((curX + preX) / 2, (curY + preY) / 2, curX, curY);
startPointX = curX;
startPointY = curY;
}
invalidate();
break;
}
return true;
}
- 4.下面对比使用线段画lineTo(curX, curY)与贝塞尔曲线画quadTo(avgX,avgY)的效果 左图为线段画的,右图为贝塞尔曲线画的,看起来更圆润!why?其实,用线段画基本上看是一个折线图,而贝塞尔函数画是一段段曲线
- 当然,贝塞尔曲线的应用十分广泛,上面是简单的例子,后面将讲如何应用模拟翻页。
总结
- 总以为登上神山才是最大的收获,原来一路走来更有收获。
- 去了解一个事物的时候,要善于思考,记忆中越来越深刻的,往往思考的越透彻。
- 2017"百度之星"程序设计大赛 - 复赛1003&&HDU 6146 Pokémon GO【数学,递推,dp】
- 2017"百度之星"程序设计大赛 - 复赛1001&&HDU 6144 Arithmetic of Bomb【java大模拟】
- Java面向对象抽象类实例练习
- 经典JS闭包面试题
- Java面向对象接口的应用实例练习
- 【机器学习笔记之八】使用朴素贝叶斯进行文本的分类
- 【Java学习笔记之二十二】解析接口在Java继承中的用法及实例分析
- 扫一扫二维码就能打开网站,就能添加联系人,就能链接wifi(续)
- Java面向对象抽象类案例分析
- 【Java学习笔记之二十三】instanceof运算符的用法小结
- 基础才是重中之重~多线程的代价~我的内存都被吃了!
- 【Java学习笔记之二十八】深入了解Java8新特性
- 【Java学习笔记之二十四】对Java多态性的一点理解
- 【Java学习笔记之二十六】深入理解Java匿名内部类
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 详解基于Linux的LVM无缝磁盘水平扩容
- CentOS平台实现搭建rsync远程同步服务器的方法
- CentOS 8设置自动更新的完整步骤
- linux 网络编程 socket选项的实现
- Ubuntu16.04安装Jenkins的方法图文详解
- leetcode树之对称二叉树
- linux 上在指定时间段内每隔多少分钟自动执行任务计划crontab
- 详解如何使用Spark和Scala分析Apache访问日志
- Centos 7.4中的远程访问控制的实现方法
- Linux查找特定程序whereis实例详解
- SpringBoot实战(二):SpringMvc接收xml请求
- CentOS环境下安装PHPUnit的方法分析
- Centos下安装Ansible的示例代码
- ubuntu18.04安装搜狗拼音的简易教程
- linux中$符号的基础用法总结