Esempio n. 1
0
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()
Esempio n. 2
0
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()
Esempio n. 3
0
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()
Esempio n. 4
0
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()
Esempio n. 5
0
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()
Esempio n. 6
0
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()
Esempio n. 7
0
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
Esempio n. 8
0
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
Esempio n. 9
0
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()
Esempio n. 10
0
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()