Path相關方法講解(二),path相關方法講解
今天咱們一起來看看Path裡 XXXTo 相關的一類方法;
通過 Path相關方法講解(一),我們已經對 Path 有了一個很基本的瞭解,我們已經知道Path代表一條路徑,而這條路徑具體表現成什麼樣,我們自己可以自由發揮,隨意構建,今天我們就一起來看看android給我們提供了哪些方法來構建路徑;
一、moveTo(float,float)
用於移動路徑的起始點到Point(x,y),咱們都知道對於android系統來說,螢幕的左上方的座標是 (0,0) , 我們在做一些操作的時候預設基準點也是 (0,0),比如調用canvas.rotate(float degrees) 將Canvas (畫布) 旋轉對應的角度,當然 ,Canvas還有另外一個方法rotate(float degrees,float px, float py),其中所做的事情就是通過 translate(px, py) 改變了canvas.rotate() 的基準點,Path 的moveTo 方法可以與此進行一個類比,就是為了改變 Path 的起始點;
我們一起看下小例子:
private void init() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStyle(Style.STROKE); mPaint.setStrokeWidth(PATH_WIDTH); mPaint.setColor(Color.RED); mPath = new Path(); mPath.lineTo(150, 150); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.WHITE); canvas.drawPath(mPath, mPaint); }此時螢幕上展現的效果即從螢幕上畫了一條直線,從 (0,0) 到 (150,150),效果如下:
我們在
mPath.lineTo(150, 150)
前面加上一句 mPath.moveTo(50,50),看看效果:
此時線的起始點移動到了(50,50) ,即從 (50,50) 連到了 (150,150) ;
二、rMoveTo(float,float)
前面加上 r 的 XXXTo方法,只需要理解它的意義即可明白, r 即 relative ,會相對於前一個點往後計量;
我們對前面的例子稍作改動:
<span style="white-space:pre"></span>mPath = new Path();<span style="white-space:pre"></span>mPath.moveTo(50, 50); mPath.lineTo(150, 150); // 相對前面的點 x 往後移動 100 個像素,y 往下移動 100 個像素 mPath.rMoveTo(100, 100); mPath.lineTo(400, 400);
按照我們的預期,此時應該是畫兩條線分別從 (0,0) - (150,150) 和 (250,250) - (400,400) , 當調 rMoveTo(float,float) 時前一個點為 (0,0) ,那麼效果等同於 moveTo(float,float);
三、lineTo(float x,float y)
上面的例子也已經能看出該方法的作用了,即從上一個點以直線方式串連到參數裡的 (x,y)
四、rLineTo(float x,float y) , 即以當前點作為基準點,以直線的形式串連到 (currentX + x , currentY + y)
五、arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo)
該方法是添加一段弧線到path中,我們先來看看各參數的意義:
第一個參數:RectF oval 代表弧線所在橢圓所佔的矩形地區;
這句話看起來還有點繞,細細一想,一段弧線必然是附屬於一個橢圓或正圓,只不過只是顯示了這個橢圓或正圓的一部分,而這個橢圓或正圓又必然剛好被包含於一個矩形地區,該參數就是這個矩形地區:
第二個參數:float startAngle 代表弧線的起始角度;
第三個參數:float sweepAngle 代表弧線所划過的角度;
第四個參數:boolean forceMoveTo 如果為true ,則效果相當於建立一條路徑並 moveTo 到弧線起始點,然後添加弧線,可能有人會問,這個方法有何用,待會一起看例子;
大家需要注意的是 0 度所在點並不是正上方,而是時鐘上三點鐘所在的位置;
接下來我們添加一段弧線到剛才的 path 裡:
mPath = new Path(); mPath.moveTo(50, 50); mPath.lineTo(150, 150); // 相對前面的點 x 往後移動 100 個像素,y 往下移動 100 個像素 mPath.rMoveTo(100, 100); mPath.lineTo(400, 400); mRectF = new RectF(0, 400, 800, 800); mPath.arcTo(mRectF, 0, 90); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.WHITE); canvas.drawPath(mPath, mPaint); canvas.drawRect(mRectF, mPaint); }此時的效果如下:
我們可以看到此時多了一條線(處理成藍色),由於弧線的起始點和 path 的最後一個點不是同一個點,path 會直接lineTo到弧線的起始點,然後arcTo ,而對於我們來說,我們不想要這一條多餘的線,該怎麼辦呢?arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo) 方法就派上用場了:
改使用
mPath.arcTo(mRectF, 0, 90, true);
此時效果為:
六、close()
顧名思義,即關閉當前路徑,還是使用前面的例子:
<span style="white-space:pre"></span>mPath.rMoveTo(100, 100); mPath.lineTo(400, 400); mRectF = new RectF(0, 400, 800, 800); mPath.arcTo(mRectF, 0, 90); mPath.close();
大家可以先想象一下現在的結果應該是什麼:
我們再看看改為
mPath.arcTo(mRectF, 0, 90, true);
之後的效果:
此時對於close的結果是否有結論了呢?close相當於lineTo到最後一次moveTo的終點,為了便於理解,可以把每次調用moveTo 之後的Path 當作一條獨立的路徑;
七、path 裡與貝茲路徑相關的方法:
我們先簡單的瞭解下貝茲路徑:
貝茲路徑(Bézier curve),又稱貝茲曲線或貝濟埃曲線,是應用於二維圖形應用程式的數學曲線。一般的向量圖形軟體通過它來精確畫出曲線,貝茲曲線由線段與節點群組成,節點是可拖動的支點,線段像可伸縮的皮筋,我們在繪圖工具上看到的鋼筆工具就是來做這種向量曲線的。貝茲路徑是電腦圖形學中相當重要的參數曲線,在一些比較成熟的位元影像軟體中也有貝茲路徑工具,如PhotoShop等。
在Flash4中還沒有完整的曲線工具,而在Flash5裡面已經提供出貝茲路徑工具。
貝茲路徑的一般參數方程為:
二次方貝茲曲線(有一個控制點)方程為:
三次貝茲路徑(有兩個控制點)方程為:
android 只對低階貝茲路徑進行了封裝,二次方貝茲曲線對應 quadTo(float x1,float y1,float x2,float y2) , 三次貝茲路徑對應 cubicTo(float x1,float y1,float x2, float y2, float x3,float y3)
(1)、quadTo(float x1, float y1, float x2, float y2)
x1、y1 代表控制點的 x、y,即一個控制點動態圖中的P1,x2、y2 代表目標點的 x、y;
(2)、cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
x1、y1 代表控制點1的 x、y;
x2、y2 代表控制點2的 x、y;
x3、y3 代表目標點的 x、y;
接下來咱們利用上面的兩個方法畫個令人怦然心動的愛心出來:
public class HeartView extends View { private static final int PATH_WIDTH = 2; // 起始點 private static final int[] START_POINT = new int[] { 300, 270 }; // 愛心下端點 private static final int[] BOTTOM_POINT = new int[] { 300, 400 }; // 左側控制點 private static final int[] LEFT_CONTROL_POINT = new int[] { 450, 200 }; // 右側控制點 private static final int[] RIGHT_CONTROL_POINT = new int[] { 150, 200 }; private Paint mPaint; private Path mPath; public HeartView(Context context) { super(context); init(); } private void init() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStyle(Style.STROKE); mPaint.setStrokeWidth(PATH_WIDTH); mPaint.setColor(Color.RED); mPath = new Path(); mPath.moveTo(START_POINT[0], START_POINT[1]); mPath.quadTo(RIGHT_CONTROL_POINT[0], RIGHT_CONTROL_POINT[1], BOTTOM_POINT[0], BOTTOM_POINT[1]); mPath.quadTo(LEFT_CONTROL_POINT[0], LEFT_CONTROL_POINT[1], START_POINT[0], START_POINT[1]); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.WHITE); canvas.drawPath(mPath, mPaint); canvas.drawCircle(RIGHT_CONTROL_POINT[0], RIGHT_CONTROL_POINT[1], 5, mPaint); canvas.drawCircle(LEFT_CONTROL_POINT[0], LEFT_CONTROL_POINT[1], 5, mPaint); }}效果如下:
到這裡,path的基本使用應該沒啥問題了,下一篇我們給這個愛心加上動效,使之更有feel;
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。