1. 程式人生 > >關於曲線 規劃 算法 線性 S曲線 貝塞爾曲線

關於曲線 規劃 算法 線性 S曲線 貝塞爾曲線

image 空間 數據結構 ace html soft 思考 同時 wiki

工控領域經常會涉及速度加減速的算法:線性加減速,S曲線加減速(sin函數,拓展其他三角函數曲線), 貝塞爾曲線,等等。

線性加減速: 設定起始速度V0,目標速度V1,加速時間Ta(s,或加速度),這個的任務執行周期為ΔT( ms 級 或者設定定時器,定時時間必須大於任務周期否則還是按任務周期計算輸出)。

int iCounter ;

  iCounter = Ta/(ΔT/1000) ; //計算達到輸出 任務需執行的 周期數。

 for(int i =0; i<iCounter;i++ ) 

  Vout = V0+i*(V1-V0)/iCounter; // Vout 為每個周期 輸出 的 目標 速度。

S曲線加減速: 設定起始速度V0,目標速度V1,加速時間Ta(s,或加速度),這個的任務執行周期為ΔT( ms 級 或者設定定時器,定時時間必須大於任務周期否則還是按任務周期計算輸出)。

  int iCounter ;

  iCounter = Ta/(ΔT/1000) ; //計算達到輸出 任務需執行的 周期數。

  for(int i =0; i<iCounter;i++ ) 

   Vout = V0+(V1-V0)(1+Sin( (pi/iCounter)*i-pi/2 )); // Vout 為每個周期 輸出 的 目標 速度。

貝塞爾曲線:很少或者基本不用貝塞爾曲線來規劃 曲線加減速,但是有必要了解貝塞爾曲線的原理,及其低階曲線的算法(3、4控制點)。

貝塞爾曲線原理:

下面我們就通過例子來了解一下如何用 de Casteljau 算法繪制一條貝塞爾曲線。

在平面內任選 3 個不共線的點,依次用線段連接。技術分享圖片

在第一條線段上任選一個點 D。計算該點到線段起點的距離 AD,與該線段總長 AB 的比例。技術分享圖片

根據上一步得到的比例,從第二條線段上找出對應的點 E,使得 AD:AB= BE:BC技術分享圖片

連接這兩點 DE。技術分享圖片

從新的線段 DE 上再次找出相同比例的點 F,使得 DF:DE= AD:AB= BE:BC技術分享圖片

到這裏,我們就確定了貝塞爾曲線上的一個點 F。接下來,請稍微回想一下中學所學的極限知識,讓選取的點 D 在第一條線段上從起點 A 移動到終點 B,找出所有的貝塞爾曲線上的點 F。所有的點找出來之後,我們也得到了這條貝塞爾曲線。技術分享圖片

如果你實在想象不出這個過程,沒關系,看動畫!技術分享圖片

回過頭來看這條貝塞爾曲線,為了確定曲線上的一個點,需要進行兩輪取點的操作,因此我們稱得到的貝塞爾曲線為二次曲線(這樣記憶很直觀,但曲線的次數其實是由前面提到的伯恩斯坦多項式決定的)。

當控制點個數為 4 時,情況是怎樣的?技術分享圖片

步驟都是相同的,只不過我們每確定一個貝塞爾曲線上的點,要進行三輪取點操作。如圖,AE:AB= BF:BC= CG:CD= EH:EF= FI:FG= HJ:HI,其中點 J 就是最終得到的貝塞爾曲線上的一個點。技術分享圖片

這樣我們得到的是一條三次貝塞爾曲線。技術分享圖片

看過了二次和三次曲線,更高次的貝塞爾曲線大家應該也知道要怎麽畫了吧。那麽比二次曲線更簡單的一次(線性)貝塞爾曲線存在嗎?長什麽樣?根據前面的介紹,只要稍作思考,想必你也能猜出來了。哈!就是一條直線~技術分享圖片

能畫曲線也能畫直線,是不是很厲害?要繪制更復雜的曲線,控制點的增加也僅僅是線性的。這一特點使其不光在工業設計領域大展拳腳,就連數學基礎不好的人也可以比較容易地掌握,比如大多數平面美術設計師們。技術分享圖片

上面介紹的內容並不足以展示貝塞爾曲線的真正威力。推廣到三維空間的貝塞爾曲面,以及更進一步的非均勻有理 B 樣條(NURBS),早已成為當今計算機輔助設計(CAD)的行業標準,不論是我們平常用到的各種產品,還是在電影院看到的精彩大片,都少不了它們的功勞。

2. 思路解析

百度百科上給出的一般參數公式是這樣的: 給定點 P0,P1,P2, ... ,Pn,其貝塞爾曲線公式如下(即貝塞爾曲線上的點 B(t) 可由如下公式計算得到):

技術分享圖片 這裏寫圖片描述

可以看出其公式是由一個格式固定的表達式之和來表示,這個表達式就是關鍵:

技術分享圖片

該表達式可分為四個部分看:

  • 從 i 遞增到 n 的常數部分
  • Pi 坐標部分
  • (1 - t)^(n - i)
  • t^i 可以看出這四部分都與 i 的值相關,此外 t 值的計算方式為:i/(n+1)
如果直接從上面的公式上找規律比較抽象,那就從具體的例子中找規律吧:

設 Bt 為要計算的貝塞爾曲線上的坐標,N 為控制點個數,P0,P1,P2..Pn 為貝塞爾曲線控制點的坐標,當 N 值不同時有如下計算公式: 如 N 為 3 表示貝塞爾曲線的控制點有 3 個點,這時 n 為 2 ,這三個點分別用 P0,P1,P2 表示。

  • N = 3: P = (1-t)^2P0 + 2(1-t)tP1 + t^2*P2
  • N = 4: P = (1-t)^3P0 + 3(1-t)^2tP1 + 3(1-t)t^2P2 + t^3*P3
  • N = 5: P = (1-t)^4P0 + 4(1-t)^3tP1 + 6(1-t)2*t2P2 + 4(1-t)t^3P3 + t^4*P4

將貝塞爾曲線一般參數公式中的表達式用如下方式表示: 設有常數 a,b 和 c,則該表達式可統一表示為如下形式: a * (1 - t)^b * t^c * Pn;

分析當 N 分別為3,4,5 時對應 a,b,c 的值: 如 N = 3 時,公式有三個表達式,第一個表達式為 (1-t)^2*P0,其對應 a,b,c 值分別為:1,2,0

  • N = 3: 1,2,0 2,1,1 1,0,2 a: 1 2 1 b: 2 1 0 c: 0 1 2
  • N = 4: 1,3,0 3,2,1 3,1,2 1,0,3 a: 1 3 3 1 b: 3 2 1 0 c: 0 1 2 3
  • N = 5: 1,4,0 4,3,1 6,2,2 4,1,3 1,0,4 a: 1 4 6 4 1 b: 4 3 2 1 0 c: 0 1 2 3 4

根據上面的分析就可以總結出 a,b,c 對應的取值規則:

  • b: (N - 1) 遞減到 0 (b 為 1-t 的冪)
  • c: 0 遞增到 (N - 1) (c 為 t 的冪)
  • a: 在 N 分別為 1,2,3,4,5 時將其值用如下形式表示:
    N=1:---------1 N=2:--------1 1 N=3:------1 2 1 N=4:-----1 3 3 1 N=5:---1 4 6 4 1 a 值的改變規則為: 楊輝三角

接下來就實現它:先再來一個例子
比如計算控制點坐標分別為:P0(3,8),P1(2,3),P2(2,7),想要返回 10 個在貝塞爾曲線上的點,用 java 可以這樣寫:

float[] p0 = {3, 8}; float[] p1 = {4, 3}; float[] p2 = {2, 7}; float[][] result = new float[10][2]; for (int i = 0; i < 10; i++) { float t = i / 10; result[i][0] = (float) (1 * Math.pow(1 - t, 2) * Math.pow(t, 0) * p0[0] + 2 * Math.pow(1 - t, 1) * Math.pow(t, 1) * p1[0] + 1 * Math.pow(1 - t, 0) * Math.pow(t, 2) * p2[0]); result[i][1] = (float) (1 * Math.pow(1 - t, 2) * Math.pow(t, 0) * p0[1] + 2 * Math.pow(1 - t, 1) * Math.pow(t, 1) * p1[1] + 1 * Math.pow(1 - t, 0) * Math.pow(t, 2) * p2[1]); }

關於曲線 規劃 算法 線性 S曲線 貝塞爾曲線