純Javascript實(shí)現(xiàn)平滑曲線(xiàn)生成
純Javascript實(shí)現(xiàn)平滑曲線(xiàn)生成
前言
平滑曲線(xiàn)生成是一個(gè)很實(shí)用的技術(shù)。
很多時(shí)候,我們都需要通過(guò)繪制一些折線(xiàn),然后讓計(jì)算機(jī)平滑的連接起來(lái),或者是生成一些平滑的面。
先來(lái)看下最終效果(紅色為我們輸入的直線(xiàn),藍(lán)色為擬合過(guò)后的曲線(xiàn)) 首尾可以特殊處理讓圖形看起來(lái)更好)。
實(shí)現(xiàn)思路是利用貝塞爾曲線(xiàn)進(jìn)行擬合。
貝塞爾曲線(xiàn)簡(jiǎn)介
貝塞爾曲線(xiàn)(英語(yǔ):Bézier curve)是計(jì)算機(jī)圖形學(xué)中相當(dāng)重要的參數(shù)曲線(xiàn)。
二次貝塞爾曲線(xiàn)
二次方貝塞爾曲線(xiàn)的路徑由給定點(diǎn)P0、P1、P2的函數(shù)B(t)追蹤:
三次貝塞爾曲線(xiàn)
對(duì)于三次曲線(xiàn),可由線(xiàn)性貝塞爾曲線(xiàn)描述的中介點(diǎn)Q0、Q1、Q2,和由二次曲線(xiàn)描述的點(diǎn)R0、R1所建構(gòu):
貝塞爾曲線(xiàn)計(jì)算函數(shù)
根據(jù)上面的公式我們可以得到計(jì)算函數(shù)。
二階
三階
擬合算法
問(wèn)題在于如何得到控制點(diǎn),我們以比較簡(jiǎn)單的方法:
- 取p1-pt-p2的角平分線(xiàn),c1c2垂直于該條角平分線(xiàn)c2為p2的投影點(diǎn)。
- 取短邊作為c1-pt c2-pt的長(zhǎng)度。
- 對(duì)該長(zhǎng)度進(jìn)行縮放,這個(gè)長(zhǎng)度可以大概理解為曲線(xiàn)的彎曲程度。
ab線(xiàn)段:這里簡(jiǎn)單處理,只使用了二階的曲線(xiàn)生成。
PS:這里可以按照個(gè)人想法處理。
bc線(xiàn)段:使用abc計(jì)算出來(lái)的控制點(diǎn)c2和bcd計(jì)算出來(lái)的控制點(diǎn)c3以此類(lèi)推。