def curve_approx_figure(): D_X = [1, 1, 0, -0.5, 1.5, 3, 4, 4.2, 4] D_Y = [0, 1, 2, 3, 4, 3.5, 3, 2.5, 2] D = [D_X, D_Y] D_N = len(D_X) k = 4 # degree H = 8 # the number of control points ''' Step 1. Calculate the parameters ''' p_centripetal = ps.centripetal(D_N, D) ''' Step 2. Calculate the knot vector ''' knot = ps.knot_vector(p_centripetal, k, D_N) ''' Step 3. Calculate the control points ''' P_control = bc.curve_approximation(D, D_N, H, k, p_centripetal, knot) # print(P_control) fig = plt.figure() for i in range(H): plt.scatter(P_control[0][i], P_control[1][i], color='b') for i in range(D_N): plt.scatter(D[0][i], D[1][i], color='r') for i in range(H - 1): tmp_x = [P_control[0][i], P_control[0][i+1]] tmp_y = [P_control[1][i], P_control[1][i+1]] plt.plot(tmp_x, tmp_y, color='b') ''' Step 4. Calculate the points on the b-spline curve ''' piece_num = 80 p_piece = np.linspace(0, 1, piece_num) p_centripetal_new = ps.centripetal(H, P_control) knot_new = ps.knot_vector(p_centripetal_new, k, H) P_piece = bc.curve(P_control, H, k, p_piece, knot_new) # print(P_piece) for i in range(piece_num - 1): tmp_x = [P_piece[0][i], P_piece[0][i+1]] tmp_y = [P_piece[1][i], P_piece[1][i+1]] plt.plot(tmp_x, tmp_y, color='g') plt.show()
def curve_approx_figure(): D_X = [1, 1, 0, -0.5, 1.5, 3, 4, 4.2, 4] D_Y = [0, 1, 2, 3, 4, 3.5, 3, 2.5, 2] D = [D_X, D_Y] D_N = len(D_X) k = 4 H = 8 p_centripetal = ps.centripetal(D_N, D) knot = ps.knot_vector(p_centripetal, k, D_N) P_control = bc.curve_approximation(D, D_N, H, k, p_centripetal, knot) print(P_control) fig = plt.figure() for i in range(H): plt.scatter(P_control[0][i], P_control[1][i], color='b') for i in range(D_N): plt.scatter(D[0][i], D[1][i], color='r') for i in range(H - 1): tmp_x = [P_control[0][i], P_control[0][i + 1]] tmp_y = [P_control[1][i], P_control[1][i + 1]] plt.plot(tmp_x, tmp_y, color='b') # for i in range(D_N-1): # tmp_x = [D[i][0], D[i+1][0]] # tmp_y = [D[i][1], D[i+1][1]] # plt.plot(tmp_x, tmp_y, color='b') piece_num = 80 p_piece = np.linspace(0, 1, piece_num) p_centripetal_new = ps.centripetal(H, P_control) knot_new = ps.knot_vector(p_centripetal_new, k, H) P_piece = bc.curve(P_control, H, k, p_piece, knot_new) # print(P_piece) for i in range(piece_num - 1): tmp_x = [P_piece[0][i], P_piece[0][i + 1]] tmp_y = [P_piece[1][i], P_piece[1][i + 1]] plt.plot(tmp_x, tmp_y, color='g') plt.show()
def curve_inter_figure(): ''' Input: Data points ''' D_X = [1, 1, 0, -0.5, 1, 3, 4, 4.2, 4] D_Y = [0, 1, 2, 3, 1, 1, 3, 2.5, 2] D = [D_X, D_Y] D_N = len(D_X) k = 2 # degree ''' Step 1. Calculate parameters ''' # p_uniform = ps.uniform_spaced(D_N) # print(p_uniform) # p_chord_length = ps.chord_length(D_N, D) # print(p_chord_length) p_centripetal = ps.centripetal(D_N, D) # print(p_centripetal) ''' Step 2. Calculate knot vector ''' knot = ps.knot_vector(p_centripetal, k, D_N) print(knot) ''' Step 3. Calculate control points ''' P_inter = bc.curve_interpolation(D, D_N, k, p_centripetal, knot) # print(P_inter) fig = plt.figure() for i in range(D_N): plt.scatter(D[0][i], D[1][i], color='r') plt.scatter(P_inter[0][i], P_inter[1][i], color='b') for i in range(D_N - 1): tmp_x = [P_inter[0][i], P_inter[0][i+1]] tmp_y = [P_inter[1][i], P_inter[1][i+1]] plt.plot(tmp_x, tmp_y, color='b') ''' Step 4. Calculate the points on the b-spline curve ''' piece_num = 80 p_piece = np.linspace(0, 1, piece_num) P_piece = bc.curve(P_inter, D_N, k, p_piece, knot) # print(P_piece) for i in range(piece_num - 1): tmp_x = [P_piece[0][i], P_piece[0][i+1]] tmp_y = [P_piece[1][i], P_piece[1][i+1]] plt.plot(tmp_x, tmp_y, color='g') plt.show()
def curve_inter_figure(): D_X = [1, 1, 0, -0.5, 1.5, 3, 4, 4.2, 4] D_Y = [0, 1, 2, 3, 4, 3.5, 3, 2.5, 2] D = [D_X, D_Y] D_N = len(D_X) k = 2 # p_uniform = ps.uniform_spaced(D_N) # print(p_uniform) # p_chord_length = ps.chord_length(D_N, D) # print(p_chord_length) p_centripetal = ps.centripetal(D_N, D) # print(p_centripetal) knot = ps.knot_vector(p_centripetal, k, D_N) # print(knot) P_inter = bc.curve_interpolation(D, D_N, k, p_centripetal, knot) # print(P_inter) fig = plt.figure() for i in range(D_N): plt.scatter(D[0][i], D[1][i], color='r') plt.scatter(P_inter[0][i], P_inter[1][i], color='b') for i in range(D_N - 1): tmp_x = [P_inter[0][i], P_inter[0][i + 1]] tmp_y = [P_inter[1][i], P_inter[1][i + 1]] plt.plot(tmp_x, tmp_y, color='b') piece_num = 80 p_piece = np.linspace(0, 1, piece_num) P_piece = bc.curve(P_inter, D_N, k, p_piece, knot) # print(P_piece) for i in range(piece_num - 1): tmp_x = [P_piece[0][i], P_piece[0][i + 1]] tmp_y = [P_piece[1][i], P_piece[1][i + 1]] plt.plot(tmp_x, tmp_y, color='g') plt.show()
def surface_approx_figure(): D_X = [[0.0, 3, 6, 7, 9, 15], [0.0, 3, 6, 7, 9, 15], [0.0, 3, 6, 7, 9, 15], [0.0, 3, 6, 7, 9, 15], [0.0, 3, 6, 7, 9, 15]] D_Y = [[2, 2, 2, 2, 2, 2], [5, 5, 5, 5, 5, 5], [10, 10, 10, 10, 10, 10], [15, 15, 15, 15, 15, 15], [20, 20, 20, 20, 20, 20]] D_Z = [[0, -2, -5, -8, -10, -14], [0, -3, -5, -9, -12, -15], [0, -2, -5, -8, -11, -16], [-1, -4, -6, -8, -11.5, -15], [1, -2, -4, -8, -11, -16]] D = [D_X, D_Y, D_Z] k = 3 q = 3 E = len(D_X) - 1 F = len(D_X[0]) - 1 P_control = bs.surface_approximation(D, k, q, E, F) piece_uv = [20, 30] knot_uv = [[], []] # p_uniform_u = ps.uniform_spaced(E) # p_uniform_v = ps.uniform_spaced(F) # knot_uv[0] = ps.knot_vector(p_uniform_u, k, E) # knot_uv[1] = ps.knot_vector(p_uniform_v, q, F) # p_piece = np.linspace(0, 1, piece_num) # p_centripetal_new = ps.centripetal(H, P_control) # knot_new = ps.knot_vector(p_centripetal_new, k, H) # P_piece = bc.curve(P_control, H, k, p_piece, knot_new) tmp_param = np.zeros((1, E)) for i in range(F): D_col_X = [x[i] for x in P_control[0]] D_col_Y = [y[i] for y in P_control[1]] D_col = [D_col_X, D_col_Y] tmp_param = tmp_param + np.array(ps.centripetal(E, D_col)) # tmp_param = ps.centripetal(N, D_row) # param_u.append(np.average(np.array(tmp_param))) param_u = np.divide(tmp_param, F).tolist()[0] param_v = [] tmp_param = np.zeros((1, F)) for i in range(E): D_row_X = P_control[0][i] D_row_Y = P_control[1][i] D_row = [D_row_X, D_row_Y] tmp_param = tmp_param + np.array(ps.centripetal(F, D_row)) # param_v.append(np.average(np.array(tmp_param))) param_v = np.divide(tmp_param, E).tolist()[0] knot_uv[0] = ps.knot_vector(param_u, k, E) knot_uv[1] = ps.knot_vector(param_v, q, F) P_piece = bs.surface(P_control, k, q, piece_uv, knot_uv) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') for i in range(len(D_X)): for j in range(len(D_X[0])): ax.scatter(D_X[i][j], D_Y[i][j], D_Z[i][j], color='r') for i in range(len(P_control[0])): for j in range(len(P_control[0][0])): ax.scatter(P_control[0][i][j], P_control[1][i][j], P_control[2][i][j], color='b') for i in range(len(P_control[0])): for j in range(len(P_control[0][0]) - 1): tmp_x = [P_control[0][i][j], P_control[0][i][j + 1]] tmp_y = [P_control[1][i][j], P_control[1][i][j + 1]] tmp_z = [P_control[2][i][j], P_control[2][i][j + 1]] ax.plot(tmp_x, tmp_y, tmp_z, color='b') for i in range(len(P_control[0]) - 1): for j in range(len(P_control[0][0])): tmp_x = [P_control[0][i][j], P_control[0][i + 1][j]] tmp_y = [P_control[1][i][j], P_control[1][i + 1][j]] tmp_z = [P_control[2][i][j], P_control[2][i + 1][j]] ax.plot(tmp_x, tmp_y, tmp_z, color='b') for i in range(len(P_piece[0]) - 1): for j in range(len(P_piece[0][0])): tmp_x = [P_piece[0][i][j], P_piece[0][i + 1][j]] tmp_y = [P_piece[1][i][j], P_piece[1][i + 1][j]] tmp_z = [P_piece[2][i][j], P_piece[2][i + 1][j]] ax.plot(tmp_x, tmp_y, tmp_z, color='g') for i in range(len(P_piece[0])): for j in range(len(P_piece[0][0]) - 1): tmp_x = [P_piece[0][i][j], P_piece[0][i][j + 1]] tmp_y = [P_piece[1][i][j], P_piece[1][i][j + 1]] tmp_z = [P_piece[2][i][j], P_piece[2][i][j + 1]] ax.plot(tmp_x, tmp_y, tmp_z, color='g') plt.show()
def surface_approx_figure(): D_X = [[0.0, 3, 6, 7, 9, 15], [0.0, 3, 6, 7, 9, 15], [0.0, 3, 6, 7, 9, 15], [0.0, 3, 6, 7, 9, 15], [0.0, 3, 6, 7, 9, 15]] D_Y = [[2, 2, 2, 2, 2, 2], [5, 5, 5, 5, 5, 5], [10, 10, 10, 10, 10, 10], [15, 15, 15, 15, 15, 15], [20, 20, 20, 20, 20, 20]] D_Z = [[0, -2, -5, -8, -10, -14], [0, -3, -5, -9, -12, -15], [0, -2, -5, -8, -11, -16], [-1, -4, -6, -8, -11.5, -15], [1, -2, -4, -8, -11, -16]] D = [D_X, D_Y, D_Z] k = 2 q = 3 E = len(D_X) - 1 F = len(D_X[0]) - 1 ''' Step 1. Calculate control surface's control points ''' P_control = bs.surface_approximation(D, k, q, E, F) ''' Step 2. Calculate the points on the b-spline surface ''' piece_uv = [20, 30] knot_uv =[[], []] tmp_param = np.zeros((1, E)) for i in range(F): D_col_X = [x[i] for x in P_control[0]] D_col_Y = [y[i] for y in P_control[1]] D_col = [D_col_X, D_col_Y] tmp_param = tmp_param + np.array(ps.centripetal(E, D_col)) param_u = np.divide(tmp_param, F).tolist()[0] param_v = [] tmp_param = np.zeros((1, F)) for i in range(E): D_row_X = P_control[0][i] D_row_Y = P_control[1][i] D_row = [D_row_X, D_row_Y] tmp_param = tmp_param + np.array(ps.centripetal(F, D_row)) # param_v.append(np.average(np.array(tmp_param))) param_v = np.divide(tmp_param, E).tolist()[0] knot_uv[0] = ps.knot_vector(param_u, k, E) knot_uv[1] = ps.knot_vector(param_v, q, F) P_piece = bs.surface(P_control, k, q, piece_uv, knot_uv) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') for i in range(len(D_X)): for j in range(len(D_X[0])): ax.scatter(D_X[i][j], D_Y[i][j], D_Z[i][j], color='r') for i in range(len(P_control[0])): for j in range(len(P_control[0][0])): ax.scatter(P_control[0][i][j], P_control[1][i][j], P_control[2][i][j], color='b') for i in range(len(P_control[0])): for j in range(len(P_control[0][0]) - 1): tmp_x = [P_control[0][i][j], P_control[0][i][j + 1]] tmp_y = [P_control[1][i][j], P_control[1][i][j + 1]] tmp_z = [P_control[2][i][j], P_control[2][i][j + 1]] ax.plot(tmp_x, tmp_y, tmp_z, color='b') for i in range(len(P_control[0]) - 1): for j in range(len(P_control[0][0])): tmp_x = [P_control[0][i][j], P_control[0][i + 1][j]] tmp_y = [P_control[1][i][j], P_control[1][i + 1][j]] tmp_z = [P_control[2][i][j], P_control[2][i + 1][j]] ax.plot(tmp_x, tmp_y, tmp_z, color='b') for i in range(len(P_piece[0]) - 1): for j in range(len(P_piece[0][0])): tmp_x = [P_piece[0][i][j], P_piece[0][i + 1][j]] tmp_y = [P_piece[1][i][j], P_piece[1][i + 1][j]] tmp_z = [P_piece[2][i][j], P_piece[2][i + 1][j]] ax.plot(tmp_x, tmp_y, tmp_z, color='g') for i in range(len(P_piece[0])): for j in range(len(P_piece[0][0]) - 1): tmp_x = [P_piece[0][i][j], P_piece[0][i][j + 1]] tmp_y = [P_piece[1][i][j], P_piece[1][i][j + 1]] tmp_z = [P_piece[2][i][j], P_piece[2][i][j + 1]] ax.plot(tmp_x, tmp_y, tmp_z, color='g') plt.show()
def surface_approximation(D, p, q, E, F): ''' Given a grid of (M x N) data points Dij, a degree (p, q), and e and f satisfying M > E > p >= 1 and N > F > q >= 1, find a B-spline surface of degree (p, q) defined by (E x F) control points Pij that approximates the data point grid in the given order. :param D: data points :param p: degree of u direction :param q: degree of v direction :return: control points ''' D_X = D[0] D_Y = D[1] D_Z = D[2] M = len(D_X) N = len(D_X[0]) knot_uv = [[], []] # calculate parameters and knot vector tmp_param = np.zeros((1, M)) for i in range(N): D_col_X = [x[i] for x in D_X] D_col_Y = [y[i] for y in D_Y] D_col_Z = [z[i] for z in D_Z] D_col = [D_col_X, D_col_Y, D_col_Z] tmp_param = tmp_param + np.array(ps.centripetal(M, D_col)) param_u = np.divide(tmp_param, N).tolist()[0] param_v = [] tmp_param = np.zeros((1, N)) for i in range(M): D_row_X = D_X[i] D_row_Y = D_Y[i] D_row_Z = D_Z[i] D_row = [D_row_X, D_row_Y, D_row_Z] tmp_param = tmp_param + np.array(ps.centripetal(N, D_row)) param_v = np.divide(tmp_param, M).tolist()[0] knot_uv[0] = ps.knot_vector(param_u, p, M) knot_uv[1] = ps.knot_vector(param_v, q, N) # calculate control points for every column Q = [ np.zeros((E, N)).tolist(), np.zeros((E, N)).tolist(), np.zeros((E, N)).tolist() ] for i in range(N): D_col_X = [x[i] for x in D_X] D_col_Y = [y[i] for y in D_Y] D_col_Z = [z[i] for z in D_Z] D_col = [D_col_X, D_col_Y, D_col_Z] Q_col = bc.curve_approximation(D_col, M, E, p, param_u, knot_uv[0]) # print(Q_col) for j in range(E): Q[0][j][i] = Q_col[0][j] Q[1][j][i] = Q_col[1][j] Q[2][j][i] = Q_col[2][j] # calculate control points for every row P = [ np.zeros((E, F)).tolist(), np.zeros((E, F)).tolist(), np.zeros((E, F)).tolist() ] for i in range(E): Q_row = [Q[0][i], Q[1][i], Q[2][i]] P_ = bc.curve_approximation(Q_row, N, F, q, param_v, knot_uv[1]) P[0][i] = P_[0] P[1][i] = P_[1] P[2][i] = P_[2] return P
def surface_interpolation(D, p, q): ''' Given a grid of (M x N) data points Dij and a degree (p, q), find a B-spline surface of degree (p, q) defined by (M x N) control points that passes all data points in the given order. :param D: data points :param p: degree of u direction :param q: degree of v direction :return: control points and knot vectors ''' D_X = D[0] D_Y = D[1] D_Z = D[2] M = len(D_X) N = len(D_X[0]) Q = [ np.zeros((len(D_X), len(D_X[0]))).tolist(), np.zeros((len(D_Y), len(D_Y[0]))).tolist(), np.zeros((len(D_Z), len(D_Z[0]))).tolist() ] knot_uv = [[], []] # calculate parameters and knot vector param_u = [] tmp_param = np.zeros((1, M)) for i in range(N): D_col_X = [x[i] for x in D_X] D_col_Y = [y[i] for y in D_Y] D_col_Z = [z[i] for z in D_Z] D_col = [D_col_X, D_col_Y, D_col_Z] tmp_param = tmp_param + np.array(ps.centripetal(M, D_col)) param_u = np.divide(tmp_param, N).tolist()[0] param_v = [] tmp_param = np.zeros((1, N)) for i in range(M): D_row_X = D_X[i] D_row_Y = D_Y[i] D_row_Z = D_Z[i] D_row = [D_row_X, D_row_Y, D_row_Z] tmp_param = tmp_param + np.array(ps.centripetal(N, D_row)) param_v = np.divide(tmp_param, M).tolist()[0] knot_uv[0] = ps.knot_vector(param_u, p, M) knot_uv[1] = ps.knot_vector(param_v, q, N) print(param_u) print(param_v) # calculate control points for every column for i in range(N): D_col_X = [x[i] for x in D_X] D_col_Y = [y[i] for y in D_Y] D_col_Z = [z[i] for z in D_Z] D_col = [D_col_X, D_col_Y, D_col_Z] Q_col = bc.curve_interpolation(D_col, M, p, param_u, knot_uv[0]) for j in range(M): Q[0][j][i] = Q_col[0][j] Q[1][j][i] = Q_col[1][j] Q[2][j][i] = Q_col[2][j] P = Q # calculate control points for every row for i in range(M): Q_row = [Q[0][i], Q[1][i], Q[2][i]] P_ = bc.curve_interpolation(Q_row, N, q, param_v, knot_uv[1]) P[0][i] = P_[0] P[1][i] = P_[1] P[2][i] = P_[2] return P, knot_uv
def LSPIA_curve(): ''' The LSPIA iterative method for blending curves. ''' # D_X = [1, 1, 0, -0.5, 1.5, 3, 4, 4.2, 5, 5.5, 6, 5.1, 4.6] # D_Y = [0, 1, 2, 3, 4, 3.5, 3, 2.5, 2, 1.2, 1, 2.7, 4] # D = [D_X, D_Y] D = load_curve_data('cur_data') D_X = D[0] D_Y = D[1] D_N = len(D_X) k = 3 # degree P_N = int(D_N / 2) - 50 print(P_N) ''' Step 1. Calculate the parameters ''' p_centripetal = ps.centripetal(D_N, D) print(p_centripetal) ''' Step 2. Calculate knot vector ''' knot_vector = ps.LSPIA_knot_vector(p_centripetal, k, P_N, D_N) print(knot_vector) ''' Step 3. Select initial control points ''' P_X = [D_X[0]] P_Y = [D_Y[0]] for i in range(1, P_N - 1): # f_i = int(D_N * i / P_N) # P_X.append(D_X[f_i]) # P_Y.append(D_Y[f_i]) P_X.append(0) P_Y.append(0) P_X.append(D_X[-1]) P_Y.append(D_Y[-1]) P = [P_X, P_Y] ''' Step 4. Calculate the collocation matrix of the NTP blending basis ''' Nik = np.zeros((D_N, P_N)) c = np.zeros((1, P_N)) for i in range(D_N): for j in range(P_N): Nik[i][j] = bf.BaseFunction(j, k + 1, p_centripetal[i], knot_vector) c[0][j] = c[0][j] + Nik[i][j] C = max(c[0].tolist()) miu = 2 / C ''' Step 5. First iteration ''' e = [] ek = cfe.curve_fitting_error(D, P, Nik) e.append(ek) ''' Step 6. Adjusting control points ''' P = cfe.curve_adjusting_control_points(D, P, Nik, miu) # print(P) ek = cfe.curve_fitting_error(D, P, Nik) e.append(ek) cnt = 0 while (abs(e[-1] - e[-2]) >= 1e-7): cnt = cnt + 1 print('iteration ', cnt) P = cfe.curve_adjusting_control_points(D, P, Nik, miu) # print(P) ek = cfe.curve_fitting_error(D, P, Nik) e.append(ek) # print(P) ''' Step 7. Calculate data points on the b-spline curve ''' piece = 200 p_piece = np.linspace(0, 1, piece) Nik_piece = np.zeros((piece, P_N)) for i in range(piece): for j in range(P_N): Nik_piece[i][j] = bf.BaseFunction(j, k + 1, p_piece[i], knot_vector) P_piece = cfe.curve(p_piece, P, Nik_piece) ''' Step 8. Draw b-spline curve ''' for i in range(D_N): plt.scatter(D[0][i], D[1][i], color='r') # for i in range(len(P[0]) - 1): # plt.scatter(P[0][i], P[1][i], color='b') # for i in range(len(P[0]) - 1): # tmp_x = [P[0][i], P[0][i + 1]] # tmp_y = [P[1][i], P[1][i + 1]] # plt.plot(tmp_x, tmp_y, color='b') for i in range(piece - 1): tmp_x = [P_piece[0][i], P_piece[0][i + 1]] tmp_y = [P_piece[1][i], P_piece[1][i + 1]] plt.plot(tmp_x, tmp_y, color='g') plt.show()
def LSPIA_surface(): ''' The LSPIA iterative method for blending surfaces. ''' D = load_surface_data('surface_data2') D_X = D[0] D_Y = D[1] D_Z = D[2] row = len(D_X) col = len(D_X[0]) p = 3 # degree q = 3 P_h = int(row / 2) # the number of control points P_l = int(col / 2) ''' Step 1. Calculate the parameters ''' param_u = [] tmp_param = np.zeros((1, row)) for i in range(col): D_col_X = [x[i] for x in D_X] D_col_Y = [y[i] for y in D_Y] D_col_Z = [z[i] for z in D_Z] D_col = [D_col_X, D_col_Y, D_col_Z] tmp_param = tmp_param + np.array(ps.centripetal(row, D_col)) param_u = np.divide(tmp_param, col).tolist()[0] param_v = [] tmp_param = np.zeros((1, col)) for i in range(row): D_row_X = D_X[i] D_row_Y = D_Y[i] D_row_Z = D_Z[i] D_row = [D_row_X, D_row_Y, D_row_Z] tmp_param = tmp_param + np.array(ps.centripetal(col, D_row)) param_v = np.divide(tmp_param, row).tolist()[0] ''' Step 2. Calculate the knot vectors ''' knot_uv = [[], []] knot_uv[0] = ps.LSPIA_knot_vector(param_u, p, P_h, row) knot_uv[1] = ps.LSPIA_knot_vector(param_v, q, P_l, col) ''' Step 3. Select initial control points ''' P_X = [] P_Y = [] P_Z = [] for i in range(0, P_h - 1): f_i = int(row * i / P_h) P_X_row = [] P_Y_row = [] P_Z_row = [] for j in range(0, P_l - 1): # f_j = int(col * j / P_l) # P_X_row.append(D_X[f_i][f_j]) # P_Y_row.append(D_Y[f_i][f_j]) # P_Z_row.append(D_Z[f_i][f_j]) P_X_row.append(0) P_Y_row.append(0) P_Z_row.append(0) # P_X_row.append(D_X[f_i][-1]) # P_Y_row.append(D_Y[f_i][-1]) # P_Z_row.append(D_Z[f_i][-1]) P_X_row.append(0) P_Y_row.append(0) P_Z_row.append(0) P_X.append(P_X_row) P_Y.append(P_Y_row) P_Z.append(P_Z_row) P_X_row = [] P_Y_row = [] P_Z_row = [] for j in range(0, P_l - 1): f_j = int(col * j / P_l) P_X_row.append(D_X[-1][f_j]) P_Y_row.append(D_Y[-1][f_j]) P_Z_row.append(D_Z[-1][f_j]) P_X_row.append(D_X[f_i][-1]) P_Y_row.append(D_Y[f_i][-1]) P_Z_row.append(D_Z[f_i][-1]) P_X.append(P_X_row) P_Y.append(P_Y_row) P_Z.append(P_Z_row) P = [P_X, P_Y, P_Z] ''' Step 4. Calculate the collocation matrix of the NTP blending basis ''' Nik_u = np.zeros((row, P_h)) c_u = np.zeros((1, P_h)) for i in range(row): for j in range(P_h): Nik_u[i][j] = bf.BaseFunction(j, p + 1, param_u[i], knot_uv[0]) c_u[0][j] = c_u[0][j] + Nik_u[i][j] C = max(c_u[0].tolist()) miu_u = 2 / C Nik_v = np.zeros((col, P_l)) c_v = np.zeros((1, P_l)) for i in range(col): for j in range(P_l): Nik_v[i][j] = bf.BaseFunction(j, q + 1, param_v[i], knot_uv[1]) c_v[0][j] = c_v[0][j] + Nik_v[i][j] C = max(c_v[0].tolist()) miu_v = 2 / C # miu = miu_u * miu_v miu = 0.2 Nik = [Nik_u, Nik_v] ''' Step 5. First iteration ''' e = [] ek = sfe.surface_fitting_error(D, P, Nik) e.append(ek) ''' Step 6. Adjusting control points ''' P = sfe.surface_adjusting_control_points(D, P, Nik, miu) # print(P) ek = sfe.surface_fitting_error(D, P, Nik) e.append(ek) cnt = 0 while (abs(e[-1] - e[-2]) >= 1e-7): cnt = cnt + 1 print('iteration ', cnt) P = sfe.surface_adjusting_control_points(D, P, Nik, miu) # print(P) ek = sfe.surface_fitting_error(D, P, Nik) e.append(ek) print(ek) ''' Step 7. Calculate data points on the b-spline curve ''' piece_u = 50 piece_v = 50 p_piece_u = np.linspace(0, 1, piece_u) p_piece_v = np.linspace(0, 1, piece_v) Nik_piece_u = np.zeros((piece_u, P_h)) Nik_piece_v = np.zeros((piece_v, P_l)) for i in range(piece_u): for j in range(P_h): Nik_piece_u[i][j] = bf.BaseFunction(j, p + 1, p_piece_u[i], knot_uv[0]) for i in range(piece_v): for j in range(P_l): Nik_piece_v[i][j] = bf.BaseFunction(j, q + 1, p_piece_v[i], knot_uv[1]) p_piece = [piece_u, piece_v] Nik_piece = [Nik_piece_u, Nik_piece_v] P_piece = sfe.surface(p_piece, P, Nik_piece) ''' Step 8. Draw b-spline curve ''' fig = plt.figure() ax = fig.add_subplot(111, projection='3d') for i in range(int(row/10)): for j in range(int(col/10)): ax.scatter(D_X[10*i][10*j], D_Y[10*i][10*j], D_Z[10*i][10*j], color='r') # for i in range(len(P[0]) - 1): # plt.scatter(P[0][i], P[1][i], color='b') # for i in range(len(P[0]) - 1): # tmp_x = [P[0][i], P[0][i + 1]] # tmp_y = [P[1][i], P[1][i + 1]] # plt.plot(tmp_x, tmp_y, color='b') for i in range(piece_u): for j in range(piece_v - 1): tmp_x = [P_piece[0][i][j], P_piece[0][i][j + 1]] tmp_y = [P_piece[1][i][j], P_piece[1][i][j + 1]] tmp_z = [P_piece[2][i][j], P_piece[2][i][j + 1]] ax.plot(tmp_x, tmp_y, tmp_z, color='g') for j in range(piece_v): for i in range(piece_u - 1): tmp_x = [P_piece[0][i][j], P_piece[0][i + 1][j]] tmp_y = [P_piece[1][i][j], P_piece[1][i + 1][j]] tmp_z = [P_piece[2][i][j], P_piece[2][i + 1][j]] ax.plot(tmp_x, tmp_y, tmp_z, color='g') plt.show()