You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
2.9 KiB
101 lines
2.9 KiB
import utils.b_spline.BaseFunction as bf
|
|
import numpy as np
|
|
|
|
|
|
def curve_interpolation(D, N, k, param, knot):
|
|
'''
|
|
Given a set of N data points, D0, D1, ..., Dn and a degree k,
|
|
find a B-spline curve of degree k defined by N control points
|
|
that passes all data points in the given order.
|
|
:param D: data points (N x 2)
|
|
:param N: the number of data points
|
|
:param k: degree
|
|
:param param: parameters
|
|
:param knot: knot vector
|
|
:return: control points (N x 2)
|
|
'''
|
|
Nik = np.zeros((N, N))
|
|
|
|
for i in range(N):
|
|
for j in range(N):
|
|
Nik[i][j] = bf.BaseFunction(j, k+1, param[i], knot)
|
|
Nik[N-1][N-1] = 1
|
|
print(Nik)
|
|
Nik_inv = np.linalg.inv(Nik)
|
|
print(Nik_inv)
|
|
P = []
|
|
for i in range(len(D)):
|
|
P.append(np.dot(Nik_inv, D[i]).tolist())
|
|
print(P)
|
|
return P
|
|
|
|
|
|
def curve_approximation(D, N, H, k, param, knot):
|
|
'''
|
|
Given a set of N data points, D0, D1, ..., Dn, a degree k,
|
|
and a number H, where N > H > k >= 1, find a B-spline curve
|
|
of degree k defined by H control points that satisfies the
|
|
following conditions:
|
|
1. this curve contains the first and last data points;
|
|
2. this curve approximates the data polygon in the sense
|
|
of least square;
|
|
:param D: data points (N x 2)
|
|
:param H: the number of control points
|
|
:param k: degree
|
|
:param param: parameters
|
|
:param knot: knot vector
|
|
:return: control points (H x 2)
|
|
'''
|
|
P = []
|
|
if H >= N or H <= k:
|
|
print('Parameter H is out of range')
|
|
return P
|
|
|
|
for idx in range(len(D)):
|
|
P_ = np.zeros((1, H))
|
|
P_[0][0] = D[idx][0]
|
|
P_[0][H-1] = D[idx][N-1]
|
|
Qk = np.zeros((N - 2, 1))
|
|
Nik = np.zeros((N, H))
|
|
for i in range(N):
|
|
for j in range(H):
|
|
Nik[i][j] = bf.BaseFunction(j, k+1, param[i], knot)
|
|
# print(Nik)
|
|
|
|
for j in range(1, N - 1):
|
|
Qk[j - 1] = D[idx][j] - Nik[j][0] * P_[0][0] - Nik[j][H - 1] * P_[0][H - 1]
|
|
|
|
N_part = Nik[1: N - 1, 1: H - 1]
|
|
# print(N_part)
|
|
Q = np.dot(N_part.transpose(), Qk)
|
|
# print(Q)
|
|
M = np.dot(np.transpose(N_part), N_part)
|
|
P_[0][1:H - 1] = np.dot(np.linalg.inv(M), Q).transpose()
|
|
P.append(P_.tolist()[0])
|
|
|
|
return P
|
|
|
|
|
|
def curve(P, N, k, param, knot):
|
|
'''
|
|
Calculate B-spline curve.
|
|
:param P: Control points
|
|
:param N: the number of control points
|
|
:param k: degree
|
|
:param param: parameters
|
|
:param knot: knot vector
|
|
:return: data point on the b-spline curve
|
|
'''
|
|
Nik = np.zeros((len(param), N))
|
|
|
|
for i in range(len(param)):
|
|
for j in range(N):
|
|
Nik[i][j] = bf.BaseFunction(j, k+1, param[i], knot)
|
|
Nik[len(param)-1][N - 1] = 1
|
|
# print(Nik)
|
|
# D = np.dot(Nik, P)
|
|
D = []
|
|
for i in range(len(P)):
|
|
D.append(np.dot(Nik, P[i]).tolist())
|
|
# print(D)
|
|
return D
|