判斷點在封閉圖形的內外的方法
方法 |
判定條件 |
解釋 |
奇偶規則 |
奇數表示在圖形內,偶數表示在圖形外 |
從任意位置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”影響的是顯示效果,而“數據結構”影響的是重建速度。