diff --git a/src/msspec/msspecgui/msspec/gui/clusterviewer.py b/src/msspec/msspecgui/msspec/gui/clusterviewer.py index b1b16b6..52917ad 100644 --- a/src/msspec/msspecgui/msspec/gui/clusterviewer.py +++ b/src/msspec/msspecgui/msspec/gui/clusterviewer.py @@ -26,7 +26,7 @@ class ClusterViewer(wx.Window): MODE_SELECTION_TOGGLE = 0b0001000 MODE_TRANSLATION = 0b0010000 MODE_ROTATION = 0b0100000 - + def __init__(self, *args, **kwargs): kwargs['style'] = wx.NO_FULL_REPAINT_ON_RESIZE | wx.CLIP_CHILDREN wx.Window.__init__(self, *args, **kwargs) @@ -108,7 +108,7 @@ class ClusterViewer(wx.Window): This will translate the model to the center of mass, move the model center to the center of screen and adjust the scale to the largest dimension of the model - + :param rescale: if True, the zoom is computed to view the atoms; if False, a fixed zoom value is used """ if atoms is None: @@ -160,7 +160,7 @@ class ClusterViewer(wx.Window): n_mat[0, 0] = n_mat[2, 2] = np.cos(np.radians(ty)) n_mat[0, 2] = -np.sin(np.radians(ty)) n_mat[2, 0] = np.sin(np.radians(ty)) - + self.rotation_matrix = np.dot(m_mat, n_mat) self.update_model_matrix() self.scale_atoms(self.scale) @@ -281,7 +281,7 @@ class ClusterViewer(wx.Window): if self.mode == self.MODE_TRANSLATION: self.mode ^= self.MODE_TRANSLATION - + self.update_drawing(light=False) def __evt_right_up_cb(self, event): @@ -478,7 +478,7 @@ class ClusterViewer(wx.Window): def create_background_sprite(self, w, h): surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h) ctx = cairo.Context(surface) - + if True: # pylint: disable=using-constant-test g = cairo.LinearGradient(0, 0, 0, h) g.add_color_stop_rgba(0.0, 1.0, 1.0, 1.0, 1.0) @@ -522,15 +522,15 @@ class ClusterViewer(wx.Window): ctx.restore() self.background_sprite = surface - + @classmethod def create_v2p_matrix(cls, left, right, bottom, top, near, far): """ creates the matrix that transforms coordinates from view space (space defined by the bounding box passed as argument) to projection space - + this transformation is a scale and offset that maps [left; right], [bottom; top], [near; far] to [-1;1], [-1;1], [0;1] """ - v2p_matrix = np.eye(4) + v2p_matrix = np.eye(4) * -1 v2p_matrix[0, 0] = 2. / (right - left) v2p_matrix[1, 1] = 2. / (right - left) v2p_matrix[2, 2] = 1. / (near - far) @@ -612,19 +612,23 @@ class ClusterViewer(wx.Window): d = 20 offset = 12 - origin = np.array([0, 0, 0, 1]) # @UnusedVariable - x_axis = np.array([d, 0, 0, 1]) - y_axis = np.array([0, d, 0, 1]) - z_axis = np.array([0, 0, d, 1]) + points = np.array([[d, 0, 0, 1, 0], + [0, d, 0, 1, 1], + [0, 0, d, 1, 2]]) - # translation = np.array([[1, 0, 0, d + offset], # @UnusedVariable - # [0, 1, 0, h - offset], - # [0, 0, 1, 1 ], - # [0, 0, 0, 1 ]]) + # project onto viewport + projections = np.dot(points[:, :4], m_matrix) + projections /= projections[:, -1, None] + # add the other columns + projections = np.c_[projections, points[:, 4:]] + # and sort by Z + projections = projections[projections[:,2].argsort()[::-1]] red = (1, 0, 0) green = (0, 0.7, 0) blue = (0, 0, 1) + colors = (red, green, blue) + labels = ('X', 'Y', 'Z') # draw a white circle so = np.array([d + offset, h - d - offset, 0]) @@ -637,19 +641,17 @@ class ClusterViewer(wx.Window): ctx.set_source_rgba(0.95, 0.95, 0.95, 1) ctx.fill() - for axis, color, label in ((x_axis, red, 'X'), - (y_axis, green, 'Y'), - (z_axis, blue, 'Z')): - axis = np.dot(axis, m_matrix) - axis /= axis[-1] + for x, y, z, w, n in projections: + n = int(n) ctx.move_to(*so[:2]) - ctx.rel_line_to(*axis[:2]) - ctx.set_source_rgb(*color) + ctx.rel_line_to(x, y) + ctx.set_source_rgb(*colors[n]) ctx.set_line_width(2) ctx.set_font_size(10) - ctx.show_text(label) + ctx.show_text(labels[n]) ctx.stroke() + def render_atoms(self, ctx): try: atoms = self.atoms @@ -732,7 +734,7 @@ class ClusterViewer(wx.Window): ctx.set_source_rgb(0, 0, 0) ctx.set_font_size(14) ctx.show_text("%d" % index) - + # save the rendering self.atoms_sprite = surface ctx.set_source_surface(surface, self.im_ox, self.im_oy) @@ -869,7 +871,7 @@ class ClusterViewer(wx.Window): #print "scale = ", self.scale, "scale0 = ", self.scale0 #self.scale_atoms(1.) - + if center: self.translate_atoms(w / 2, h / 2)