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


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