這學期同時上了計算機圖形學和計算方法兩門課,學到這部分的時候突然覺得de Casteljau遞推算法特別像牛頓插值,尤其遞推計算步驟很像牛頓差商表。
一開始用伯恩斯坦多項式計算Bezier曲線的時候,由於其多項式的計算十分不利於計算機實現,還會出現數值不穩定的情況
所以后來出現了de Casteljau算法,以下PPT截圖來自北京化工大學李輝老師
實現代碼(六個頂點):
import numpy as np import matplotlib.pyplot as plt #B = (1-t)*P0+t*P1 def one_bezier_curve(a, b, t): return (1-t)*a + t*b #使用de Casteljau算法求解曲線 def n_bezier_curve(x, n, k, t): #當且僅當為一階時,遞歸結束 if n == 1: return one_bezier_curve(x[k], x[k+1], t) else: return (1-t)*n_bezier_curve(x, n-1, k, t) + t*n_bezier_curve(x, n-1, k+1, t) def bezier_curve(x, y, num, b_x, b_y): #n表示階數 n = len(x) - 1 t_step = 1.0 / (num - 1) t = np.arange(0.0, 1+t_step, t_step) for each in t: b_x.append(n_bezier_curve(x, n, 0, each)) b_y.append(n_bezier_curve(y, n, 0, each)) if __name__ == "__main__": x = [int(n) for n in input('x:').split()] y = [int(n) for n in input('y:').split()] plt.plot(x, y) # x = [0, 2, 5, 10, 15, 20] # y = [0, 6, 10, 0, 5, 5] num = 100 b_x = [] b_y = [] bezier_curve(x, y, num, b_x, b_y) plt.plot(b_x, b_y) plt.show()
運行截圖: