我看了不少插值的方法,有的方法講得莫名其妙,一個程序,一些系數,為什么這個系數是1,而不是0.5從來不講,讓人很懷疑其可用性。
后來做刀光的時候,采集的刀光的點不夠圓滑,需要用到插值——想想自己的高數還沒有完全忘光,干脆自己推導一個得了。
首先我們要明白什么叫做光滑的曲線,可以這么認為,這個曲線是一個運動物體,在時間[0,1]內運動的軌跡。而要求的光滑的曲線,就是要求物體運動 過程中沒有速度的突變。且要求不同的曲線段之間,速度也不能有突變。據此,我們可以大約知道插值一段曲線,需要指導曲線其實點的位置和速度,結束點的位置 和速度。由于有四個已知變量,顯然,用一個四次方程來描述這個曲線是再合適不過了。
方程如下:
f(t) = a * t ^ 3 + b * t ^ 2 + c * t + d [0 <= t <= 1]
對f(t)求導,得到速度方程:
f'(t) = 3 * a * t ^ 2 + 2 * b * t + c [0 <= t <= 1]
所以
f(0) = d = x0(起始點位置)
f(1) = a + b + c + d = x1(結束點位置)
f'(0) = c = y0(起始點速度)
f'(1) = 3 * a + 2 * b + c = y1(結束點速度)
聯合上面四個式子可解得
a = 2 * x0 - 2 * x1 + y0 + y1
b = 3 * x1 - 3 * x0 - y1 - 2 * y0
c = y0
d = x0
再利用
f(t) = a * t ^ 3 + b * t ^ 2 + c * t + d [0 <= t <= 1]
就可以插值這斷曲線了
當然,事情還沒有完,通常情況下,我們得到的數據只有各個采樣點的位置,沒有速度。這個時候,速度怎么辦?我的解決辦法是,在有3個采樣點的時候(p0,p1,p2),計算出p1采樣點的速度,另外,再假設采樣時間間隔是均勻的,因此:
v1 = (p2 - p0) * 0.5
在有N個采樣的時候,特殊處理起始點和結束點的速度
v0 = p1 - p0;
vn = pn - p(n-1)
這樣得到的曲線完全滿足平滑的要求,缺點是,曲線開始插值的時候要延遲一個采樣點的時間,有的時候,v0 速度很快,因此,會出現一條有縫隙刀光。針對當前項目,我在第一次采樣的時候,將時間稍微往后加了0.001秒,按照當前的運動趨勢多采樣了一次,從而消 除了這個縫隙。因為預測的運動時間很短,即使預測錯誤,也不影響刀光的外觀。