-
Notifications
You must be signed in to change notification settings - Fork 1
/
b_spline.py
83 lines (70 loc) · 2.46 KB
/
b_spline.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
from __future__ import division, print_function
import numpy as np
import scipy.sparse
def get_bspline_mtx(num_cp, num_pt, order=4):
""" Create Jacobian to fit a bspline to a set of data.
Parameters
----------
num_cp : int
Number of control points.
num_pt : int
Number of points.
order : int, optional
Order of b-spline fit.
Returns
-------
out : CSR sparse matrix
Matrix that gives the points vector when multiplied by the control
points vector.
"""
knots = np.zeros(num_cp + order)
knots[order-1:num_cp+1] = np.linspace(0, 1, num_cp - order + 2)
knots[num_cp+1:] = 1.0
t_vec = np.linspace(0, 1, num_pt)
basis = np.zeros(order)
arange = np.arange(order)
data = np.zeros((num_pt, order))
rows = np.zeros((num_pt, order), int)
cols = np.zeros((num_pt, order), int)
for ipt in range(num_pt):
t = t_vec[ipt]
i0 = -1
for ind in range(order, num_cp+1):
if (knots[ind-1] <= t) and (t < knots[ind]):
i0 = ind - order
if t == knots[-1]:
i0 = num_cp - order
basis[:] = 0.
basis[-1] = 1.
for i in range(2, order+1):
l = i - 1
j1 = order - l
j2 = order
n = i0 + j1
if knots[n+l] != knots[n]:
basis[j1-1] = (knots[n+l] - t) / \
(knots[n+l] - knots[n]) * basis[j1]
else:
basis[j1-1] = 0.
for j in range(j1+1, j2):
n = i0 + j
if knots[n+l-1] != knots[n-1]:
basis[j-1] = (t - knots[n-1]) / \
(knots[n+l-1] - knots[n-1]) * basis[j-1]
else:
basis[j-1] = 0.
if knots[n+l] != knots[n]:
basis[j-1] += (knots[n+l] - t) / \
(knots[n+l] - knots[n]) * basis[j]
n = i0 + j2
if knots[n+l-1] != knots[n-1]:
basis[j2-1] = (t - knots[n-1]) / \
(knots[n+l-1] - knots[n-1]) * basis[j2-1]
else:
basis[j2-1] = 0.
data[ipt, :] = basis
rows[ipt, :] = ipt
cols[ipt, :] = i0 + arange
data, rows, cols = data.flatten(), rows.flatten(), cols.flatten()
return scipy.sparse.csr_matrix((data, (rows, cols)),
shape=(num_pt, num_cp))