Android使用绘图Path总结

Path作为Android中一种相对复杂的绘图方式,官方文档中的有些解释并不是很好理解,这里作一个相对全面一些的总结,供日后查看,也分享给大家,共同进步。

1.基本绘图方法

  1. addArc(RectF oval, float startAngle, float sweepAngle)
    绘制弧线,配合Paint的Style可以实现不同的填充效果
  2. addCircle(float x, float y, float radius, Path.Direction dir)
    绘制圆形,其中第dir参数用来指定绘制时是顺时针还是逆时针
  3. addOval(RectF oval, Path.Direction dir)
    绘制椭圆形,其中 oval作为椭圆的外切矩形区域
  4. addRect(RectF rect, Path.Direction dir)
    绘制矩形
  5. addRoundRect(RectF rect, float rx, float ry, Path.Direction dir)
    绘制圆角矩形
  6. lineTo(float x, float y)
    绘制直线
  7. addPath(Path src)
    添加一个新的Path到当前Path
  8. arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
    addArc方法相似,但也有区别,下文细述。
  9. quadTo(float x1, float y1, float x2, float y2)
    绘制二次贝塞尔曲线,其中 (x1,y1)为控制点,(x2,y2)为终点
  10. 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方法:

  1. rLineTo(float dx, float dy)
  2. rMoveTo(float dx, float dy)
  3. rQuadTo(float dx1, float dy1, float dx2, float dy2)
  4. 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方法

1
2
3
4
//原型
op(Path path, Path.Op op)
//eg
path1.op(path2,Path.Op.DIFFERENCE);

此方法用于对两个Path对象做相应的运算组合(combine),具体的说是根据不同的op参数及path2参数来影响path1对象,有点类似于数学上的集合运算。请看下面的例子:

1
2
3
4
5
6
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效果:

总结:
  1. Path.Op.DIFFERENCE 减去path1中path1与path2都存在的部分;
    path1 = (path1 - path1 ∩ path2)
  2. Path.Op.INTERSECT 保留path1与path2共同的部分;
    path1 = path1 ∩ path2
  3. Path.Op.UNION 取path1与path2的并集;
    path1 = path1 ∪ path2
  4. Path.Op.REVERSE_DIFFERENCE 与DIFFERENCE刚好相反;
    path1 = path2 - (path1 ∩ path2)
  5. Path.Op.XOR 与INTERSECT刚好相反;
    path1 = (path1 ∪ path2) - (path1 ∩ path2)

4.setFillType

设置path的填充模式.网上关于path的FillType的介绍很少,实际上在官方ApiDemos里就有个很好的例子:

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
33
34
35
36
37
38
39
40
41
42
/**
* 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就是用来界定哪里算内部的算法。在计算机图形学中界定一个点是不是在多边形内部有两种算法:

  1. 非零环绕数规则(Nonzero-rule)
  2. 奇偶规则(Even–odd rule)

关于这两种算法这里不作详细介绍,具体可以参考上面的维基链接,或者这篇中文资料(注意看评论区)

5.易混淆的方法

1. addArc 与 arcTo

前者指定在某处画一条弧线,仅此而已,不会受当前paint的位置所影响。而arcTo方法有两种形式:

  1. arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
  2. arcTo(RectF oval, float startAngle, float sweepAngle)

    对于第一种形式的方法,若forceMoveTo参数为false,则与第二种形式的方法没区别,绘制成的最终图形会受到落笔点的影响;
    若forceMoveTo参数值为true,则绘制效果与addArc方法没有区别。

1
2
3
4
5
//代码1
Path path = new Path();
path.moveTo(100, 100);
path.addArc(200, 200, 400, 400, 0, 150);
canvas.drawPath(path, paint);

代码1效果如下图:

1
2
3
4
5
//代码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上相关的数据结构,以高效的复用。
Detail

其它方法

  1. moveTo(float x,float y)
    移动画笔到 (x,y) 处
  2. offset(float dx, float dy)
    平移当前path,在此path上绘制的任何图形都会受到影响
  3. close()
    闭合当前路径 (系统会自动从起点到终点绘制一条直线,使当前路径闭合)
  4. reset()
    重置path,但不会重置fill-type设置
  5. rewind()
    重置path,但会保留内部数据结构
  6. set(Path src)
    设置新的Path到当前对象
  7. setLastPoint(float x,float y)
    设置当前path的终点
  8. transform(Matrix matrix)
    矩阵变换
转自:http://ghui.me/post/2015/11/android-graphics-path/

转载于:https://www.cnblogs.com/android-blogs/p/5702695.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372599.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2017.3.23下午

下午通过对OSPF基本原理进一步的学习,对上午学习的内容进行了复习。 转载于:https://www.cnblogs.com/bgd140206206/p/6606192.html

编写Eclipse插件教程–第1部分

Eclipse是三个最受欢迎的Java开发IDE之一。 其成功的原因之一是其可扩展性。 对于任何知道该怎么做并且已经做到的人来说,编写eclipse插件都可以非常轻松快捷。 不幸的是,第一次在Eclipse中进行操作可能会非常耗时且令人沮丧。 Eclipse框架非常庞大&…

简单Window下 Android Studio的安装

(1)首先安装JDK 下载JDK 本人觉得官方网站下JDK比较慢,可以直接百度JDK,(如果是64位 百度搜索记得64位) 类似于这样的下载 安装可以看下教程,包括环境变量的配置 如何安装JDK (2&…

日期处理一之NSLalendar的使用

一、日期和时间模式 日期和时间格式由日期和时间模式字符串组成,在日期和时间模式字符串中未加引号的A到‘Z’和a到‘z’被解释为模式字母,用来表示日期或时间。字符串元素,文本可以使用单引号(‘’)引起来使用。定义以…

java的使用Pair要导入什么包,第三方jar包的使用

被导入的外部类所在源文件通常要打包成jar包,java中的jar文件装的是 .class 文件。它是一种压缩格式和zip兼容,被称为jar包。JDK提供的许多类,也是以jar包的形式提供的。在用的时候呢,你的文件里有很多个类,把这些类和…

十大最受欢迎的新Eclipse插件

Eclipse Marketplace仍然是发现有趣且相关的Eclipse插件的地方。 通过Eclipse Marketplace客户端,每月成功安装100,000多个基于Eclipse的产品。 我们提供了过去30天 以来所有时间最受欢迎的插件列表。 我认为看看过去12个月中最受欢迎的新插件会很有趣。 以下列出了…

在桌面显示我电脑

打开Windows PowerShell(一个像是命令提示符的东西[蓝底白字],但不是命令提示符),在Windows PowerShell内输入cmd回车,当返回如下信息: Microsoft Windows [版本 6.2.9200](c) 2012 Microsoft Corporation。…

《Java技术》第二次作业计科1501赵健宇

(一)学习总结 1.使用Eclipse关联jdk源代码,查看String类的equals()方法 equals()方法截图 “”比较的是地址。equals方法他同样使用号进行内存地址的比较。但是equals方法重写如果号比较不相等,…

注射php,UPDATE注射(mysqlphp)的两个模式

一.测试环境:OS:Windowsxpsp2php:php4.3.10(mysql4.1.9apache1.3.33二.测试数据库结构:-----start-----数据库:test----------------------------------------------------------------表的结构userinfo--CREATETABLEuserinfo(groudidvarchar(12)NOTNULL…

JUnit的内置Hamcrest Core Matcher支持

在用JUnit和Hamcrest改进assertEquals的文章中,我简要讨论了Hamcrest “ 核心 ”匹配器与JUnit的现代版本“结合”在一起的情况。 在那篇文章中,我特别关注了JUnit的assertThat(T,Matcher)静态方法与Hamcrest核心is()匹…

FormsAuthentication使用指南,实现登录

一般情况下,在我们做访问权限管理的时候,会把用户的正确登录后的基本信息保存在Session中,以后用户每次请求页面或接口数据的时候,拿到Session中存储的用户基本信息,查看比较他有没有登录和能否访问当前页面。Session的…

Java开发高性能网站需要关注的事

转自:http://www.javabloger.com/java-development-concern-those-things/ 近期各家IT媒体举办的业内技术大会让很多网站都在披露自己的技术内幕与同行们分享,大到facebook,百度,小到刚起步的网站。facebook,百度之类的…

mysql到oracle数据迁移,mysql数据迁移到oracle

mysql: utf-8字符集oracle: Al32UTF8步骤:1. 从mysql导出csv格式数据,导出时设置default_character_setgbk,否则会乱码2.上传至linux服务器(oracle服务器),用以下命令将windows的/r/n换成/r:sed -i "s//r//g" file3.将gbk编码转为u…

测试抽象类和模板方法模式

摘自Wikipedia,“模板方法定义了算法的程序框架。 子类可以覆盖一个或多个算法步骤,以允许不同的行为,同时确保仍然遵循总体算法。” 通常,此模式由两个或多个类组成,一个是提供模板方法(非抽象&#xff09…

LoadRunner性能测试结果计数器指标说明

LoadRunner性能测试结果计数器指标说明 转载2015-09-23 09:57:13标签:loadrunner计数器针对性能测试结果分析过程中,面对大量的测试数据,反而感觉无从下手分析。今天我们就Windows操作系统计数器中的个别被监控对象进行简单的说明。 Memory: …

Elasticsearch之需要注意的问题(es和jdk版本)

(1)在使用java代码操作es集群的时候 要保证本地使用的es的版本和集群上es的版本保持一致。 (2)保证集群中每个节点的JDK版本和es基本配置一致 这个很简单,不多说。 (3)es集群中jdk版本不一致 …

oracle视图查询数据慢,8i查询DBA_FREE_SPACE视图极慢的问题

还是那套古老的8.1.7.4,在该系统上检查表空间使用情况的SQL运行缓慢,其SQL如下:SELECT D.TABLESPACE_NAME,SPACE "SUM_SPACE(M)",SPACE - NVL(FREE_SPACE, 0) "USED_SPACE(M)",ROUND((1 - NVL(FREE_SPACE, 0) / SPACE) * 100, 2) &q…

bzoj 4332:JSOI2012 分零食

描述 这里是欢乐的进香河,这里是欢乐的幼儿园。 今天是2月14日,星期二。在这个特殊的日子里,老师带着同学们欢乐地跳着,笑着。校长从幼儿园旁边的小吃店买了大量的零食决定分给同学们。听到这个消息,所有同学都安安静静…

并发–顺序线程和原始线程

我不久前参与了一个项目,该项目的报告流程如下: 用户会要求举报 报告要求将被翻译成较小的部分 每个零件的报告将基于零件/节的类型由报告生成器生成 组成报告的各个部分将重新组合成最终报告,并返回给用户 我的目标是展示如何从错误的实…

借贷期末余额 oracle,应交税费期末余额分别在借贷方表示什么

应交税费是负债类科目,有时期末余额会在借方,有时会在贷方。因此,小伙伴们在实际的账务处理工作中,一定要弄清楚两者的含义。为了帮助大家进行有更进一步的理解,小编再次汇总了应交税费期末余额分别在借贷方表示什么的…