# 固定了B样条基函数defB_curve_uni(V,n):# V存储坐标点,V = [[x], [y]] # n为曲线次数
U = np.linspace(0,1,100)
X = V[0]
Y = V[1]
n =3# 测试只用n=3
coef_matrix =1/6*np.matrix([[1,4,1,0],[-3,0,3,0],[3,-6,3,0],[-1,3,-3,1]])iflen(X)< n+1:return'型值点个数不够'else:# n+1个点绘制一条曲线段,len(x)-n为需要绘制的曲线段数
x =[]
y =[]
fig = plt.figure()
plt.plot(X,Y,marker='o',markerfacecolor='white')for i inrange(len(X)-n):for u in U:
x.append((np.matrix([1,u,np.power(u,2),np.power(u,3)])*coef_matrix*(np.matrix(X[i:i+n+1]).T))[0,0])
y.append((np.matrix([1,u,np.power(u,2),np.power(u,3)])*coef_matrix*(np.matrix(Y[i:i+n+1]).T))[0,0])
plt.plot(x,y)
plt.plot([x[0],x[100],x[200],x[-1]],[y[0],y[100],y[200],y[-1]],'o')
plt.xticks(fontsize=14)
plt.yticks(fontsize=14)
plt.show()
V =[[0,0,2,3,2,1],[1,3,3,2,1,1]]# V = [[0,0,2],[1,3,3]]
B_curve_uni(V,3)
3.B样条曲线绘制(基函数随曲线次数改变)
defN(i,k,T,t):# 曲线N_ikif k ==0:if t<T[i]or t>T[i+1]:return0else:return1else:
result =(t-T[i])/(T[i+k]-T[i])*N(i,k-1,T,t)+(T[i+k+1]-t)/(T[i+k+1]-T[i+1])*N(i+1,k-1,T,t)return result
defmain(n,V,V_num):
T = np.linspace(0,1,n+V_num+1)# T存储节点
t_x = np.linspace(0,1,160)# t_x存储每一个t值
X = V[0]
Y = V[1]
x =[]# 用来存储曲线的x值
y =[]# 用来存储曲线的y值for i inrange(V_num-n):# for循环用作获取第几条曲线段的数值
result = pd.DataFrame(t_x,columns=['t'])for j inrange(n+1):
result1 =[]for t in t_x:
result1.append(N(i+j,n,T,t))
result['N_{0}{1}'.format(i+j,n)]= result1 # 将N_ij存入dataframe# 把Dataframe中 T[i+n]<=t<=T[i+n+1] 的数据取出来 保存为 matrix, 然后用matrix*np.matrix(X[i:i+n+1]).T获取曲线的x值# lambda x: x>T[i+n] and x<T[i+n+1] 很奇怪,用 >= 或 <= 曲线有时会有问题 比如 V = [[0,0,2,3,2,1],[1,3,3,2,1,1]]
Ni_matrix = np.matrix(result[result['t'].apply(lambda x: x>=T[i+n]and x<=T[i+n+1])].iloc[:,1:])# Ni_matrix 是一个 t_ba*j 维矩阵
x = x+((Ni_matrix*np.matrix(X[i:i+n+1]).T).T).tolist()[0]
y = y+((Ni_matrix*np.matrix(Y[i:i+n+1]).T).T).tolist()[0]
fig = plt.figure()
plt.plot(X,Y,marker='o',markerfacecolor='white')
plt.plot(x,y)
plt.show()if __name__ =='__main__':
n =int(input('请输入曲线的次数:'))
V_num =int(input('请输入控制顶点个数:'))
V =[[1,1,1.5,3,3.8,3.2,5,8,8],[0,0,2.6,3,2.2,-0.3,-0.8,2,2]]# 有重复型值点坐标
main(n,V,V_num)