-
Notifications
You must be signed in to change notification settings - Fork 0
/
bspline.py
executable file
·74 lines (52 loc) · 2 KB
/
bspline.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
# adapted from:
# http://stackoverflow.com/questions/12643079/bezier-curve-fitting-with-scipy/14125828
import numpy as np
from scipy.misc import comb
class Bezier(object):
def __init__(self):
super(Bezier, self).__init__()
pass
# The Bernstein polynomial of n, i as a function of t
def bernstein_poly(self, i, n, t):
return comb(n, i) * ( t**(n-i) ) * (1 - t)**i
# Given a set of control points, return the bezier curve defined by the control points.
# points should be a flat list
# such as [1,1, 2,2, 3,3, ...Xn,Yn]
# nTimes is the number of time steps, defaults to 1000
def bezier_curve(self, points, nTimes=1000):
nPoints = len(points) / 2
t = np.linspace(0.0, 1.0, nTimes)
polynomial_array = np.array([self.bernstein_poly(i, nPoints-1, t) for i in range(0, nPoints)])
nPoints *= 2
l1 = []
l2 = []
for i in range(0, nPoints, 2):
l1.append(points[i])
l2.append(points[i+1])
xvals = np.dot(np.array(l1), polynomial_array)
yvals = np.dot(np.array(l2), polynomial_array)
l1 = []
for i in range(0, nTimes, 2):
l1.append(xvals[i])
l1.append(yvals[i+1])
return l1
def split_pairs(self,l):
l1 = []
l2 = []
for i in range(0, len(l), 2):
l1.append(l[i])
l2.append(l[i+1])
return l1, l2
if __name__ == '__main__':
from matplotlib import pyplot as plt
points = [155.95185909, 4.64042794, 57.74101074, 138.1875438, 25.93409495, 81.44692581,21.16373321, 184.4609643]
b = Bezier()
bezier = b.bezier_curve(points, nTimes=1000)
# split_pairs is a utility to convert to plt.plot's funky format
xpoints, ypoints = b.split_pairs(points)
xvals, yvals = b.split_pairs(bezier)
plt.plot(xvals, yvals)
plt.plot(xpoints, ypoints, "ro")
for nr in range(len(xpoints)):
plt.text(xpoints[nr], ypoints[nr], nr)
plt.show()