【转载】Android绘图之Path总结
Path作为Android中一种相对复杂的绘图方式,官方文档中的有些解释并不是很好理解,这里作一个相对全面一些的总结,供日后查看,也分享给大家,共同进步。
1.基本绘图方法
- addArc(RectF oval, float startAngle, float sweepAngle)
绘制弧线,配合Paint的Style可以实现不同的填充效果 - addCircle(float x, float y, float radius, Path.Direction dir)
绘制圆形,其中第dir
参数用来指定绘制时是顺时针还是逆时针 - addOval(RectF oval, Path.Direction dir)
绘制椭圆形,其中oval
作为椭圆的外切矩形区域 - addRect(RectF rect, Path.Direction dir)
绘制矩形 - addRoundRect(RectF rect, float rx, float ry, Path.Direction dir)
绘制圆角矩形 - lineTo(float x, float y)
绘制直线 - addPath(Path src)
添加一个新的Path到当前Path - arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
与addArc
方法相似,但也有区别,下文细述。 - quadTo(float x1, float y1, float x2, float y2)
绘制二次贝塞尔曲线
,其中 (x1,y1)为控制点,(x2,y2)为终点 - cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
绘制三次贝塞尔曲线
,其中(x1,y1),(x2,y2)为控制点,(x3,y3)为终点
2.rXXX方法
上面的lineTo,MoveTo,QuadTo,CubicTo方法都有与之对应的rXXX
方法:
- rLineTo(float dx, float dy)
- rMoveTo(float dx, float dy)
- rQuadTo(float dx1, float dy1, float dx2, float dy2)
- rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
这些方法与之对应的原方法相比,惟一的区别在于:r方法是基于当前绘制开始点的offest,比如当前paint位于 (100,100)处,则使用rLineTo(100,100)
方法绘制出来的直线是从(100,100)到(200,200)的一条直接,由此可见rXXX
方法方便用来基于之前的绘制作连续绘制。
3.Path.op方法
//原型
op(Path path, Path.Op op)
//eg
path1.op(path2,Path.Op.DIFFERENCE);
此方法用于对两个Path对象做相应的运算组合(combine),具体的说是根据不同的op
参数及path2参数来影响path1对象,有点类似于数学上的集合运算。请看下面的例子:
Path path1 = new Path();
path1.addCircle(150, 150, 100, Path.Direction.CW);
Path path2 = new Path();
path2.addCircle(200, 200, 100, Path.Direction.CW);
path1.op(path2, Path.Op.DIFFERENCE);
canvas.drawPath(path1, paint1);
效果如下:
通过不断修改path1.op的第二个参数依次可以得到如下效果:
Path.Op.INTERSECT
效果:
Path.Op.UNION
效果:
Path.Op.REVERSE_DIFFERENCE
效果:
Path.Op.XOR
效果:
总结:
- Path.Op.DIFFERENCE 减去path1中path1与path2都存在的部分;
path1 = (path1 – path1 ∩ path2) - Path.Op.INTERSECT 保留path1与path2共同的部分;
path1 = path1 ∩ path2 - Path.Op.UNION 取path1与path2的并集;
path1 = path1 ∪ path2 - Path.Op.REVERSE_DIFFERENCE 与DIFFERENCE刚好相反;
path1 = path2 – (path1 ∩ path2) - Path.Op.XOR 与INTERSECT刚好相反;
path1 = (path1 ∪ path2) – (path1 ∩ path2)
4.setFillType
设置path的填充模式.网上关于path的FillType的介绍很少,实际上在官方ApiDemos
里就有个很好的例子:
/**
* Created by ghui on 10/25/15.
*/
public class PathFillTypeView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path mPath; public PathFillTypeView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true); mPath = new Path();
mPath.addCircle(40, 40, 45, Path.Direction.CCW);
mPath.addCircle(80, 80, 45, Path.Direction.CCW);
mPath.addCircle(120, 120, 45, Path.Direction.CCW);
} private void showPath(Canvas canvas, int x, int y, Path.FillType ft,
Paint paint) {
canvas.save();
canvas.translate(x, y);
canvas.clipRect(0, 0, 160, 160);
canvas.drawColor(Color.WHITE);
mPath.setFillType(ft);
canvas.drawPath(mPath, paint);
canvas.restore();
} @Override
protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
paint.setColor(Color.RED);
canvas.drawColor(0xFFCCCCCC);
canvas.translate(20, 20);
paint.setAntiAlias(true);
showPath(canvas, 0, 0, Path.FillType.WINDING, paint);
showPath(canvas, 160 * 2, 0, Path.FillType.EVEN_ODD, paint);
showPath(canvas, 0, 160 * 2, Path.FillType.INVERSE_WINDING, paint);
showPath(canvas, 160 * 2, 160 * 2, Path.FillType.INVERSE_EVEN_ODD, paint);
}
}
效果如下:
(上面的例子在官方ApiDemo的基础上做了适当的修改)
总结:
所谓填充指的就是填充内部,setFillType
就是用来界定哪里算内部的算法。在计算机图形学中界定一个点是不是在多边形内部有两种算法:
- 非零环绕数规则(Nonzero-rule)
- 奇偶规则(Even–odd rule)
关于这两种算法这里不作详细介绍。
5.易混淆的方法
1. addArc 与 arcTo
前者指定在某处画一条弧线,仅此而已,不会受当前paint的位置所影响。而arcTo方法有两种形式:
- arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
- arcTo(RectF oval, float startAngle, float sweepAngle)对于第一种形式的方法,若forceMoveTo参数为false,则与第二种形式的方法没区别,绘制成的最终图形会受到落笔点的影响;
若forceMoveTo参数值为true,则绘制效果与addArc
方法没有区别。
//代码1
Path path = new Path();
path.moveTo(100, 100);
path.addArc(200, 200, 400, 400, 0, 150);
canvas.drawPath(path, paint);
代码1效果如下图:
//代码2
Path path = new Path();
path.moveTo(100, 100);
path.arcTo(200, 200, 400, 400, 0, 150, false);
canvas.drawPath(path,paint);
代码2效果如下图:
若将代码2中的arcTo方法的参数修改为true则绘制的效果与代码1相同。
2. reset 与 rewind
reset
清除path上的内容,重置path到 path = new Path()的初始状态。rewind
清除path上的内容,但会保留path上相关的数据结构,以高效的复用。
其它方法
- moveTo(float x,float y)
移动画笔到 (x,y) 处 - offset(float dx, float dy)
平移当前path,在此path上绘制的任何图形都会受到影响 - close()
闭合当前路径 (系统会自动从起点到终点绘制一条直线,使当前路径闭合) - reset()
重置path,但不会重置fill-type
设置 - rewind()
重置path,但会保留内部数据结构 - set(Path src)
设置新的Path到当前对象 - setLastPoint(float x,float y)
设置当前path的终点 - transform(Matrix matrix)
矩阵变换
【转载】Android绘图之Path总结的更多相关文章
- Android为TV端助力 转载:Android绘图Canvas十八般武器之Shader详解及实战篇(上)
前言 Android中绘图离不开的就是Canvas了,Canvas是一个庞大的知识体系,有Java层的,也有jni层深入到Framework.Canvas有许多的知识内容,构建了一个武器库一般,所谓十 ...
- android 绘图之Path与Paint详解
/** * Paint类介绍 * * Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了颜色, * 样式等绘制信息,指定了如何绘制文本和图形,画笔对象有很多设置方法, * 大体上可以分 ...
- Android为TV端助力 转载:Android绘图Canvas十八般武器之Shader详解及实战篇(下)
LinearGradient 线性渐变渲染器 LinearGradient中文翻译过来就是线性渐变的意思.线性渐变通俗来讲就是给起点设置一个颜色值如#faf84d,终点设置一个颜色值如#CC423C, ...
- 论文第5章:Android绘图平台的实现
面向移动设备的矢量绘图平台设计与实现 Design and Implementation of Mobile Device-oriented Vector Drawing Platform 引用本论文 ...
- android 绘图之Canvas,Paint类
Canvas,Paint 1.在android 绘图但中经常要用到Canvas和Paint类,Canvas好比是一张画布,上面已经有你想绘制图画的轮廓了,而Paint就好比是画笔,就要给Canvas进 ...
- Android群英传》读书笔记 (3) 第六章 Android绘图机制与处理技巧 + 第七章 Android动画机制与使用技巧
第六章 Android绘图机制与处理技巧 1.屏幕尺寸信息屏幕大小:屏幕对角线长度,单位“寸”:分辨率:手机屏幕像素点个数,例如720x1280分辨率:PPI(Pixels Per Inch):即DP ...
- 第三章 Android绘图机制与处理技巧
1.屏幕尺寸信息 屏幕大小:屏幕对角线长度,单位“寸”:分辨率:手机屏幕像素点个数,例如720x1280分辨率:PPI(Pixels Per Inch):即DPI(Dots Per Inch),它是对 ...
- Android群英传笔记——第六章:Android绘图机制与处理技巧
Android群英传笔记--第六章:Android绘图机制与处理技巧 一直在情调,时间都是可以自己调节的,不然世界上哪有这么多牛X的人 今天就开始读第六章了,算日子也刚好一个月了,一个月就读一半,这效 ...
- Android绘图机制(二)——自定义View绘制形, 圆形, 三角形, 扇形, 椭圆, 曲线,文字和图片的坐标讲解
Android绘图机制(二)--自定义View绘制形, 圆形, 三角形, 扇形, 椭圆, 曲线,文字和图片的坐标讲解 我们要想画好一些炫酷的View,首先我们得知道怎么去画一些基础的图案,比如矩形,圆 ...
随机推荐
- 控制DIV移动
键盘控制DIV移动 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...
- 没想到Spring Boot居然这么耗内存,有点惊讶
Spring Boot总体来说,搭建还是比较容易的,特别是Spring Cloud全家桶,简称亲民微服务,但在发展趋势中,容器化技术已经成熟,面对巨耗内存的Spring Boot,小公司表示用不起.如 ...
- WebSocket断开原因、心跳机制防止自动断开连接
1.断开原因 WebSocket断开的原因有很多,最好在WebSocket断开时,将错误打印出来. ws.onclose = function (e) { console.log('websocket ...
- axios统一接口管理及优化
之前我写了一篇文章,分享了自己的项目中对于接口管理的方法.总结下来就是:定义接口文件--withAxios导出--调用接口方法.这样实现了接口的统一管理和调用接口的语义化与简单化. 根据在项目的使用, ...
- C lang: The Command line
Ax_command line h Ax_a command line describe The command line is in enviroment for DOS,to user opera ...
- 最近几周,写了个微信好友检测助手App
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/130 微信好友检测助手App 最近几周,写了个微信好友检测 ...
- 分享一个酷炫动态登录页面html
话不多说,如下图: 代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <H ...
- 检测值是否存在(??)(Freemarker的null值处理)
使用形式: unsafe_expr?? 或 (unsafe_expr)?? 这个操作符告诉我们一个值是否存在.基于这种情况, 结果是 true 或 false. 访问非顶层变量的使用规则和默认值操作符 ...
- JMeter系列教程
认识JMeter工具 JMeter常用元件功能介绍 JMeter线程组 JMeter脚本三种录制方法 Jmeter组件介绍及其作用域和执行顺序 JMeter参数化 JMeter集合点 JMeter关联 ...
- 新入手的Mac,该如何设置?
如果您入手了一台Mac.设置Mac的过程直观且易于执行,但是如果您是新手,可能会遇到有一些小麻烦.没关系,本篇文章小编将帮助您设置Mac,让您像专业人士一样迅速运转您的Mac. 设置前提 在开始设置全 ...