★60.自定义控件 ★10.Path之填充模式

2017-06-29  本文已影响0人  iDragonfly

判断点在封闭图形的内外的方法

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

自相交图形

自相交图形定义:多边形在平面内除顶点外还有其他公共点。

填充模式

简介

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

填充模式相关方法

方法 作用
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.setFillType(Path.FillType.EVEN_ODD);                   // 设置Path填充模式为 奇偶规则
path.setFillType(Path.FillType.INVERSE_EVEN_ODD);            // 反奇偶规则
path.addRect(-200,-200,200,200, Path.Direction.CW);         // 给Path中添加一个矩形

同向与非零环绕数规则

反向与非零环绕数规则

同向与反非零环绕数规则

省略,与同向与非零环绕数规则相比,白色->黑色,黑色->白色。

反向与反非零环绕数规则

省略,与反向与非零环绕数规则相比,白色->黑色,黑色->白色。

布尔操作(API19)

五种逻辑

逻辑名称 类比 说明 示意图
DIFFERENCE 差集 Path1中减去Path2后剩下的部分
REVERSE_DIFFERENCE 差集 Path2中减去Path1后剩下的部分
INTERSECT 交集 Path1与Path2相交的部分
UNION 并集 包含全部Path1和Path2
XOR 异或 包含Path1与Path2但不包括两者相交的部分

布尔运算方法

boolean op (Path path, Path.Op op)
boolean op (Path path1, Path path2, Path.Op op)

示例

int x = 80;
int r = 100;

canvas.translate(250,0);

Path path1 = new Path();
Path path2 = new Path();
Path pathOpResult = new Path();

path1.addCircle(-x, 0, r, Path.Direction.CW);
path2.addCircle(x, 0, r, Path.Direction.CW);

pathOpResult.op(path1,path2, Path.Op.DIFFERENCE);
canvas.translate(0, 200);
canvas.drawText("DIFFERENCE", 240,0,mDeafultPaint);
canvas.drawPath(pathOpResult,mDeafultPaint);

pathOpResult.op(path1,path2, Path.Op.REVERSE_DIFFERENCE);
canvas.translate(0, 300);
canvas.drawText("REVERSE_DIFFERENCE", 240,0,mDeafultPaint);
canvas.drawPath(pathOpResult,mDeafultPaint);

pathOpResult.op(path1,path2, Path.Op.INTERSECT);
canvas.translate(0, 300);
canvas.drawText("INTERSECT", 240,0,mDeafultPaint);
canvas.drawPath(pathOpResult,mDeafultPaint);

pathOpResult.op(path1,path2, Path.Op.UNION);
canvas.translate(0, 300);
canvas.drawText("UNION", 240,0,mDeafultPaint);
canvas.drawPath(pathOpResult,mDeafultPaint);

pathOpResult.op(path1,path2, Path.Op.XOR);
canvas.translate(0, 300);
canvas.drawText("XOR", 240,0,mDeafultPaint);
canvas.drawPath(pathOpResult,mDeafultPaint);

计算边界

方法

void computeBounds (RectF bounds, boolean exact)
参数 作用
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

方法

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

FAQ

Q :这个两个方法应该何时选择呢?
A :选择权重: FillType > 数据结构,因为“FillType”影响的是显示效果,而“数据结构”影响的是重建速度。

上一篇 下一篇

猜你喜欢

热点阅读