必須要理解掌握的貝塞爾曲線

原文鏈接:https://www.jianshu.com/p/0c9b4b681724

在Android開發和麪試中(尤其是一些中高級崗位面試),面試官可能會問你自定義控件的詳細內容,我們知道自定義控件這一塊涉及到的內容很多,回答的越多越深入,那麼面試的印象會更好。自定義控件涉及的內容比如測量和繪製、事件分發的處理、動畫效果的渲染與實現,當然還有不得不提的貝賽爾曲線(實際上一些面試官自己都不是很理解二階貝塞爾、三階貝塞爾曲線等概念)。

一些朋友看到以歪果仁大佬名字定義的一些計算公式、定理就頭大(比如梅涅勞斯(Menelaus)定理、塞瓦(Ceva)定理等),不得不承認我也是。本着《士兵突擊》不拋棄不放棄的精神,因此就算是在難啃的骨頭我們也要堅持啃下來!所以本篇文章主要介紹的是貝賽爾曲線的基本概念、在Android的應用場景以及一些思考。不考慮篇幅的情況下力求將概念和理解寫的詳細。

貝賽爾曲線的前世今生:

貝塞爾曲線,這個命名規則一眼看上去大概是一個叫貝塞爾的數學家發明的。但,貝塞爾曲線依據的最原始的數學公式,是在1912年在數學界廣爲人知的伯恩斯坦多項式。簡單理解,伯恩斯坦多項式可以用來證明,在[ a, b ] 區間上所有的連續函數都可以用多項式來逼近,並且收斂性很強,也就是一致收斂。再簡單點,就是一個連續函數,你可以將它寫成若干個伯恩斯坦多項式相加的形式,並且,隨着 n→∞,這個多項式將一致收斂到原函數,這個就是伯恩斯坦斯的逼近性質。

時光荏苒歲月如梭,鏡頭切換到了1959年。當時就職於雪鐵龍的法國數學家 Paul de Casteljau 開始對伯恩斯坦多項式進行了圖形化的嘗試,並且提供了一種數值穩定的德卡斯特里奧(de Casteljau) 算法。(多數理論公式是建立在大量且系統的數學建模基礎之上研究的規律性成果)根據這個算法,就可以實現 通過很少的控制點,去生成複雜的平滑曲線,也就是貝塞爾曲線

但貝塞爾曲線的聲名大噪,不得不提到1962年就職於雷諾的法國工程師皮埃爾·貝塞爾(Pierre Bézier),他使用這種方法來輔助汽車的車體工業設計(最早計算機的誕生則是爲了幫助美國海軍繪製彈道圖),並且廣泛宣傳(典型的理論聯繫實際並獲得成功的示例),因此大家稱爲貝塞爾曲線 。

貝賽爾曲線的數學理論:

既然貝賽爾曲線的本質是通過數學計算公式去繪製平滑的曲線,那就可以通過數學工具進行實際求證以及解釋說明。當然對其進行數學求證就沒必要了,因爲這些偉大的數學家們已經做過了,這裏只是解釋說明:

  • 步驟一:在平面內選3個不同線的點並且依次用線段連接。如下所示..

3點連線

  • 步驟二:在AB和BC線段上找出點D和點E,使得 AD/AB = BE/BC

    AD/AB = BE/BC

     

  • 步驟三:連接DE,在DE上尋找點F,F點需要滿足:DF/DE = AD/AB = BE/BC

    DF/DE = AD/AB = BE/BC

     

  • 步驟四:最最重要的!根據DE線段和計算公式找出所有的F點,記住是所有的F點,然後將其這些點連接起來。那,連接規則是什麼?以上圖爲例,第一個連接點是A-F,第二連接點是A-F1(這個F1必須滿足DF1/DE = AD/AB = BE/BC)以此類推,直到最後連接上C點,下面上一個動圖加深理解:

貝塞爾曲線

可能有些朋友還是不理解,那麼這個GIF我截下其中的一張圖說明,如下圖:

示例說明

動圖裏的P0、P1、P2分別代表的是上圖的:P0 == A;P1 == B;P2 == C。那麼這個黑色點,代表的就是F點,綠色線段的2個端點(P0-P1線段上的綠色點,代表是就是D點,P0-P2線段上的綠色點,代表是就是E點)。線段上面點的獲取,必須要滿足等比關係。

關於貝賽爾曲線的基本數學理論大概就是上面的內容。兩個線段根據等比關係找點的貝塞爾曲線,一般也稱爲二階貝塞爾曲線。

貝賽爾曲線的N階拓展(三階貝塞爾與N階貝塞爾曲線)

剛纔說到,上面的貝賽爾曲線一般稱爲二階貝塞爾曲線,既然是二階貝塞爾曲線,那肯定有三階貝塞爾曲線、四階貝賽爾曲線等等。其實三階貝塞爾與四階貝賽爾曲線以及N階貝賽爾曲線曲線的規則都是一樣的,都是先在線段上找點,這個點必須要滿足等比關係,然後依次連接,下面是三階貝賽爾曲線的解釋說明:

  • 步驟一:三階貝賽爾曲線,簡單理解就是在平面內選4個不同線的點並且依次用線段連接(也就是三條線)。如下所示

     

    四點三線

  • 步驟二:同二階貝塞爾曲線一樣首先需要在線段上找對應的點(E、F、G),對應的點必須要符合等比的計算規則,計算規則如下:AE/AB = BF/BC = CG/CD;找到對應的點以後接着依次鏈接EF、FG;接着在EF、FG線段上面繼續找點H、I,對應的點依舊要符合等比的計算規則,也就是 EH/EF = FI/FG;最後連接H、I線段,在HI線段上面繼續找點J、點J的計算規則需要符合:EH/EF = FI/FG = HJ/HI

     

    三階貝賽爾曲線找點

  • 步驟三:重複步驟二的動作,找到所有的J點,依次將J點連接起來,這樣最終完成了三階貝賽爾曲線。

     

    J點依次連線

整一個三階貝賽爾曲線的動作加起來就是下面的一張動圖:

 

三階貝塞爾

那麼四階貝賽爾曲線的實現步驟也是一樣的,平面上先選取5個點(5點4線)、依次選點(滿足等比關係)、依次連接、根據計算規則找到所有的點(逐個連接)。。。。。。

 

四階貝賽爾曲線

貌似都是從二階貝塞爾曲線說起的,那麼一階貝賽爾又是怎麼樣的?一階貝賽爾如圖:

 

一階貝賽爾

 

可以看到一階貝賽爾是一條直線!因此,N階貝賽爾不僅可以畫平滑的曲線也可以畫直線,因此自定義控件畫直線又多了一種可選擇的方式,但是一般用貝賽爾主要是畫曲線,這裏只是提供了一種別的解決思路;另外,在Android屬性動畫,系統爲我們提供了一個PathInterpolator插值器。這個PathInterpolator裏面就有貝塞爾曲線的身影。有興趣的小夥伴也可以去了解一下。

未完待續。。。

如果這篇文章對您有開發or學習上的些許幫助,希望各位看官留下寶貴的star,謝謝。

Ps:著作權歸作者所有,轉載請註明作者, 商業轉載請聯繫作者獲得授權,非商業轉載請註明出處(開頭或結尾請添加轉載出處,添加原文url地址),文章請勿濫用,也希望大家尊重筆者的勞動成果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章