diff --git a/src/laplace/laplace_plot.py b/src/laplace/laplace_plot.py index 41abc00cd193d30a39bac078135b54761a9c00d1..57ee12b99ce859ce9efdc65a72de424f1fc4c87c 100644 --- a/src/laplace/laplace_plot.py +++ b/src/laplace/laplace_plot.py @@ -25,7 +25,7 @@ class pzPoint(): def clear(self): if self.h_point is not None: self.h_point.remove(); self.h_point = None if self.h_point_conj is not None: self.h_point_conj.remove(); self.h_point_conj = None - if self.h_order is not None: self.h_order.remove(); self.h_order = None + if self.h_order is not None: self.h_order[0].remove(); self.h_order[1].remove(); self.h_order = None class pzPlot(): @@ -106,26 +106,84 @@ class pzPlot(): self.ax.set_title('Pol- /Nullstellen Diagramm', fontsize='12') self.ax.set_aspect('equal', adjustable='datalim') - def onclick(event): - if self.action == 'add' and event.key == 'shift': - self.action = 'del' + # * move indicates whether a drag is happening + # * selected_coords indicates selected coords when button is pressed + # * ghost_hpoint, ghost_hpoint_conj are the half transparent poles/zeroes to indicate where the newly created will be + self.move = False + self.selected_coords = None + self.ghost_hpoint = None + self.ghost_hpoint_conj = None + def on_btn_press(event): if event.inaxes != self.ax: return if self.filter != 'man': return - p = event.xdata + 1j * event.ydata - self.update_point(p, self.mode) - def onkeypress(event): - self.action_locked = True if self.action == 'del' else False - self.w_action_type.children[0].value = 'Löschen' + # button press, reset move + self.move = False - def onkeyrelease(event): - if not self.action_locked: - self.w_action_type.children[0].value = 'Hinzufügen' + # find closest point and set selected if there are any valid points nearby + p = event.xdata + 1j * event.ydata + self.selected_coords = p + + def on_btn_release(event): + # press + no movement + release = click + if not self.move: + on_click(event) + + # press + movement + release = drag + # if dragging process is finished + if self.move and self.find_closest_point(self.selected_coords, self.mode)[0] is not None: + # release move + self.move = False + + # remove any ghosts from the figure and clear variables + if self.ghost_hpoint is not None: + self.ghost_hpoint.remove() + self.ghost_hpoint_conj.remove() + self.ghost_hpoint = None + self.ghost_hpoint_conj = None + + # delete at press selected point + tmp_action = self.action + self.action = 'del' + self.update_point(self.selected_coords, self.mode) + + # add new point at drag point + self.action = 'add' + on_click(event) + self.action = tmp_action + + def on_motion(event): + # if button is pressed + if event.button == 1: + # lock move + self.move = True + + # if a point was selected + if self.find_closest_point(self.selected_coords, self.mode)[0] is not None: + if self.ghost_hpoint is None: + # draw ghost point + if self.mode == 'p': + plotstyle = rwth_plots.style_poles + else: + plotstyle = rwth_plots.style_zeros + + self.ghost_hpoint, = self.ax.plot(event.xdata, event.ydata, **plotstyle, alpha=.5) + + if np.abs(event.ydata) > 0: # plot complex conjugated poles/zeroes + self.ghost_hpoint_conj, = self.ax.plot(event.xdata, -event.ydata, **plotstyle, alpha=.5) + else: + self.ghost_hpoint.set_data(event.xdata, event.ydata) + self.ghost_hpoint_conj.set_data(event.xdata, -event.ydata) + + def on_click(event): + # update point + p = event.xdata + 1j * event.ydata + self.update_point(p, self.mode) - self.fig.canvas.mpl_connect('button_press_event', onclick) - self.fig.canvas.mpl_connect('key_press_event', onkeypress) - self.fig.canvas.mpl_connect('key_release_event', onkeyrelease) + self.fig.canvas.mpl_connect('button_press_event', on_btn_press) + self.fig.canvas.mpl_connect('button_release_event', on_btn_release) + self.fig.canvas.mpl_connect('motion_notify_event', on_motion) self.handles['axh'] = plt.subplot(gs[0, 1]) self.handles['axh'].set_title('Impulsantwort', fontsize='12') diff --git a/src/z_transform/z_transform.py b/src/z_transform/z_transform.py index 9d3f42ea5c5377bca265ad4591d867a464fc480a..047bfc8c686eb3dc41cda4b0fc60ed72c78b5ff1 100644 --- a/src/z_transform/z_transform.py +++ b/src/z_transform/z_transform.py @@ -25,7 +25,7 @@ class pzPoint(): def clear(self): if self.h_point is not None: self.h_point.remove(); self.h_point = None if self.h_point_conj is not None: self.h_point_conj.remove(); self.h_point_conj = None - if self.h_order is not None: self.h_order.remove(); self.h_order = None + if self.h_order is not None: self.h_order[0].remove(); self.h_order[1].remove(); self.h_order = None class zPlot(): @@ -103,26 +103,87 @@ class zPlot(): self.ax.set_title('Pol- /Nullstellen Diagramm', fontsize='12') self.ax.set_aspect('equal') - def onclick(event): - if self.action == 'add' and event.key == 'shift': - self.action = 'del' + # * move indicates whether a drag is happening + # * selected_coords indicates selected coords when button is pressed + # * ghost_hpoint, ghost_hpoint_conj are the half transparent poles/zeroes to indicate where the newly created will be + self.move = False + self.selected_coords = None + self.ghost_hpoint = None + self.ghost_hpoint_conj = None + def on_btn_press(event): if event.inaxes != self.ax: return if self.filter != 'man': return + + # button press, reset move + self.move = False + + # find closest point and set selected if there are any valid points nearby p = event.xdata + 1j * event.ydata - self.update_point(p, self.mode) + self.selected_coords = p + + def on_btn_release(event): + # press + no movement + release = click + if not self.move: + on_click(event) + + # press + movement + release = drag + # if dragging process is finished + if self.move and self.find_closest_point(self.selected_coords, self.mode)[0] is not None: + # release move + self.move = False + + # remove any ghosts from the figure and clear variables + if self.ghost_hpoint is not None: + self.ghost_hpoint.remove() + self.ghost_hpoint_conj.remove() + self.ghost_hpoint = None + self.ghost_hpoint_conj = None + + # delete at press selected point + tmp_action = self.action + self.action = 'del' + self.update_point(self.selected_coords, self.mode) + + # add new point at drag point + self.action = 'add' + on_click(event) + self.action = tmp_action + + def on_motion(event): + # if button is pressed + if event.button == 1: + # lock move + self.move = True + + # if a point was selected + if self.find_closest_point(self.selected_coords, self.mode)[0] is not None: + if self.ghost_hpoint is None: + # draw ghost point + if self.mode == 'p': + plotstyle = rwth_plots.style_poles + else: + plotstyle = rwth_plots.style_zeros + + self.ghost_hpoint, = self.ax.plot(event.xdata, event.ydata, **plotstyle, alpha=.5) + + if np.abs(event.ydata) > 0: # plot complex conjugated poles/zeroes + self.ghost_hpoint_conj, = self.ax.plot(event.xdata, -event.ydata, **plotstyle, alpha=.5) + else: + self.ghost_hpoint.set_data(event.xdata, event.ydata) + self.ghost_hpoint_conj.set_data(event.xdata, -event.ydata) - def onkeypress(event): - self.action_locked = self.action == 'del' - self.w_action_type.children[0].value = 'Löschen' + def on_click(event): + if self.filter != 'man': return + if event.inaxes != self.ax: return - def onkeyrelease(event): - if not self.action_locked: - self.w_action_type.children[0].value = 'Hinzufügen' + # update point + p = event.xdata + 1j * event.ydata + self.update_point(p, self.mode) - self.fig.canvas.mpl_connect('button_press_event', onclick) - self.fig.canvas.mpl_connect('key_press_event', onkeypress) - self.fig.canvas.mpl_connect('key_release_event', onkeyrelease) + self.fig.canvas.mpl_connect('button_press_event', on_btn_press) + self.fig.canvas.mpl_connect('button_release_event', on_btn_release) + self.fig.canvas.mpl_connect('motion_notify_event', on_motion) self.handles['axh'] = plt.subplot(gs[0, 1]) self.handles['axh'].set_xlim(-15, 15);