Graphics2D API:Path之貝塞爾曲線

在之前的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
貝塞爾曲線繪制圓

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市恩沛,隨后出現(xiàn)的幾起案子在扰,更是在濱河造成了極大的恐慌,老刑警劉巖雷客,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芒珠,死亡現(xiàn)場離奇詭異,居然都是意外死亡搅裙,警方通過查閱死者的電腦和手機(jī)皱卓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來部逮,“玉大人娜汁,你說我怎么就攤上這事⌒峙螅” “怎么了掐禁?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長颅和。 經(jīng)常有香客問我傅事,道長,這世上最難降的妖魔是什么峡扩? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任蹭越,我火速辦了婚禮,結(jié)果婚禮上教届,老公的妹妹穿的比我還像新娘般又。我一直安慰自己,他們只是感情好巍佑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布茴迁。 她就那樣靜靜地躺著,像睡著了一般萤衰。 火紅的嫁衣襯著肌膚如雪堕义。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天脆栋,我揣著相機(jī)與錄音倦卖,去河邊找鬼。 笑死椿争,一個(gè)胖子當(dāng)著我的面吹牛怕膛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播秦踪,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼褐捻,長吁一口氣:“原來是場噩夢啊……” “哼掸茅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起柠逞,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤昧狮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后板壮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逗鸣,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年绰精,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了撒璧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡笨使,死狀恐怖卿樱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情阱表,我是刑警寧澤殿如,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布贡珊,位于F島的核電站最爬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏门岔。R本人自食惡果不足惜爱致,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望寒随。 院中可真熱鬧糠悯,春花似錦、人聲如沸妻往。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讯泣。三九已至纫普,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間好渠,已是汗流浹背昨稼。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拳锚,地道東北人假栓。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像霍掺,于是被迫代替她去往敵國和親匾荆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拌蜘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容