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’被解释为模式字母,用来表示日期或时间。字符串元素,文本可以使用单引号(‘’)引起来使用。定义以…

十大最受欢迎的新Eclipse插件

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

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

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

JUnit的内置Hamcrest Core Matcher支持

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

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

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

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

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

linux夏令时配置文件,Linux夏令时是怎么调整的?

以法国巴黎为例:root121 zoneinfo]# ln -s /usr/share/zoneinfo/Europe/Paris /etc/localtime[root121 zoneinfo]# date2015年 10月 13日 星期二 03:45:09 CEST[root121 zoneinfo]# date -RTue, 13 Oct 2015 03:45:31 0200[root121 zoneinfo]# zdump -v /etc/localt…

Kali Linux渗透基础知识整理(二)漏洞扫描

Kali Linux渗透基础知识整理系列文章回顾 漏洞扫描 网络流量NmapHping3NessuswhatwebDirBusterjoomscanWPScan网络流量 网络流量就是网络上传输的数据量。 TCP协议 TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待…

嵌入式软件设计第09实验报告

学号:140201133 姓名:李宇昕 组别:第3组 实验地点:D19 一、实验目的: 1.熟悉WWW技术中的SSI(Server Side Include)技术。 2.学会使用SSI技术编写代码把当前开发板内…

TeamCity工件:HTTP,Ant,Gradle和Maven

您可以通过几种方式检索TeamCity工件? 我说有很多选择 ! 如果您使用的是Java构建工具,那么可以使用简单的HTTP请求,Ant Ivy,Gradle和Maven下载和使用TeamCity构建配置生成的二进制文件。 怎么样? 继续阅读…

AutoCAD如何方便截图放到Word文档,改成白底黑字

将模型视图切换到布局2即可 比如下图所示的效果 先回到模型视图把所有线条颜色都改成白色,然后添加适当的标注(比如要受力分析,则在CAD中绘制箭头也很方便的),文字说明。然后切换到布局2就OK 可以截图了。 转载于:http…

iOS--支付宝环境集成

1.下载支付宝SDK以及Demo https://doc.open.alipay.com/doc2/detail?treeId54&articleId103419&docType1 2.新建文件夹“AliSDK”,将压缩包内的文件拷贝到该文件夹下,完成后如下图所示: 3.将文件夹拷贝到项目中, 4.执行完…

Java EE 6测试第二部分– Arquillian和ShrinkWrap简介

在Java EE 6测试的第一部分中,我简要介绍了使用Glassfish嵌入式容器的EJB 3.1 Embeddable API,以演示如何启动该容器,如何在项目类路径中查找bean以及运行非常简单的集成测试。 这篇文章重点介绍Arquillian和ShrinkWrap以及为什么它们是用于企…

【腾讯Bugly干货分享】Android内存优化总结实践

本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/2MsEAR9pQfMr1Sfs7cPdWQ 导语 智能手机发展到今天已经有十几个年头,手机的软硬件都已经发…

令人印象深刻的第一个Apache Camel版本

为了准备下周的CamelOne会议,我花了一些时间回顾一下Apache Camel项目的历史。 因此,除其他外,我了解了Apache Camel的第一个正式1.0版本 。 Apache Camel 1.0 – 5年前 我看的越多,这个版本的事实给我留下了深刻的印象。 现在您…

为什么在2012/2013年我将在新的Enterprise Java项目中继续使用Spring *和* Java EE

自从我担任技术决策职务以来已经过去了一年多,很高兴看到我仍然与之保持着完美的和谐。 几个月前,我在KaiWhner的一个不错的博客中写了一个有关JEE与Spring的答案。 如果观点没有不同,那么讨论的附加值在哪里? 我确实同意Kai的许多…

linux ubuntu 五笔输入法,ubuntu下安装fcitx五笔输入法

安装fcitx输入法sudo add-apt-repository ppa:fcitx-team/stable #添加安装源,apt-get 添加,nightly源也可以sudo apt-get update #更新源,否则无法安装fcit…