自定義View(九) PathMeasure的使用

PathMeasure就是對(duì)Path進(jìn)行計(jì)算的類。

PathMeasure有兩個(gè)構(gòu)造方法:

方法名 釋義
PathMeasure() 創(chuàng)建一個(gè)空的PathMeasure
PathMeasure(Path path, boolean forceClosed) 創(chuàng)建 PathMeasure 并關(guān)聯(lián)一個(gè)指定的Path(Path需要已經(jīng)創(chuàng)建完成)。

PathMeasure主要方法:

返回值 方法名 釋義
void setPath(Path path, boolean forceClosed) 關(guān)聯(lián)一個(gè)Path
boolean isClosed() 是否閉合
float getLength() 獲取Path的長度
boolean nextContour() 跳轉(zhuǎn)到下一個(gè)輪廓
boolean getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo) 截取片段
boolean getPosTan(float distance, float[] pos, float[] tan) 獲取指定長度的位置坐標(biāo)及該點(diǎn)切線值
boolean getMatrix(float distance, Matrix matrix, int flags) 獲取指定長度的位置坐標(biāo)及該點(diǎn)Matrix

PathMeasure的第二個(gè)構(gòu)造函數(shù)中的path就是要測量的對(duì)象,后邊的forceClosed是設(shè)置要不要閉合計(jì)算。
比如說一個(gè)不必和的path,使用PathMeasure計(jì)算它的長度,如果forceClosed為false,則計(jì)算的就是這條path的真是長度,如果forceClosed為true,那么PathMeasure計(jì)算出來的長度就是真是長度加上首尾。
PathMeasure中forceClosed的設(shè)置不會(huì)對(duì)path產(chǎn)生任何影響。

簡單講一下setPath、 isClosed 和 getLength

setPath 是 PathMeasure 與 Path 關(guān)聯(lián)的重要方法,效果和 構(gòu)造函數(shù) 中兩個(gè)參數(shù)的作用是一樣的。

isClosed 用于判斷 Path 是否閉合,但是如果你在關(guān)聯(lián) Path 的時(shí)候設(shè)置 forceClosed 為 true 的話,這個(gè)方法的返回值則一定為true。

getLength 用于獲取 Path 的總長度,在之前的測試中已經(jīng)用過了。

getSegment

getSegment是用來獲取path中某一段的path對(duì)象

boolean getSegment (float startD, float stopD, Path dst, boolean startWithMoveTo)

getSegment用來獲取path路徑中從startD到stopD的一段,然后將這一段添加在dst中。startWithMoveTo是用來判斷你現(xiàn)在截取的這一段要不要連接dst中之前的路徑。因?yàn)榻厝〉穆窂绞翘砑拥絛st中的,所以dst中之前可能已經(jīng)有路徑了。
如果 startD、stopD 的數(shù)值不在取值范圍 [0, getLength] 內(nèi),或者 startD == stopD 則返回值為 false,不會(huì)改變 dst 內(nèi)容。

 canvas.translate(mWidth / 2, mHeight / 2);
        Path path = new Path();
        path.addRect(-200, -200, 200, 200, Path.Direction.CW);

        Path dst = new Path();

        PathMeasure pathMeasure = new PathMeasure();

        pathMeasure.setPath(path, false);

        pathMeasure.getSegment(200, 600, dst, true);
        //保持當(dāng)前獲取的這段路徑起始點(diǎn)不變
//        pathMeasure.getSegment(800, 900, dst, true);
        //不保持當(dāng)前獲取的這段路徑起始點(diǎn)不變
        pathMeasure.getSegment(800, 900, dst, false);

        canvas.drawPath(dst, paint);
保持當(dāng)前獲取的這段路徑起始點(diǎn)不變
不保持當(dāng)前獲取的這段路徑起始點(diǎn)不變

nextContour

Path可能不是有一條路徑組成的,PathMeasure中的getLength(),getSegment()方法都是作用在一條路徑上的。如果我們想要測量下一條路徑,就可以使用nextContour()方法跳到下一條路徑上,然后在進(jìn)行計(jì)算測量。

canvas.translate(mViewWidth / 2, mViewHeight / 2);      // 平移坐標(biāo)系

Path path = new Path();

path.addRect(-100, -100, 100, 100, Path.Direction.CW);  // 添加小矩形
path.addRect(-200, -200, 200, 200, Path.Direction.CW);  // 添加大矩形

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

PathMeasure measure = new PathMeasure(path, false);     // 將Path與PathMeasure關(guān)聯(lián)

float len1 = measure.getLength();                       // 獲得第一條路徑的長度

measure.nextContour();                                  // 跳轉(zhuǎn)到下一條路徑

float len2 = measure.getLength();                       // 獲得第二條路徑的長度

Log.i("LEN","len1="+len1);                              // 輸出兩條路徑的長度
Log.i("LEN","len2="+len2);

結(jié)果:

com.gcssloop.canvas I/LEN: len1=800.0
com.gcssloop.canvas I/LEN: len2=1600.0mn

getPosTan

這個(gè)方法用于得到路徑上某一長度的坐標(biāo)和該位置正切值。

boolean getPosTan (float distance, float[] pos, float[] tan)

getPosTan方法是將舉例起點(diǎn)distance距離的位置的坐標(biāo)值存入pos中,將這一點(diǎn)的正切值存放到tan中。
tan代表這一點(diǎn)在曲線上的方向,可以用Math.atan2(tan[1], tan[0]) 獲取到正切角的弧度值,弧度值可以轉(zhuǎn)化為角度值。
tan[0]是臨邊長,tan[1]代表對(duì)邊長。
我們此處用 tan 來描述 Path 上某一點(diǎn)的切線方向,主要用了兩個(gè)數(shù)值 tan[0] 和 tan[1] 來描述這個(gè)切線的方向(切線方向與x軸夾角) 。具體講解參考:安卓自定義View進(jìn)階-PathMeasure

getMatrix

這個(gè)方法是用于得到路徑上某一長度的位置以及該位置的正切值的矩陣:

boolean getMatrix (float distance, Matrix matrix, int flags)

這個(gè)方法可以講距起點(diǎn)distance這一位置的坐標(biāo)位置和正切值存入矩陣matrix中,flags有兩個(gè)值:POSITION_MATRIX_FLAG(位置)
ANGENT_MATRIX_FLAG(正切)
可以兩個(gè)一起選擇,中間用|分隔

measure.getMatrix(distance, matrix, PathMeasure.TANGENT_MATRIX_FLAG | PathMeasure.POSITION_MATRIX_FLAG);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容