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

判斷點(diǎn)在封閉圖形的內(nèi)外的方法

方法 判定條件 解釋
奇偶規(guī)則 奇數(shù)表示在圖形內(nèi),偶數(shù)表示在圖形外 從任意位置p作一條射線, 若與該射線相交的圖形邊的數(shù)目為奇數(shù),則p是圖形內(nèi)部點(diǎn),否則是外部點(diǎn)。
非零環(huán)繞數(shù)規(guī)則 若環(huán)繞數(shù)為0表示在圖形外,非零表示在圖形內(nèi) 首先使圖形的邊變?yōu)槭噶俊h(huán)繞數(shù)初始化為零。再從任意位置p作一條射線。當(dāng)從p點(diǎn)沿射線方向移動時,對在每個方向上穿過射線的邊計(jì)數(shù),每當(dāng)圖形的邊從右到左穿過射線時,環(huán)繞數(shù)加1,從左到右時,環(huán)繞數(shù)減1。處理完圖形的所有相關(guān)邊之后,若環(huán)繞數(shù)為非零,則p為內(nèi)部點(diǎn),否則,p是外部點(diǎn)。

自相交圖形

自相交圖形定義:多邊形在平面內(nèi)除頂點(diǎn)外還有其他公共點(diǎn)。

填充模式

簡介

模式 簡介
EVEN_ODD 奇偶規(guī)則
INVERSE_EVEN_ODD 反奇偶規(guī)則
WINDING 非零環(huán)繞數(shù)規(guī)則
INVERSE_WINDING 反非零環(huán)繞數(shù)規(guī)則

填充模式相關(guān)方法

方法 作用
setFillType 設(shè)置填充規(guī)則
getFillType 獲取當(dāng)前填充規(guī)則
isInverseFillType 判斷是否是反向(INVERSE)規(guī)則
toggleInverseFillType 切換填充規(guī)則(即原有規(guī)則與反向規(guī)則之間相互切換)

奇偶規(guī)則與反奇偶規(guī)則

代碼

mDeafultPaint.setStyle(Paint.Style.FILL);                   // 設(shè)置畫布模式為填充
canvas.translate(mViewWidth / 2, mViewHeight / 2);          // 移動畫布(坐標(biāo)系)
Path path = new Path();                                     // 創(chuàng)建Path
//path.setFillType(Path.FillType.EVEN_ODD);                   // 設(shè)置Path填充模式為 奇偶規(guī)則
path.setFillType(Path.FillType.INVERSE_EVEN_ODD);            // 反奇偶規(guī)則
path.addRect(-200,-200,200,200, Path.Direction.CW);         // 給Path中添加一個矩形

奇偶

反奇偶

非零環(huán)繞數(shù)規(guī)則與反非零環(huán)繞數(shù)規(guī)則

代碼

mDeafultPaint.setStyle(Paint.Style.FILL);                   // 設(shè)置畫布模式為填充
canvas.translate(mViewWidth / 2, mViewHeight / 2);          // 移動畫布(坐標(biāo)系)
Path path = new Path();                                     // 創(chuàng)建Path
//path.setFillType(Path.FillType.EVEN_ODD);                   // 設(shè)置Path填充模式為 奇偶規(guī)則
path.setFillType(Path.FillType.INVERSE_EVEN_ODD);            // 反奇偶規(guī)則
path.addRect(-200,-200,200,200, Path.Direction.CW);         // 給Path中添加一個矩形

同向與非零環(huán)繞數(shù)規(guī)則

反向與非零環(huán)繞數(shù)規(guī)則

同向與反非零環(huán)繞數(shù)規(guī)則

省略,與同向與非零環(huán)繞數(shù)規(guī)則相比,白色->黑色,黑色->白色。

反向與反非零環(huán)繞數(shù)規(guī)則

省略,與反向與非零環(huán)繞數(shù)規(guī)則相比,白色->黑色,黑色->白色。

布爾操作(API19)

五種邏輯

邏輯名稱 類比 說明 示意圖
DIFFERENCE 差集 Path1中減去Path2后剩下的部分
REVERSE_DIFFERENCE 差集 Path2中減去Path1后剩下的部分
INTERSECT 交集 Path1與Path2相交的部分
UNION 并集 包含全部Path1和Path2
XOR 異或 包含Path1與Path2但不包括兩者相交的部分

布爾運(yùn)算方法

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);

計(jì)算邊界

方法

void computeBounds (RectF bounds, boolean exact)
參數(shù) 作用
bounds 測量結(jié)果會放入這個矩形
exact 是否精確測量,目前這一個參數(shù)作用已經(jīng)廢棄,一般寫true即可。

示例

// 移動canvas,mViewWidth與mViewHeight在 onSizeChanged 方法中獲得
canvas.translate(mViewWidth/2,mViewHeight/2);

RectF rect1 = new RectF();              // 存放測量結(jié)果的矩形

Path path = new Path();                 // 創(chuàng)建Path并添加一些內(nèi)容
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設(shè)置 是否保留原有數(shù)據(jù)結(jié)構(gòu)
reset
rewind

FAQ

Q :這個兩個方法應(yīng)該何時選擇呢?
A :選擇權(quán)重: FillType > 數(shù)據(jù)結(jié)構(gòu),因?yàn)椤癋illType”影響的是顯示效果,而“數(shù)據(jù)結(jié)構(gòu)”影響的是重建速度。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容