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')
  111.            self.ax.add_patch(rect)
  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)
  278.         #plt.gca().set_aspect('equal', adjustable='box-forced')
  279.         plt.pause(0.005)
  280.         plt.cla()
  281.  
  282.         if(first_run):
  283.             first_run = False
  284.             click = Click(ax2, button=1)
  285.  
  286.     while 1:
  287.         test(False)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top