• API
• FAQ
• Tools
• Archive
SHARE
TWEET

# Untitled

a guest Oct 23rd, 2019 71 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. import numpy as np
2. import matplotlib.patches as patches
3.
4.
5. class BSpline():
6.     def __init__(self):
7.         pass
8.         self.warp = 4.
9.         self.count = 26*2
10.
11.
12.     def process(self, Px, Py, Pw, ax, MODE=1):
13.         self.mode = MODE # Can be 0 or 1 for terminal tangents
14.         self.ax = ax
15.         self.Px = Px
16.         self.Py = Py
17.         self.Pw = Pw
18.
19.         count = self.count
20.         if self.mode == 0:
21.             self.n = len(Px) - 2
22.         else:
23.             self.n = len(Px) - 2
24.         self.n1 = self.n+1;
25.         self.B0 = [None]*count
26.         self.B1 = [None]*count
27.         self.B2 = [None]*count
28.         self.B3 = [None]*count
29.         self.dx = [None]*self.n
30.         self.dy = [None]*self.n
31.
32.         t = 0.;
33.         for i in range(0, count):
34.             t1 = 1-t
35.             t12 = t1*t1
36.             t2 = t*t
37.             self.B0[i] = t1*t12
38.             self.B1[i] = 3*t*t12
39.             self.B2[i] = 3*t2*t1
40.             self.B3[i] = t*t2
41.             t += 1.00/count
42.
43.         return self.drawSpline()
44.
45.     def findCPoints(self):
46.         if self.mode == 0:
47.             self.dx[0] = self.Px[self.n] - self.Px[0];
48.             self.dy[0] = self.Py[self.n] - self.Py[0];
49.             self.dx[self.n-1] = -(self.Px[self.n1] - self.Px[self.n-1])
50.             self.dy[self.n-1] = -(self.Py[self.n1] - self.Py[self.n - 1])
51.         else:
52.             DIV = 3.
53.             self.dx[0] = (self.Px[1] - self.Px[0])/DIV;
54.             self.dy[0] = (self.Py[1] - self.Py[0])/DIV;
55.             self.dx[self.n-1] = (self.Px[self.n-1] - self.Px[self.n-2])/DIV;
56.             self.dy[self.n-1] = (self.Py[self.n-1] - self.Py[self.n-2])/DIV;
57.
58.         #self.warp += 0.05
59.
60.         warps = self.Pw
61.
62.         Ax = [None]*self.n
63.         Ay = [None]*self.n
64.         Bi = [None]*self.n
65.         Bi[1] = -1/warps[1]
66.         Ax[1] = -(self.Px[2] - self.Px[0] - self.dx[0])*Bi[1]
67.         Ay[1] = -(self.Py[2] - self.Py[0] - self.dy[0])*Bi[1];
68.         for i in range(2, self.n-1):
69.             warpval = warps[i]
70.             Bi[i] = -1/(warpval+ Bi[i-1]);
71.             Ax[i] = -(self.Px[i+1] - self.Px[i-1] - Ax[i-1])*Bi[i];
72.             Ay[i] = -(self.Py[i+1] - self.Py[i-1] - Ay[i-1])*Bi[i];
73.         for i in range(self.n-2, 0, -1):
74.             self.dx[i] = Ax[i] + self.dx[i+1]*Bi[i];
75.             self.dy[i] = Ay[i] + self.dy[i+1]*Bi[i];
76.
77.         #self.dx[1] = 0
78.         #self.dy[0] = 0
79.         #self.dy[1] = 0
80.         # for i in range(0, len(self.dx)):
81.         #     self.dx[i] = 0
82.         #     self.dy[i] = 0
83.         # print self.dx
84.         # print self.dy
85.
86.
87.     def drawSpline(self):
88.         self.findCPoints()
89.
90.         w = 1.
91.         h = 1.
92.         d = 0.
93.         h1 = h
94.         d2 = d
95.         step = 1./w
96.         t = step;
97.         scPx = [None]*self.n
98.         scPy = [None]*self.n
99.         scDx = [None]*self.n
100.         scDy = [None]*self.n
101.         X = None
102.         Y = None
103.
104.         squaresize = 0.3
105.         for i in range(0, self.n):
106.            X = scPx[i] = self.Px[i]*w
107.            Y = scPy[i] = self.Py[i]*h;
108.            scDx[i] = self.dx[i]*w;
109.            scDy[i] = self.dy[i]*h;
110.            rect = patches.Rectangle((X - squaresize/2.,Y - squaresize/2.),squaresize,squaresize,linewidth=1,edgecolor='r',facecolor='none')
112.
113.         #if self.mode == 0:
114.         self.ax.add_patch(patches.Rectangle((scPx[0]+scDx[0] - squaresize/2., (scPy[0]+scDy[0])- squaresize/2.),squaresize,squaresize,
115.             linewidth=1,edgecolor='b',facecolor='none'))
116.         self.ax.add_patch(patches.Rectangle((scPx[self.n-1]-scDx[self.n-1] - squaresize/2., (scPy[self.n-1]-scDy[self.n-1])- squaresize/2.),squaresize,squaresize,
117.             linewidth=1,edgecolor='b',facecolor='none'))
118.
119.         # if self.n > 1:
120.         #     paths = [[scPx[0], scPy[0]]]
121.         #     for i in range(1, self.n):
122.         #         paths.append([scPx[i-1]+scDx[i-1], scPy[i-1]-scDy[i-1]])
123.         #         paths.append([scPx[i]-scDx[i], scPy[i]+scDy[i]])
124.         #         paths.append([scPx[i], scPy[i]])
125.         #     paths_arr = np.array(paths)
126.         #     plt.plot(paths_arr[:, 0], paths_arr[:, 1])
127.         #     #for path in paths:
128.
129.         paths = [[scPx[0], scPy[0]]]
130.         for i in range(0, self.n-1):
131.             for k in range(0, self.count):
132.                 X = (scPx[i]*self.B0[k] + (scPx[i] + scDx[i])*self.B1[k] +
133.                     (scPx[i+1] - scDx[i+1])*self.B2[k] + scPx[i+1]*self.B3[k])
134.                 Y = (scPy[i]*self.B0[k] + (scPy[i] + scDy[i])*self.B1[k] +
135.                     (scPy[i+1] - scDy[i+1])*self.B2[k] + scPy[i+1]*self.B3[k]);
136.                 paths.append([X,Y])
137.         paths_arr = np.array(paths)
138.         plt.scatter(paths_arr[:, 0], paths_arr[:, 1], s=0.2)
139.
140.         return paths_arr
141.
142. # cv = np.array(
143. # [[ 2.70967742,  1.30411255,  4.        ], # D
144. #  [ 2.45564516,  6.28246753,  4.        ], # C
145. #  [-0.90322581,  6.39069264,  4.        ],
146. #  [-1.04435484,  1.27705628,  4.        ],
147. #  [-5.75806452,  1.41233766,  4.        ], # B
148. #  [-5.95564516,  6.14718615,  4.        ], # A
149. #  [ 2.51209677,  3.79329004,  4.        ], # T: Should be center of CD
150. #  [-6.06854839,  4.11796537,  4.        ]] # T: Should be center of AB
151. #     )
152.
153. cv = np.array(
154. [[ 6.35080645,  5.95779221,  4.        ],
155.  [ 6.32258065,  1.46645022,  4.        ],
156.  [ 4.20564516,  1.46645022,  4.        ],
157.  [ 4.20564516,  6.01190476,  4.        ],
158.  [ 1.80645161,  5.95779221,  4.        ],
159.  [ 1.66532258,  1.46645022,  4.        ],
160.  [-0.56451613,  1.38528139,  4.        ],
161.  [-0.64919355,  6.06601732,  4.        ],
162.  [-2.73790323,  6.03896104,  4.        ],
163.  [-2.96370968,  1.33116883,  4.        ],
164.  [-5.75806452,  1.41233766,  4.        ],
165.  [-5.95564516,  6.14718615,  4.        ],
166.  [ 6.29435484,  3.76623377,  4.        ],
167.  [-6.06854839,  4.11796537,  4.        ]]
168.     )
169.
170. class Click():
171.     def __init__(self, ax, button=1):
172.         self.ax=ax
173.         self.button=button
174.         self.press=False
175.         self.move = False
176.         self.c1=self.ax.figure.canvas.mpl_connect('button_press_event', self.onpress)
177.         self.c2=self.ax.figure.canvas.mpl_connect('button_release_event', self.onrelease)
178.         self.c3=self.ax.figure.canvas.mpl_connect('motion_notify_event', self.onmove)
179.
180.         self.c4=self.ax.figure.canvas.mpl_connect('scroll_event',self.onzoom)
181.
182.     def onzoom(self, event):
183.         print("zoom")
184.         global cv
185.         lowest_dist = 1000
186.         lowest_index = -1
187.         for i in range(0, cv.shape[0]):
188.             dist = np.sqrt((cv[i,0]-event.xdata)**2 + (cv[i,1]-event.ydata)**2)
189.             if dist < lowest_dist:
190.                 lowest_dist = dist
191.                 lowest_index = i
192.         if lowest_dist < 2:
193.             if event.button == "up":
194.                 cv[lowest_index, 2] += 0.5
195.             elif event.button == "down":
196.                 if cv[lowest_index, 2] > 1.5:
197.                     cv[lowest_index, 2] -= 0.5
198.
199.     def onclick(self,event):
200.         if event.inaxes == self.ax:
201.             global cv
202.             lowest_dist = 1000
203.             lowest_index = -1
204.             for i in range(0, cv.shape[0]):
205.                 dist = np.sqrt((cv[i,0]-event.xdata)**2 + (cv[i,1]-event.ydata)**2)
206.                 if dist < lowest_dist:
207.                     lowest_dist = dist
208.                     lowest_index = i
209.             if event.button == self.button:
210.                 if lowest_dist > 1:
211.                     cv = np.vstack((np.array([event.xdata, event.ydata, 4.]),cv))
212.
213.                     # Get Centre
214.                     print(cv[0,:])
215.                     print(cv[1,:])
216.                     center_x = (cv[0,0] + cv[1,0])/2
217.                     center_y = (cv[0,1] + cv[1,1])/2
218.                     print(center_x, center_y)
219.                     cv[-2,0] = center_x
220.                     cv[-2,1] = center_y
221.             if event.button == 3:
222.
223.                 if lowest_dist < 1:
224.                     cv = np.delete(cv, (lowest_index), axis=0)
225.
226.     def onpress(self,event):
227.         self.press=True
228.     def onmove(self,event):
229.         if self.press:
230.             self.move=True
231.
232.             # Find the closest point to the click
233.             global cv
234.             lowest_dist = 1000
235.             lowest_index = -1
236.             for i in range(0, cv.shape[0]):
237.                 dist = np.sqrt((cv[i,0]-event.xdata)**2 + (cv[i,1]-event.ydata)**2)
238.                 if dist < lowest_dist:
239.                     lowest_dist = dist
240.                     lowest_index = i
241.             if lowest_dist < 2:
242.                 cv[lowest_index, 0] = event.xdata
243.                 cv[lowest_index, 1] = event.ydata
244.                 print(lowest_index)
245.
246.             print(cv)
247.
248.     def onrelease(self,event):
249.         if self.press and not self.move:
250.             self.onclick(event)
251.         self.press=False; self.move=False
252.         #print("Release")
253.
254. if __name__ == "__main__":
255.     import matplotlib.pyplot as plt
256.     first_run = True
257.     click  = None
258.
259.     axes = plt.gca()
260.
261.     bspline = BSpline()
262.
263.     def test(closed):
264.         global click
265.         global first_run
266.         global cv
267.
268.         cvT = cv.T
269.         ax2 = plt.gca()
270.         spline = bspline.process(cvT[0],cvT[1],cvT[2],ax2)
271.         # plt.plot(x,y,'k-',label='Curve')
272.         plt.minorticks_on()
273.         plt.legend()
274.         plt.xlabel('x')
275.         plt.ylabel('y')
276.         plt.xlim(-7, 7)
277.         plt.ylim(0, 10)