2011-05-29 170 views
2

我需要編寫一個程序來生成並顯示插值每組數據點(我有一個包含數據點的txt文件)的分段二次貝塞爾曲線。曲線應該具有連續的切線方向,每個數據點處的切線方向是兩個相鄰絃線方向的凸組合。在分段二次貝塞爾曲線上找到控制點

0.1 0, 
0 0, 
0 5, 
0.25 5, 
0.25 0, 
5 0, 
5 5, 
10 5, 
10 0, 
9.5 0 

以上是我有的數據點,有誰知道我可以用什麼公式計算控制點?

回答

0

您將需要使用三次Bezier來很好地處理多個斜率變化,例如發生在您的數據集中。對於二次貝塞爾曲線,數據點之間只有一個控制點,因此每條曲線段都在連接線段的一側。難以解釋,所以這裏是你的數據(黑點)和二次控制點(紅色)和曲線(藍色)的快速簡圖。 (假裝曲線是平滑的!)

enter image description here

查找到Cubic Hermite curves一個通用的解決方案。

+0

感謝您的回覆,以及不錯的繪畫:))) – 2011-05-29 15:02:36

0

從這裏:http://blog.mackerron.com/2011/01/01/javascript-cubic-splines/

要產生這樣的插補曲線:

natural curve monotonic curve

您可以使用此咖啡腳本類(編譯成JavaScript)

class MonotonicCubicSpline 

# by George MacKerron, mackerron.com 

# adapted from: 
# http://sourceforge.net/mailarchive/forum.php?thread_name= 
# EC90C5C6-C982-4F49-8D46-A64F270C5247%40gmail.com&forum_name=matplotlib-users 
# (easier to read at http://old.nabble.com/%22Piecewise-Cubic-Hermite-Interpolating- 
# Polynomial%22-in-python-td25204843.html) 

# with help from: 
# F N Fritsch & R E Carlson (1980) 'Monotone Piecewise Cubic Interpolation', 
# SIAM Journal of Numerical Analysis 17(2), 238 - 246. 
# http://en.wikipedia.org/wiki/Monotone_cubic_interpolation 
# http://en.wikipedia.org/wiki/Cubic_Hermite_spline 

constructor: (x, y) -> 
    n = x.length 
    delta = []; m = []; alpha = []; beta = []; dist = []; tau = [] 
    for i in [0...(n - 1)] 
    delta[i] = (y[i + 1] - y[i])/(x[i + 1] - x[i]) 
    m[i] = (delta[i - 1] + delta[i])/2 if i > 0 
    m[0] = delta[0] 
    m[n - 1] = delta[n - 2] 
    to_fix = [] 
    for i in [0...(n - 1)] 
    to_fix.push(i) if delta[i] == 0 
    for i in to_fix 
    m[i] = m[i + 1] = 0 
    for i in [0...(n - 1)] 
    alpha[i] = m[i]/delta[i] 
    beta[i] = m[i + 1]/delta[i] 
    dist[i] = Math.pow(alpha[i], 2) + Math.pow(beta[i], 2) 
    tau[i] = 3/Math.sqrt(dist[i]) 
    to_fix = [] 
    for i in [0...(n - 1)] 
    to_fix.push(i) if dist[i] > 9 
    for i in to_fix 
    m[i]  = tau[i] * alpha[i] * delta[i] 
    m[i + 1] = tau[i] * beta[i] * delta[i] 
    @x = x[0...n] # copy 
    @y = y[0...n] # copy 
    @m = m 

interpolate: (x) -> 
    for i in [(@x.length - 2)..0] 
    break if @x[i] <= x 
    h = @x[i + 1] - @x[i] 
    t = (x - @x[i])/h 
    t2 = Math.pow(t, 2) 
    t3 = Math.pow(t, 3) 
    h00 = 2 * t3 - 3 * t2 + 1 
    h10 =  t3 - 2 * t2 + t 
    h01 = -2 * t3 + 3 * t2 
    h11 =  t3 - t2 
    y = h00 * @y[i] + 
     h10 * h * @m[i] + 
     h01 * @y[i + 1] + 
     h11 * h * @m[i + 1] 
    y