Path相關方法講解(二),path相關方法講解

來源:互聯網
上載者:User

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;





著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.