def _mouse_motion(self, event): """Handler for mouse motion""" if self._button1 or self._button2: dx = event.x - self._event_xy[0] dy = event.y - self._event_xy[1] self._event_xy = (event.x, event.y) if self._button1: #rotate or move vertex if self._ind is not None: poly = self.active_poly self.update_curve(dx, dy) self.draw_curves() return if self._shift: ax_LR = self._ax_LR_alt else: ax_LR = self._ax_LR rot1 = Quaternion.from_v_theta(self._ax_UD, self._step_UD * dy) rot2 = Quaternion.from_v_theta(ax_LR, self._step_LR * dx) self.rotate(rot1 * rot2) self.draw_curves() if self._button2: if self._shift: #translate self.translate(dx / self.slower, dy / self.slower) self.draw_curves() else: #zoom factor = 1 - 0.003 * (dx + dy) xlim = self.get_xlim() ylim = self.get_ylim() self.set_xlim(factor * xlim[0], factor * xlim[1]) self.set_ylim(factor * ylim[0], factor * ylim[1]) self.figure.canvas.draw()
def __init__(self, fig, sections, xkcd, is_3d=False, *args, **kwargs): super(DrawCurveInteractive, self).__init__(fig, sections_=sections, xkcd=False, is_3d=False, *args, **kwargs) self.current_curve = 0 self.optimization_curve = self.current_curve self._do_optimization = False self.pick_tol = 5 self.slow = 15. self.slower = 20. self._ind = None self.active_poly = None self._start_trans_x = 0. self._start_trans_y = 0. self._start_rot = Quaternion.from_v_theta((1, -1, 0), -np.pi / 6) # define axes for Up/Down motion and Left/Right motion self._ax_LR = (0, -1, 0) #Left Right self._ax_LR_alt = (0, 0, 1) self._step_LR = 0.01 self._ax_UD = (1, 0, 0) #Up Down self._step_UD = 0.01 self._active = False # true when mouse is over axes self._button1 = False # true when button 1 is pressed self._button2 = False # true when button 2 is pressed self._button3 = False # true when button 2 is pressed self._event_xy = None # store xy position of mouse event self._shift = False # shift key pressed self._current_trans_x = self._start_trans_x self._current_trans_y = self._start_trans_y self._current_rot = self._start_rot # connect some GUI events self.figure.canvas.mpl_connect('key_press_event', self._key_press) #self.figure.canvas.mpl_connect('pick_event', # self.on_pick_which) self.figure.canvas.mpl_connect('button_press_event', self._mouse_press) self.figure.canvas.mpl_connect('button_release_event', self._mouse_release) self.figure.canvas.mpl_connect('motion_notify_event', self._mouse_motion) self.figure.canvas.mpl_connect('key_release_event', self._key_release) self.zoom = self.zoom_factory(base_scale=3.0) #self.figure.canvas.mpl_connect('scroll_event',self.zoom_factory()) #self.figure.text(0.05, 0.15, ("Click and Drag to Move\n" # "Hold shift key to adjust rotation, etc.")) #self.figure.text(0.05, 0.05, ("Right click to zoom\n" # "shift right click to pan")) self.figure.text(0.05, 0.05, ("UNO Naval Architecture"))
def animate(j): q = quat[:, j] angle = 2 * np.arccos(q[0]) # catch when dividing by 0 because of angle if (q[0] == 1.): axis = (0, 0, 1) else: axis = tuple(q[1:] / np.sqrt(1 - (q[0]**2))) current_rot = Quaternion.from_v_theta(axis, angle) Rs_x = [(current_rot * rot).as_rotation_matrix() for rot in rots_x] Rs_y = [(current_rot * rot).as_rotation_matrix() for rot in rots_y] Rs_z = [(current_rot * rot).as_rotation_matrix() for rot in rots_z] faces_x = [np.dot(x_face, R.T) for R in Rs_y] faces_y = [np.dot(y_face, R.T) for R in Rs_z] faces_z = [np.dot(z_face, R.T) for R in Rs_x] faces_proj_x = [face[:, :2] for face in faces_x] faces_proj_y = [face[:, :2] for face in faces_y] faces_proj_z = [face[:, :2] for face in faces_z] zorder_x = [face[:4, 2].sum() for face in faces_x] zorder_y = [face[:4, 2].sum() for face in faces_y] zorder_z = [face[:4, 2].sum() for face in faces_z] for i in range(2): polys[i].set_xy(faces_proj_x[i]) polys[i].set_zorder(zorder_x[i]) polys[i + 2].set_xy(faces_proj_y[i]) polys[i + 2].set_zorder(zorder_y[i]) polys[i + 4].set_xy(faces_proj_z[i]) polys[i + 4].set_zorder(zorder_z[i]) time_text.set_text('frame = %.1f' % j) return tuple(polys), time_text
time_text = ax.text(0.02, 0.95, '', transform=ax.transAxes) d = loadmat('Data/quat_test.mat') quat = d['quat'] # we want three kinds of faces z_face = np.array([[2, 0.2, 1], [2, -0.2, 1], [-2, -0.2, 1], [-2, 0.2, 1], [2, 0.2, 1]]) x_face = np.array([[2, 0.2, -1], [2, -0.2, -1], [2, -0.2, 1], [2, 0.2, 1], [2, 0.2, -1]]) y_face = np.array([[2, 0.2, -1], [2, 0.2, 1], [-2, 0.2, 1], [-2, 0.2, -1], [2, 0.2, -1]]) # and reflections about the three axes x, y, z = np.eye(3) rots_x = [Quaternion.from_v_theta(x, theta) for theta in (np.pi, 0)] rots_y = [Quaternion.from_v_theta(y, theta) for theta in (np.pi, 0)] rots_z = [Quaternion.from_v_theta(z, theta) for theta in (np.pi, 0)] colors = ['blue', 'green', 'black', 'yellow', 'orange', 'red'] current_rot = Quaternion.from_v_theta((1, 0, 0), 0.01) #can be whatever Rs_x = [(current_rot * rot).as_rotation_matrix() for rot in rots_x] Rs_y = [(current_rot * rot).as_rotation_matrix() for rot in rots_y] Rs_z = [(current_rot * rot).as_rotation_matrix() for rot in rots_z] faces_x = [np.dot(x_face, R.T) for R in Rs_y] faces_y = [np.dot(y_face, R.T) for R in Rs_z] faces_z = [np.dot(z_face, R.T) for R in Rs_x]
def rotate_curve(): rt = np.sqrt(2.) / 2. _current_rot = Quaternion.from_v_theta((rt, 0., rt), 0.) return
def __init__(self, fig, rect=[0, 0, 1, 1], sections_=None, xkcd=False, is_3d=False, *args, **kwargs): if xkcd: plt.xkcd() real_faces = None sections = sections_.sections bow_id = sections_.bow_id for key in sections: if key == bow_id: if real_faces is None: cv, vt = self.get_bow(sections[key]) real_faces = [cv] vertices = [vt] else: cv, vt = self.get_bow(sections[key]) real_faces.append(cv) vertices.append(vt) else: if real_faces is None: cv, vt = self.get_curve(sections[key]) if len(np.unique(vt[:,0]))==1 or \ len(np.unique(vt[:,1]))==1 or \ len(np.unique(vt[:,2]))==1 : real_faces = [cv] vertices = [vt] else: cv, vt = self.get_curve(sections[key]) if len(np.unique(vt[:,0]))==1 or \ len(np.unique(vt[:,1]))==1 or \ len(np.unique(vt[:,2]))==1 : real_faces.append(cv) vertices.append(vt) self.hull_frame = sections_ self.real_faces = real_faces self.vertices = vertices self.colors = [ 'green', 'blue', 'green', 'white', 'yellow', 'orange', 'red', 'grey' ] self._show_curvature = False x, y, z = np.identity(3) kwargs.update( dict(xlim=(-25., 25.), ylim=(-25., 25.), frameon=True, xticks=[], yticks=[], aspect='equal')) super(DrawCurve, self).__init__(fig, rect, *args, **kwargs) self.rots = Quaternion.from_v_theta(x, 0.) self.xaxis.set_major_formatter(plt.NullFormatter()) self.yaxis.set_major_formatter(plt.NullFormatter()) self.nfaces = len(real_faces) # define the current rotation axis and angle self._current_rot = Quaternion.from_v_theta((1., 0., 0.), 0.)
) * pt * Qrotor #matches Rs - in w,(x,y,z) form. Note as_v_theta does not quite! c = self._current_rot * self.rots * pt * self.rots.conjugate( ) * self._current_rot.conjugate() print a print a.as_v_theta()[0] print b.as_v_theta()[0] #order matters! b1 = Qrotor.conjugate() b2 = Qrotor * pt b3 = b2 * b1 #http://stackoverflow.com/questions/4870393/rotating-coordinate-system-via-a-quaternion x_axis_unit = (1, 0, 0) y_axis_unit = (0, 1, 0) z_axis_unit = (0, 0, 1) theta = np.pi / 2. r1 = Quaternion.from_v_theta(x_axis_unit, theta) r2 = Quaternion.from_v_theta(y_axis_unit, theta) r3 = Quaternion.from_v_theta(z_axis_unit, theta) v = r1 * np.asarray( y_axis_unit) * r2.conjugate() * r3.conjugate() v.as_v_theta() v = r3 * r2 * r1 * np.asarray(y_axis_unit) * r1.conjugate( ) * r2.conjugate() * r3.conjugate() print v.as_v_theta() # output: (4.930380657631324e-32, 2.220446049250313e-16, -1.0), theta v = r3 * r2 * r1 * np.asarray(x_axis_unit) * r1.conjugate( ) * r2.conjugate() * r3.conjugate() print v.as_v_theta()