自定义View(八) Path填充模式和最后的几个方法

这算是Path最后一篇,主要看一下Path的两种填充模式。但是在这之前先把一下理解起来简单的列出来。

rXxx方法

rMoveTo(x,y);
 rLineTo(x,y);
 rQuadTo(controlX,controlY,endX,endY);
 rCubicTo(control1X,control1Y,control2X,controlY,endX,endY);

我们看到上边的方法都是在之前讲的一些方法前面加了r。
加了r的方法用的是相对位置,相对于上一个点的位置;
不加r的方法使用的是绝对位置,也就是使用的是坐标系的位置。

Path path = new Path();

path.moveTo(100,100);
path.lineTo(100,200);

canvas.drawPath(path,mDeafultPaint);
不加r
Path path = new Path();

path.moveTo(100,100);
path.rLineTo(100,200);

canvas.drawPath(path,mDeafultPaint);

加r

我们看到加了r的显示结果是第二个点的位置是相对于第一个位置的,而不是先对于坐标系的。第二个点的坐标应该是(100+100,100+200)r方法中的参数应该是上一个点的偏移量得到的点。

布尔操作

操作就是将两个path进行交集,并集,差集,异或得到新的path

// 对 path1 和 path2 执行布尔运算,运算方式由第二个参数指定,运算结果存入到path1中。
path1.op(path2, Path.Op.DIFFERENCE);

// 对 path1 和 path2 执行布尔运算,运算方式由第三个参数指定,运算结果存入到path3中。
path3.op(path1, path2, Path.Op.DIFFERENCE)
逻辑名称 类比 说明 示意图
DIFFERENCE 差集 Path1中减去Path2后剩下的部分
image
REVERSE_DIFFERENCE 差集 Path2中减去Path1后剩下的部分
image
INTERSECT 交集 Path1Path2相交的部分
image
UNION 并集 包含全部Path1Path2
image
XOR 异或 包含Path1Path2但不包括两者相交的部分
image

根据具体需求具体使用。

计算边界

void computeBounds (RectF bounds, boolean exact)

这个方法是用来测量一个path所占用的空间大小的,得到的结果存储在bounds中。后边一个exact已废弃,默认写true

// 移动canvas,mViewWidth与mViewHeight在 onSizeChanged 方法中获得
canvas.translate(mViewWidth/2,mViewHeight/2);

RectF rect1 = new RectF();              // 存放测量结果的矩形

Path path = new Path();                 // 创建Path并添加一些内容
path.lineTo(100,-50);
path.lineTo(100,50);
path.close();
path.addCircle(-100,0,100, Path.Direction.CW);

path.computeBounds(rect1,true);         // 测量Path

canvas.drawPath(path,mDeafultPaint);    // 绘制Path

mDeafultPaint.setStyle(Paint.Style.STROKE);
mDeafultPaint.setColor(Color.RED);
canvas.drawRect(rect1,mDeafultPaint);   // 绘制边界
path边界计算

重置路径

重置path的方法有resetrewind两种。
FillType填充规则

方法 是否保留FillType设置 是否保留原有数据结构
reset
rewind

选择权重: FillType > 数据结构

下面开始重头戏:填充模式

Path的填充模式

方法 判定条件 解释
奇偶规则 奇数表示在图形内,偶数表示在图形外 从任意位置p作一条射线, 若与该射线相交的图形边的数目为奇数,则p是图形内部点,否则是外部点。
非零环绕数规则 若环绕数为0表示在图形外,非零表示在图形内 首先使图形的边变为矢量。将环绕数初始化为零。再从任意位置p作一条射线。当从p点沿射线方向移动时,对在每个方向上穿过射线的边计数,每当图形的边从右到左穿过射线时,环绕数加1,从左到右时,环绕数减1。处理完图形的所有相关边之后,若环绕数为非零,则p为内部点,否则,p是外部点。

感觉讲了半天搞懂了,用起来也就那一句话。但还是建议去看安卓自定义View进阶-Path之完结篇里边关于两种规则的讲解。
我们通过这两种模式来判断是填充在图形外边还是图形里边。

Android 中的填充模式有四种:

模式 简介
EVEN_ODD 奇偶规则
INVERSE_EVEN_ODD 反奇偶规则
WINDING 非零环绕数规则
INVERSE_WINDING 反非零环绕数规则

Inverse 和含义是“相反,对立”,说明反奇偶规则刚好与奇偶规则相反,例如对于一个矩形而言,使用奇偶规则会填充矩形内部,而使用反奇偶规则会填充矩形外部,这个会在后面示例中代码展示两者对区别。

关于填充的几种方法

方法 作用
setFillType 设置填充规则
getFillType 获取当前填充规则
isInverseFillType 判断是否是反向(INVERSE)规则
toggleInverseFillType 切换填充规则(即原有规则与反向规则之间相互切换)

下边是奇偶和反奇偶规则的例子:

mDeafultPaint.setStyle(Paint.Style.FILL);                   // 设置画布模式为填充

canvas.translate(mViewWidth / 2, mViewHeight / 2);          // 移动画布(坐标系)

Path path = new Path();                                     // 创建Path

//path.setFillType(Path.FillType.EVEN_ODD);                   // 设置Path填充模式为 奇偶规则
path.setFillType(Path.FillType.INVERSE_EVEN_ODD);            // 反奇偶规则

path.addRect(-200,-200,200,200, Path.Direction.CW);         // 给Path中添加一个矩形
奇偶规则

反奇偶规则

使用非零环绕原则进行填充
前边提到的图形历经顺序会对填充有影响,印象就在这里:

mDeafultPaint.setStyle(Paint.Style.FILL);                   // 设置画笔模式为填充

canvas.translate(mViewWidth / 2, mViewHeight / 2);          // 移动画布(坐系)

Path path = new Path();                                     // 创建Path

// 添加小正方形 (通过这两行代码来控制小正方形边的方向,从而演示不同的效果)
// path.addRect(-200, -200, 200, 200, Path.Direction.CW);
path.addRect(-200, -200, 200, 200, Path.Direction.CCW);

// 添加大正方形
path.addRect(-400, -400, 400, 400, Path.Direction.CCW);

path.setFillType(Path.FillType.WINDING);                    // 设置Path填充模式为非零环绕规则

canvas.drawPath(path, mDeafultPaint);                       // 绘制Path
内部矩形顺时针

内部矩形逆时针
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容