判断点在封闭图形的内外的方法
方法 |
判定条件 |
解释 |
奇偶规则 |
奇数表示在图形内,偶数表示在图形外 |
从任意位置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”影响的是显示效果,而“数据结构”影响的是重建速度。