在之前的Path基本操作中已經(jīng)介紹了Path常用方法掩驱,不過Path中十分重要的貝塞爾曲線沒有介紹.
何為貝賽爾曲線撒轮?貝塞爾曲線有什么用巩掺?
關(guān)于貝賽爾曲線的來歷就不介紹了汹来,有興趣的可自行搜索了解.
我們?cè)诂F(xiàn)實(shí)中畫曲線想怎么畫就怎么畫续膳,但是計(jì)算機(jī)它不知道怎么畫啊改艇,它需要我們告訴它怎么畫,怎么確定一個(gè)曲線軌跡坟岔,貝賽爾曲線的作用基于此目的:
貝塞爾曲線可以通過控制3個(gè)點(diǎn)來確定一條平滑的曲線谒兄,因?yàn)榭刂品奖悖运谟?jì)算機(jī)圖形學(xué)領(lǐng)域占有極其重要的地位.
比較出名的繪圖軟件:Photoshop 社付、illustrator承疲、CorelDraw 等,無一例外都提供了繪制貝塞爾曲線的功能.
貝塞爾曲線又分為:一階貝賽爾曲線鸥咖、二階貝塞爾曲線燕鸽、三階貝塞爾曲線、高階貝賽爾曲線啼辣,一階貝賽爾曲線就是一條線段啊研,Path類中支持二階貝塞爾曲線和三階貝賽爾曲線.
一、簡述貝塞爾曲線原理
1鸥拧、一階貝塞爾曲線
上面這幅圖表示一階貝賽爾曲線的形成過程悲伶,一階貝賽爾曲線就是一條線段,紅線部分就是隨著時(shí)間變化貝塞爾曲線的軌跡.
可以簡單理解為:在起點(diǎn)P0和終點(diǎn)P1形成的線段上住涉,勻速移動(dòng)的點(diǎn)隨著時(shí)間變化形成的軌跡.
2麸锉、二階貝塞爾曲線
一開始已經(jīng)介紹過,貝塞爾曲線可以通過3個(gè)點(diǎn)確定一條平滑的曲線舆声,這3個(gè)點(diǎn)分別是:起點(diǎn)(P0)花沉、終點(diǎn)(P2)、控制點(diǎn)(P1)媳握,起點(diǎn)終點(diǎn)就是貝塞爾曲線開始結(jié)束位置碱屁,控制點(diǎn)用來控制貝塞爾曲線的彎曲程度.
我們截取某個(gè)時(shí)刻的軌跡圖:
這里有三條一階貝塞爾曲線:
P0P1:在這條一階貝塞爾曲線上移動(dòng)的點(diǎn)是B1
P1P2:在這條一階貝塞爾曲線上移動(dòng)的點(diǎn)是B2
B1B2:在動(dòng)態(tài)點(diǎn)B1、B2之間又形成了一條一階貝賽爾曲線蛾找,在這條一階貝賽爾曲線動(dòng)態(tài)移動(dòng)的是點(diǎn)B
B的移動(dòng)軌跡就是這個(gè)二階貝賽爾曲線的軌跡.
每個(gè)時(shí)刻B點(diǎn)軌跡的確定:
一階貝賽爾曲線是一個(gè)勻速移動(dòng)的點(diǎn)形成的軌跡娩脾,在B1和B2移動(dòng)的過程中:
P0B1:P0P1 = P1B2:P1P2 = 比值
B點(diǎn)的確定就是根據(jù)這個(gè)比值,在B1B2上移動(dòng)的點(diǎn)B:
B1B:B1B2 = 這個(gè)比值.
3打毛、三階貝塞爾曲線
這里的起始點(diǎn)是:P0柿赊,終點(diǎn)是:P3,有兩個(gè)控制點(diǎn):P1幻枉,P2.
我們?cè)俅谓厝∧硞€(gè)時(shí)刻的軌跡圖:
首先碰声,這里有3條一階貝塞爾曲線(灰色):
P0P1:在這條一階貝塞爾曲線上勻速移動(dòng)的點(diǎn)是B1
P1P2:在這條一階貝塞爾曲線上勻速移動(dòng)的點(diǎn)是B2
P2P3:在這條一階貝塞爾曲線上勻速移動(dòng)的點(diǎn)是B3
然后,移動(dòng)點(diǎn)B1熬甫、B2胰挑、B3之間再次形成了2條一階貝塞爾曲線(綠色):
B1B2:在這條一階貝塞爾曲線上勻速移動(dòng)的點(diǎn)是Q1
B2B3:在這條一階貝塞爾曲線上勻速移動(dòng)的點(diǎn)是Q2
最后,移動(dòng)點(diǎn)Q1、Q2又形成了一條一階貝賽爾曲線(藍(lán)色)瞻颂,在這條一階貝賽爾曲線動(dòng)態(tài)移動(dòng)的是點(diǎn)B
B的移動(dòng)軌跡就是這個(gè)三階貝賽爾曲線的軌跡.
移動(dòng)點(diǎn)B1豺谈、B2、B3贡这、Q1茬末、Q2、B的確定:
P0B1:P0P1 = P1B2:P1P2 = P2B3:P2P3
= B1Q1:B1B2 = B2Q2:B2B3
= Q1B:Q1Q2
依次類推藕坯,高階貝塞爾曲線不難理解.
4、繪圖軟件中的貝塞爾工具
二噪沙、Path中添加貝塞爾曲線
1炼彪、二階貝塞爾曲線
Path中添加二階貝塞爾曲線的方法有2個(gè):
public void quadTo(float x1, float y1, float x2, float y2)
控制點(diǎn)坐標(biāo):(x1,y1)
終點(diǎn)坐標(biāo):(x2,y2)
public void rQuadTo(float dx1, float dy1, float dx2, float dy2)
控制點(diǎn)坐標(biāo):(x+dx1,y+dy1)
終點(diǎn)坐標(biāo):(x+dx2,y+dy2)
其中(x,y)是起始點(diǎn)坐標(biāo)
默認(rèn)起始點(diǎn)坐標(biāo)(0,0),可以通過Path.moveTo(x,y)指定起始點(diǎn)坐標(biāo)
連續(xù)調(diào)用quadTo()/rQuadTo正歼,前一個(gè)quadTo()/rQuadTo的終點(diǎn)辐马,就是下一個(gè)quadTo()/rQuadTo方法的起始點(diǎn)
測試
private void gogogo(Canvas canvas) {
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
mPaint.setColor(Color.BLUE);
mPaint.setAntiAlias(true);
Path path = new Path();
path.moveTo(200, 200);
path.quadTo(300, 100, 400, 200);//起始點(diǎn)(200,200)、控制點(diǎn)(300,100)局义、結(jié)束點(diǎn)(400,200)
path.quadTo(500, 300, 600, 200);//起始點(diǎn)(400,200)喜爷、控制點(diǎn)(500,300)、結(jié)束點(diǎn)(600,200)
Path path2 = new Path();
path2.moveTo(200, 300);
path2.quadTo(300, 200, 400, 300);//起始點(diǎn)(200,300)萄唇、控制點(diǎn)(300,200)檩帐、結(jié)束點(diǎn)(400,300)
path2.rQuadTo(100, 100, 200, 0);//起始點(diǎn)(400,300)、控制點(diǎn)(400+100,300+100)另萤、結(jié)束點(diǎn)(400+200,300)
Path path3 = new Path();
path3.moveTo(200, 400);
path3.rQuadTo(100, -100, 200, 0);//起始點(diǎn)(200,400)湃密、控制點(diǎn)(200+100,400-100)、結(jié)束點(diǎn)(200+200,400)
path3.rQuadTo(100, 100, 200, 0);//起始點(diǎn)(200+200,400)四敞、控制點(diǎn)(200+200+100,400+100)泛源、結(jié)束點(diǎn)(200+200+200,400)
canvas.drawPath(path, mPaint);
canvas.drawPath(path2, mPaint);
canvas.drawPath(path3, mPaint);
}
繪制流程:
分析:
第一次繪制二階貝塞爾曲線:起始點(diǎn)P0、控制點(diǎn)P1忿危、終點(diǎn)P2
第二次繪制二階貝塞爾曲線:起始點(diǎn)P2达箍、控制點(diǎn)P3、終點(diǎn)P4
2铺厨、三階貝塞爾曲線
Path中添加三階貝塞爾曲線的方法也有2個(gè):
public void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
控制點(diǎn)坐標(biāo):(x1,y1)
控制點(diǎn)坐標(biāo):(x2,y2)
終點(diǎn)坐標(biāo):(x3,y3)
public void rCubicTo(float x1, float y1, float x2, float y2,float x3, float y3)
控制點(diǎn)坐標(biāo):(x+x1,y+y1)
控制點(diǎn)坐標(biāo):(x+x2,y+y2)
終點(diǎn)坐標(biāo):(x+x3,y+y3)
其中(x,y)是起始點(diǎn)坐標(biāo)
默認(rèn)起始點(diǎn)坐標(biāo)(0,0)缎玫,可以通過Path.moveTo(x,y)指定起始點(diǎn)坐標(biāo)
連續(xù)調(diào)用quadTo()/rQuadTo,前一個(gè)quadTo()/rQuadTo的終點(diǎn)解滓,就是下一個(gè)quadTo()/rQuadTo方法的起始點(diǎn)
就比二階多了一個(gè)控制點(diǎn)碘梢,此處就不贅述了.
關(guān)于貝塞爾曲線,其實(shí)最重要的是理解貝塞爾曲線的生成方式伐蒂,也就是第一部分煞躬,然后就是通過一些Demo來實(shí)戰(zhàn)練習(xí).
最后,給出網(wǎng)上一些案例:
花束直播點(diǎn)贊效果
MagicCircle
SpringIndicator
貝塞爾曲線繪制圓