コード例 #1
0
    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:
                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_cube()

            if self._button2:
                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()
コード例 #2
0
    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:
                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_cube()

            if self._button2:
                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()
コード例 #3
0
ファイル: cube_interactive.py プロジェクト: maugl/MagicCube
    def _key_press(self, event):
        """Handler for key press events"""
        stickers_to_color = list()
        if event.key == 'shift':
            self._shift = True
        elif event.key.isdigit():
            self._digit_flags[int(event.key)] = 1
        elif event.key == 'right':
            if self._shift:
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR,
                                                5 * self._step_LR))
        elif event.key == 'left':
            if self._shift:
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR,
                                                -5 * self._step_LR))
        elif event.key == 'up':
            self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                                5 * self._step_UD))
        elif event.key == 'down':
            self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                                -5 * self._step_UD))
        elif event.key.upper() in 'LRUDBF':
            if self._shift:
                direction = -1
            else:
                direction = 1

            # max
            dir_word = "cw" if direction == 1 else "ccw"

            if np.any(self._digit_flags[:N]):
                for d in np.arange(N)[self._digit_flags[:N]]:
                    self.rotate_face(event.key.upper(), direction, layer=d)
                    # max
                    self.cube.wc.make_move(face=event.key.upper(), layer=d, direction=dir_word)
                    stickers_to_color = self.cube.wc.check_cube()
            else:
                self.rotate_face(event.key.upper(), direction)
                # max
                self.cube.wc.make_move(face=event.key.upper(), direction=dir_word, layer=0)
                stickers_to_color = self.cube.wc.check_cube()

            print(self.cube.wc)
            print(stickers_to_color)
            if len(self.stickers_to_color_old) > 0:
                for i in self.stickers_to_color_old:
                    self._text_annotations[i].set_color("black")
            for i in stickers_to_color:
                self._text_annotations[i].set_color("r")
            self.stickers_to_color_old = stickers_to_color

        self._draw_cube()
コード例 #4
0
ファイル: axes3d.py プロジェクト: AxiomOfChoice1/NNCube
def cube_axes(N=1, **kwargs):
    """Create an N x N x N rubiks cube

    kwargs are passed to the PolyView3D instance.
    """
    stickerwidth = 0.9
    small = 0.5 * (1. - stickerwidth)
    d1 = 1 - small
    d2 = 1 - 2 * small
    d3 = 1.01
    base_sticker = np.array([[d1, d2, d3], [d2, d1, d3], [-d2, d1, d3],
                             [-d1, d2, d3], [-d1, -d2, d3], [-d2, -d1, d3],
                             [d2, -d1, d3], [d1, -d2, d3], [d1, d2, d3]],
                            dtype=float)

    base_face = np.array(
        [[1, 1, 1], [1, -1, 1], [-1, -1, 1], [-1, 1, 1], [1, 1, 1]],
        dtype=float)

    x, y, z = np.eye(3)
    rots = [
        Quaternion.from_v_theta(x, theta) for theta in (np.pi / 2, -np.pi / 2)
    ]
    rots += [
        Quaternion.from_v_theta(y, theta)
        for theta in (np.pi / 2, -np.pi / 2, np.pi, 2 * np.pi)
    ]

    cubie_width = 2. / N
    translations = np.array(
        [[-1 + (i + 0.5) * cubie_width, -1 + (j + 0.5) * cubie_width, 0]
         for i in range(N) for j in range(N)])

    colors = ['blue', 'green', 'white', 'yellow', 'orange', 'red']

    factor = np.array([1. / N, 1. / N, 1])

    ax = PolyView3D(**kwargs)
    facecolor = []
    polys = []

    for t in translations:
        base_face_trans = factor * base_face + t
        base_sticker_trans = factor * base_sticker + t
        for r, c in zip(rots, colors):
            polys += [r.rotate(base_face_trans), r.rotate(base_sticker_trans)]
            facecolor += ['k', c]

    ax.poly3D_batch(polys, facecolor=facecolor)

    ax.figure.text(0.05,
                   0.05,
                   ("Drag Mouse or use arrow keys to change perspective.\n"
                    "Hold shift to adjust z-axis rotation"),
                   ha='left',
                   va='bottom')
    return ax
コード例 #5
0
class Cube(object):
    """An Axes for displaying a 3D cube"""
    # fiducial face is perpendicular to z at z=+1
    one_face = np.array([[1, 1, 1], [1, -1, 1], [-1, -1, 1], [-1, 1, 1],
                         [1, 1, 1]])

    # Construct six rotators for the cube faces. These will take a single
    # fiducial face, and rotate it to the appropriate 3D location.
    x, y, z = np.eye(3)
    _rots = [
        Quaternion.from_v_theta(x, theta) for theta in (np.pi / 2, -np.pi / 2)
    ]
    _rots += [
        Quaternion.from_v_theta(y, theta)
        for theta in (np.pi / 2, -np.pi / 2, np.pi, 2 * np.pi)
    ]
    _faces = np.array(
        [np.dot(one_face,
                rot.as_rotation_matrix().T) for rot in _rots])

    def __init__(self, view=(0, 0, 10), colors=None, alpha=0.8):
        self.view = view
        self.current_rotation = Quaternion.from_v_theta((0, 0, 1), 0)

        if colors is None:
            colors = ['blue', 'green', 'white', 'yellow', 'orange', 'red']
        else:
            assert len(colors) == 6

        self.polys = [
            plt.Polygon(self._faces[i, :, :2],
                        facecolor=colors[i],
                        alpha=alpha) for i in range(6)
        ]

    def rotate(self, v, theta):
        new_rot = Quaternion.from_v_theta(v, theta)
        self.current_rotation = self.current_rotation * new_rot

        faces_proj = project_points(self._faces, self.current_rotation,
                                    self.view)
        xy = faces_proj[:, :, :2]
        zorder = -faces_proj[:, :4, 2].mean(-1)

        for i in range(6):
            self.polys[i].set_xy(xy[i])
            self.polys[i].set_zorder(zorder[i])

    def set_view(self, view):
        self.view = view
        self.rotate(self.z, 0)

    def add_to_ax(self, ax):
        for poly in self.polys:
            ax.add_patch(poly)
        ax.set_xlim(-3, 3)
        ax.set_ylim(-3, 3)
コード例 #6
0
ファイル: axes3d.py プロジェクト: amshenoy/MagicCube
def cube_axes(N=1, **kwargs):
    """Create an N x N x N rubiks cube

    kwargs are passed to the PolyView3D instance.
    """
    stickerwidth = 0.9
    small = 0.5 * (1. - stickerwidth)
    d1 = 1 - small
    d2 = 1 - 2 * small
    d3 = 1.01
    base_sticker = np.array([[d1, d2, d3], [d2, d1, d3],
                             [-d2, d1, d3], [-d1, d2, d3],
                             [-d1, -d2, d3], [-d2, -d1, d3],
                             [d2, -d1, d3], [d1, -d2, d3],
                             [d1, d2, d3]], dtype=float)

    base_face = np.array([[1, 1, 1],
                          [1, -1, 1],
                          [-1, -1, 1],
                          [-1, 1, 1],
                          [1, 1, 1]], dtype=float)

    x, y, z = np.eye(3)
    rots = [Quaternion.from_v_theta(x, theta)
            for theta in (np.pi / 2, -np.pi / 2)]
    rots += [Quaternion.from_v_theta(y, theta)
             for theta in (np.pi / 2, -np.pi / 2, np.pi, 2 * np.pi)]

    cubie_width = 2. / N
    translations = np.array([[-1 + (i + 0.5) * cubie_width,
                              -1 + (j + 0.5) * cubie_width, 0]
                             for i in range(N) for j in range(N)])

    colors = ['blue', 'green', 'white', 'yellow', 'orange', 'red']

    factor = np.array([1. / N, 1. / N, 1])

    ax = PolyView3D(**kwargs)
    facecolor = []
    polys = []

    for t in translations:
        base_face_trans = factor * base_face + t
        base_sticker_trans = factor * base_sticker + t
        for r, c in zip(rots, colors):
            polys += [r.rotate(base_face_trans),
                      r.rotate(base_sticker_trans)]
            facecolor += ['k', c]

    ax.poly3D_batch(polys, facecolor=facecolor)

    ax.figure.text(0.05, 0.05,
                   ("Drag Mouse or use arrow keys to change perspective.\n"
                    "Hold shift to adjust z-axis rotation"),
                   ha='left', va='bottom')
    return ax
コード例 #7
0
    def _key_press(self, event):
        """Handler for key press events"""
        if event.key == 'shift':
            self._shift = True
        elif event.key.isdigit():
            self._digit_flags[int(event.key)] = 1
        elif event.key == 'right':
            if self._shift:
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR,
                                                5 * self._step_LR))
        elif event.key == 'left':
            if self._shift:
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR,
                                                -5 * self._step_LR))
        elif event.key == 'up':
            self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                                5 * self._step_UD))
        elif event.key == 'down':
            self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                                -5 * self._step_UD))
        elif event.key.upper() in 'LRUDBF':
            if self._shift:
                direction = -1
            else:
                direction = 1



            if np.any(self._digit_flags[:self.cube.N]):
                for d in solvesolve.arange(self.cube.N)[self._digit_flags[:self.cube.N]]:
                    self.rotate_face(event.key.upper(), direction, layer=d)

                    if direction == 1:
                        self._pycuber_rep((event.key.upper()))
                    elif direction == -1:
                        self._pycuber_rep((event.key.upper()+"'"))

            else:
                self.rotate_face(event.key.upper(), direction)
                if direction == 1:
                    self._pycuber_rep((event.key.upper()))
                elif direction == -1:
                    self._pycuber_rep((event.key.upper()+"'"))

        self._draw_cube()
コード例 #8
0
 def rotate_event(self, direction, stepsize):
     if direction == 'right':
         self.rotate(Quaternion.from_v_theta(self._ax_LR,
                                             stepsize * self._step_LR))
     elif direction == 'left':
         self.rotate(Quaternion.from_v_theta(self._ax_LR,
                                             -stepsize * self._step_LR))
     elif direction == 'up':
         self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                             stepsize * self._step_UD))
     elif direction == 'down':
         self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                             -stepsize * self._step_UD))
     self._draw_cube()
コード例 #9
0
 def rotate_event(self, direction, stepsize):
     if direction == 'right':
         self.rotate(
             Quaternion.from_v_theta(self._ax_LR, stepsize * self._step_LR))
     elif direction == 'left':
         self.rotate(
             Quaternion.from_v_theta(self._ax_LR,
                                     -stepsize * self._step_LR))
     elif direction == 'up':
         self.rotate(
             Quaternion.from_v_theta(self._ax_UD, stepsize * self._step_UD))
     elif direction == 'down':
         self.rotate(
             Quaternion.from_v_theta(self._ax_UD,
                                     -stepsize * self._step_UD))
     self._draw_cube()
コード例 #10
0
    def rotate_face(self, f, n=1, layer=0):
        """Rotate Face"""
        if layer < 0 or layer >= self.N:
            raise ValueError('layer should be between 0 and N-1')

        try:
            f_last, n_last, layer_last = self._move_list[-1]
        except:
            f_last, n_last, layer_last = None, None, None

        if (f == f_last) and (layer == layer_last):
            ntot = (n_last + n) % 4
            if abs(ntot - 4) < abs(ntot):
                ntot = ntot - 4
            if np.allclose(ntot, 0):
                self._move_list = self._move_list[:-1]
            else:
                self._move_list[-1] = (f, ntot, layer)
        else:
            self._move_list.append((f, n, layer))

        v = self.facesdict[f]
        r = Quaternion.from_v_theta(v, n * np.pi / 2)
        M = r.as_rotation_matrix()

        proj = np.dot(self._face_centroids[:, :3], v)
        cubie_width = 2. / self.N
        flag = ((proj > 0.9 - (layer + 1) * cubie_width) &
                (proj < 1.1 - layer * cubie_width))

        for x in [self._stickers, self._sticker_centroids, self._faces]:
            x[flag] = np.dot(x[flag], M.T)
        self._face_centroids[flag, :3] = np.dot(self._face_centroids[flag, :3],
                                                M.T)
コード例 #11
0
    def rotate_face(self, f, n=1, layer=0):
        """Rotate Face"""
        if layer < 0 or layer >= self.N:
            raise ValueError('layer should be between 0 and N-1')

        try:
            f_last, n_last, layer_last = self._move_list[-1]
        except:
            f_last, n_last, layer_last = None, None, None

        if (f == f_last) and (layer == layer_last):
            ntot = (n_last + n) % 4
            if abs(ntot - 4) < abs(ntot):
                ntot = ntot - 4
            if np.allclose(ntot, 0):
                self._move_list = self._move_list[:-1]
            else:
                self._move_list[-1] = (f, ntot, layer)
        else:
            self._move_list.append((f, n, layer))
        
        v = self.facesdict[f]
        r = Quaternion.from_v_theta(v, n * np.pi / 2)
        M = r.as_rotation_matrix()

        proj = np.dot(self._face_centroids[:, :3], v)
        cubie_width = 2. / self.N
        flag = ((proj > 0.9 - (layer + 1) * cubie_width) &
                (proj < 1.1 - layer * cubie_width))

        for x in [self._stickers, self._sticker_centroids,
                  self._faces]:
            x[flag] = np.dot(x[flag], M.T)
        self._face_centroids[flag, :3] = np.dot(self._face_centroids[flag, :3],
                                                M.T)
コード例 #12
0
ファイル: cube_interactive.py プロジェクト: johan--/rubik-1
    def _key_press(self, event):
        """Handler for key press events"""
        if not event.key:
            return 
        elif event.key == 'shift':
            self._shift = True
        elif event.key.isdigit():
            self._digit_flags[int(event.key)] = 1
        elif event.key == 'right':
            if self._shift:
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR,
                                                5 * self._step_LR))
        elif event.key == 'left':
            if self._shift:
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR,
                                                - 5 * self._step_LR))
        elif event.key == 'up':
            self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                                5 * self._step_UD))
        elif event.key == 'down':
            self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                                - 5 * self._step_UD))
        elif event.key.upper() in InteractiveCube.FACES:
            # if self._shift:
            if event.key in InteractiveCube.FACES:
                # Upper-case
                direction = -1
            else:
                # Lower-case
                direction = 1

            N = self.cube.N
            if np.any(self._digit_flags[:N]):
                for d in np.arange(N)[self._digit_flags[:N]]:
                    self.rotate_face(event.key.upper(), direction, layer=d)
            else:
                self.rotate_face(event.key.upper(), direction)
                
        self._draw_cube()
コード例 #13
0
ファイル: axes3d.py プロジェクト: amshenoy/MagicCube
    def _key_press(self, event):
        """Handler for key press events"""
        if event.key == 'shift':
            self._ax_LR = (0, 0, 1)

        elif event.key == 'right':
            self.rotate(Quaternion.from_v_theta(self._ax_LR,
                                                5 * self._step_LR))
        elif event.key == 'left':
            self.rotate(Quaternion.from_v_theta(self._ax_LR,
                                                -5 * self._step_LR))
        elif event.key == 'up':
            self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                                5 * self._step_UD))
        elif event.key == 'down':
            self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                                -5 * self._step_UD))
        self._update_projection()
コード例 #14
0
ファイル: axes3d.py プロジェクト: AxiomOfChoice1/NNCube
    def _key_press(self, event):
        """Handler for key press events"""
        if event.key == 'shift':
            self._ax_LR = (0, 0, 1)

        elif event.key == 'right':
            self.rotate(Quaternion.from_v_theta(self._ax_LR,
                                                5 * self._step_LR))
        elif event.key == 'left':
            self.rotate(
                Quaternion.from_v_theta(self._ax_LR, -5 * self._step_LR))
        elif event.key == 'up':
            self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                                5 * self._step_UD))
        elif event.key == 'down':
            self.rotate(
                Quaternion.from_v_theta(self._ax_UD, -5 * self._step_UD))
        self._update_projection()
コード例 #15
0
    def _key_press(self, event):
        """Handler for key press events"""
        #matplotlib does not detect shift events by itself
        if event.key.isdigit():
            self._digit_flags[int(event.key)] = 1
        elif event.key == 'right' or event.key == 'shift+right':
            if event.key == 'shift+right':
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR, 5 * self._step_LR))
        elif event.key == 'shift+left' or event.key == 'left':
            if event.key == 'shift+left':
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR, -5 * self._step_LR))
        elif event.key == 'up':
            self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                                5 * self._step_UD))
        elif event.key == 'down':
            self.rotate(
                Quaternion.from_v_theta(self._ax_UD, -5 * self._step_UD))
        elif event.key.upper() in 'LRUDBF':
            if event.key in 'LRUDBF':
                direction = -1
            else:
                direction = 1

            sanitizedMove = event.key.upper() + "" if direction == 1 else "'"
            if np.any(self._digit_flags[:self.cube.N]):
                for d in np.arange(
                        self.cube.N)[self._digit_flags[:self.cube.N]]:
                    self.rotate_face(event.key.upper(), direction, layer=d)
                    self._pycuber_rep(sanitizedMove)
            else:
                self.rotate_face(event.key.upper(), direction)
                self._pycuber_rep(sanitizedMove)

            self._moveList.append(sanitizedMove)

            print(str(self._moveList))
            self._printShuffleLabel(self._moveList)
            self._draw_cube()
コード例 #16
0
    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:
                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_cube()
                '''
                if self._figsave%10==0:
                    plt.savefig("images2/test"+str(self._figsave)+".jpg")
                    abcd = ["test"+str(self._figsave)+".jpg"]
                    # array([0.00834558, 0.00809627, 0.01133022, 0.01168023])
                    currot = [np.float(ab) for ab in (str(self._current_rot)[7:-2]).replace(" ","").split(",")]
                    abcd.extend(currot)
                    self._figquats.append(abcd)
                    print("Saved ",len(self._figquats))
                    if len(self._figquats) == 50:
                        print("Saving data to file..")
                        with open('quaternions2.csv', 'w', newline='') as file:
                            writer = csv.writer(file)
                            for quat in self._figquats:
                                writer.writerow(quat)
                self._figsave += 1
                '''
            if self._button2:
                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()
コード例 #17
0
 def _key_press(self, event):
     """Handler for key press events"""
     if event.key.isdigit():
         self._digit_flags[int(event.key)] = 1
     elif event.key == 'right':
         self.rotate(Quaternion.from_v_theta(self._ax_LR,
                                             5 * self._step_LR))
     elif event.key == 'left':
         self.rotate(
             Quaternion.from_v_theta(self._ax_LR, -5 * self._step_LR))
     elif event.key == 'up':
         self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                             5 * self._step_UD))
     elif event.key == 'down':
         self.rotate(
             Quaternion.from_v_theta(self._ax_UD, -5 * self._step_UD))
     elif event.key.upper() in 'URF':
         self.rotate_face(event.key.upper(), 1)
     self._draw_cube()
コード例 #18
0
    def rotate(self, v, theta):
        new_rot = Quaternion.from_v_theta(v, theta)
        self.current_rotation = self.current_rotation * new_rot

        faces_proj = project_points(self._faces, self.current_rotation,
                                    self.view)
        xy = faces_proj[:, :, :2]
        zorder = -faces_proj[:, :4, 2].mean(-1)

        for i in range(6):
            self.polys[i].set_xy(xy[i])
            self.polys[i].set_zorder(zorder[i])
コード例 #19
0
    def rotate(self, v, theta):
        new_rot = Quaternion.from_v_theta(v, theta)
        self.current_rotation = self.current_rotation * new_rot
        
        faces_proj = project_points(self._faces, self.current_rotation,
                                    self.view)
        xy = faces_proj[:, :, :2]
        zorder = -faces_proj[:, :4, 2].mean(-1)

        for i in range(6):
            self.polys[i].set_xy(xy[i])
            self.polys[i].set_zorder(zorder[i])
コード例 #20
0
    def _key_press(self, event):
        """Handler for key press events"""
        if event.key == 'shift':
            self._shift = True
        elif event.key.isdigit():
            self._digit_flags[int(event.key)] = 1
        elif event.key == 'right':
            if self._shift:
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR, 5 * self._step_LR))
        elif event.key == 'left':
            if self._shift:
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR, -5 * self._step_LR))
        elif event.key == 'up':
            self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                                5 * self._step_UD))
        elif event.key == 'down':
            self.rotate(
                Quaternion.from_v_theta(self._ax_UD, -5 * self._step_UD))
        elif event.key.upper() in 'LRUDBF':
            if self._shift:
                direction = -1  #Era -1
            else:
                direction = 1  #Era 1

            if np.any(self._digit_flags[:N]):
                for d in np.arange(N)[self._digit_flags[:N]]:
                    self.rotate_face(event.key.upper(), direction, layer=d)
            else:
                self.rotate_face(event.key.upper(), direction)
            self.deordering_movs.append(
                direction * (self.movList.index(event.key.upper()) + 1))
            #print("self.deordering_movs")
            #print(self.deordering_movs)
        self._draw_cube()
コード例 #21
0
    def __init__(self, view=(0, 0, 10), colors=None, alpha=0.8):
        self.view = view
        self.current_rotation = Quaternion.from_v_theta((0, 0, 1), 0)

        if colors is None:
            colors = ['blue', 'green', 'white', 'yellow', 'orange', 'red']
        else:
            assert len(colors) == 6

        self.polys = [plt.Polygon(self._faces[i, :, :2],
                                  facecolor=colors[i],
                                  alpha=alpha)
                      for i in range(6)]
コード例 #22
0
    def __init__(self, view=(0, 0, 10), colors=None, alpha=0.8):
        self.view = view
        self.current_rotation = Quaternion.from_v_theta((0, 0, 1), 0)

        if colors is None:
            colors = ['blue', 'green', 'white', 'yellow', 'orange', 'red']
        else:
            assert len(colors) == 6

        self.polys = [
            plt.Polygon(self._faces[i, :, :2],
                        facecolor=colors[i],
                        alpha=alpha) for i in range(6)
        ]
コード例 #23
0
    def _key_press(self, event):
        """Operador para eventos de pressionar tecla"""
        if event.key == 'shift':
            self._shift = True
        elif event.key.isdigit():
            self._digit_flags[int(event.key)] = 1
        elif event.key == 'right':
            if self._shift:
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR, 5 * self._step_LR))
        elif event.key == 'left':
            if self._shift:
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR, -5 * self._step_LR))
        elif event.key == 'up':
            self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                                5 * self._step_UD))
        elif event.key == 'down':
            self.rotate(
                Quaternion.from_v_theta(self._ax_UD, -5 * self._step_UD))
        elif event.key.upper() in 'LRUDBF':
            if self._shift:
                direction = -1
            else:
                direction = 1

            if np.any(self._digit_flags[:N]):
                for d in np.arange(N)[self._digit_flags[:N]]:
                    self.rotate_face(event.key.upper(), direction, layer=d)
            else:
                self.rotate_face(event.key.upper(), direction)

        self._draw_cube()
コード例 #24
0
    def __init__(self, view=(0, 0, 10), fig=None,
                 rect=None, **kwargs):
        if rect is None:
            rect = [0, 0, 1, 1]
        if fig is None:
            fig = plt.gcf()

        self.view = np.asarray(view)
        self.start_rot = Quaternion.from_v_theta((1, -1, 0), -np.pi / 6)

        # Define movement for up/down arrows or up/down mouse movement
        self._ax_UD = (1, 0, 0)
        self._step_UD = 0.01

        # Define movement for left/right arrows or left/right mouse movement
        self._ax_LR = (0, -1, 0)
        self._step_LR = 0.01

        # Internal state variable
        self._button1 = False
        self._button2 = False
        self._event_xy = None
        self._current_rot = self.start_rot
        self._npts = [1]
        self._xyzs = [[0, 0, 0]]
        self._xys = [[0, 0]]
        self._polys = []

        # initialize the axes.  We'll set some keywords by default
        kwargs.update(dict(aspect='equal',
                           xlim=(-2.5, 2.5), ylim=(-2.5, 2.5),
                           frameon=False, xticks=[], yticks=[]))
        super(PolyView3D, self).__init__(fig, rect, **kwargs)
        self.xaxis.set_major_formatter(plt.NullFormatter())
        self.yaxis.set_major_formatter(plt.NullFormatter())

        # connect some GUI events
        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_press_event',
                                       self._key_press)
        self.figure.canvas.mpl_connect('key_release_event',
                                       self._key_release)
コード例 #25
0
ファイル: axes3d.py プロジェクト: amshenoy/MagicCube
    def __init__(self, view=(0, 0, 10), fig=None,
                 rect=[0, 0, 1, 1], **kwargs):
        if fig is None:
            fig = plt.gcf()

        self.view = np.asarray(view)
        self.start_rot = Quaternion.from_v_theta((1, -1, 0), -np.pi / 6)

        # Define movement for up/down arrows or up/down mouse movement
        self._ax_UD = (1, 0, 0)
        self._step_UD = 0.01

        # Define movement for left/right arrows or left/right mouse movement
        self._ax_LR = (0, -1, 0)
        self._step_LR = 0.01

        # Internal state variable
        self._button1 = False
        self._button2 = False
        self._event_xy = None
        self._current_rot = self.start_rot
        self._npts = [1]
        self._xyzs = [[0, 0, 0]]
        self._xys = [[0, 0]]
        self._polys = []

        # initialize the axes.  We'll set some keywords by default
        kwargs.update(dict(aspect='equal',
                           xlim=(-2.5, 2.5), ylim=(-2.5, 2.5),
                           frameon=False, xticks=[], yticks=[]))
        super(PolyView3D, self).__init__(fig, rect, **kwargs)
        self.xaxis.set_major_formatter(plt.NullFormatter())
        self.yaxis.set_major_formatter(plt.NullFormatter())

        # connect some GUI events
        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_press_event',
                                       self._key_press)
        self.figure.canvas.mpl_connect('key_release_event',
                                       self._key_release)
コード例 #26
0
class Cube:
    """Representacao do Cubo Magico"""
    # define alguns atributos
    default_plastic_color = 'black'
    default_face_colors = [
        "w", "#00ff80", "#ff007f", "#007fff", "#ff8000", "#ffff00", "#141400",
        "none"
    ]
    base_face = np.array(
        [[1, 1, 1], [1, -1, 1], [-1, -1, 1], [-1, 1, 1], [1, 1, 1]],
        dtype=float)
    stickerwidth = 0.9
    stickermargin = 0.5 * (1. - stickerwidth)
    stickerthickness = 0.001
    (d1, d2, d3) = (1 - stickermargin, 1 - 2 * stickermargin,
                    1 + stickerthickness)
    base_sticker = np.array([[d1, d2, d3], [d2, d1, d3], [-d2, d1, d3],
                             [-d1, d2, d3], [-d1, -d2, d3], [-d2, -d1, d3],
                             [d2, -d1, d3], [d1, -d2, d3], [d1, d2, d3]],
                            dtype=float)

    base_face_centroid = np.array([[0, 0, 1]])
    base_sticker_centroid = np.array([[0, 0, 1 + stickerthickness]])

    # Define a rotacao dos angulos e eixos para os 6 lados do cubo
    x, y, z = np.eye(3)
    rots = [
        Quaternion.from_v_theta(np.eye(3)[0], theta)
        for theta in (np.pi / 2, -np.pi / 2)
    ]
    rots += [
        Quaternion.from_v_theta(np.eye(3)[1], theta)
        for theta in (np.pi / 2, -np.pi / 2, np.pi, 2 * np.pi)
    ]

    # define os movimentos das faces
    facesdict = dict(F=z, B=-z, R=x, L=-x, U=y, D=-y)

    def __init__(self, N=3, plastic_color=None, face_colors=None):
        self.N = N
        if plastic_color is None:
            self.plastic_color = self.default_plastic_color
        else:
            self.plastic_color = plastic_color

        if face_colors is None:
            self.face_colors = self.default_face_colors
        else:
            self.face_colors = face_colors

        self._move_list = []
        self._initialize_arrays()

    def _initialize_arrays(self):
        # Inicializa os centroides, faces e adesivos do cubo.Comecamos com uma
        # base para cada um, e entao transladamos e rotacionamos na posicao.

        # Define N^2 translacoes para cada face do cubo
        cubie_width = 2. / self.N
        translations = np.array(
            [[[-1 + (i + 0.5) * cubie_width, -1 + (j + 0.5) * cubie_width, 0]]
             for i in range(self.N) for j in range(self.N)])

        #  Cria arrays para os centroides, faces, adesivos e cores
        face_centroids = []
        faces = []
        sticker_centroids = []
        stickers = []
        colors = []

        factor = np.array([1. / self.N, 1. / self.N, 1])

        for i in range(6):
            M = self.rots[i].as_rotation_matrix()
            faces_t = np.dot(factor * self.base_face + translations, M.T)
            stickers_t = np.dot(factor * self.base_sticker + translations, M.T)
            face_centroids_t = np.dot(self.base_face_centroid + translations,
                                      M.T)
            sticker_centroids_t = np.dot(
                self.base_sticker_centroid + translations, M.T)
            colors_i = i + np.zeros(face_centroids_t.shape[0], dtype=int)

            # Anexa o id da face a face do centroide para o embaralhamento
            face_centroids_t = np.hstack(
                [face_centroids_t.reshape(-1, 3), colors_i[:, None]])
            sticker_centroids_t = sticker_centroids_t.reshape((-1, 3))

            faces.append(faces_t)
            face_centroids.append(face_centroids_t)
            stickers.append(stickers_t)
            sticker_centroids.append(sticker_centroids_t)
            colors.append(colors_i)

        self._face_centroids = np.vstack(face_centroids)
        self._faces = np.vstack(faces)
        self._sticker_centroids = np.vstack(sticker_centroids)
        self._stickers = np.vstack(stickers)
        self._colors = np.concatenate(colors)

        self._sort_faces()

    def _sort_faces(self):
        # Use o embaralhamento(lexsort)  nos centroides para colocar as faces na ordem original
        ind = np.lexsort(self._face_centroids.T)
        self._face_centroids = self._face_centroids[ind]
        self._sticker_centroids = self._sticker_centroids[ind]
        self._stickers = self._stickers[ind]
        self._colors = self._colors[ind]
        self._faces = self._faces[ind]

    def rotate_face(self, f, n=1, layer=0):
        """Rotacao da face"""
        if layer < 0 or layer >= self.N:
            raise ValueError('camada deve estar entre  0 e N-1')

        try:
            f_last, n_last, layer_last = self._move_list[-1]
        except:
            f_last, n_last, layer_last = None, None, None

        if (f == f_last) and (layer == layer_last):
            ntot = (n_last + n) % 4
            if abs(ntot - 4) < abs(ntot):
                ntot = ntot - 4
            if np.allclose(ntot, 0):
                self._move_list = self._move_list[:-1]
            else:
                self._move_list[-1] = (f, ntot, layer)
        else:
            self._move_list.append((f, n, layer))

        v = self.facesdict[f]
        r = Quaternion.from_v_theta(v, n * np.pi / 2)
        M = r.as_rotation_matrix()

        proj = np.dot(self._face_centroids[:, :3], v)
        cubie_width = 2. / self.N
        flag = ((proj > 0.9 - (layer + 1) * cubie_width) &
                (proj < 1.1 - layer * cubie_width))

        for x in [self._stickers, self._sticker_centroids, self._faces]:
            x[flag] = np.dot(x[flag], M.T)
        self._face_centroids[flag, :3] = np.dot(self._face_centroids[flag, :3],
                                                M.T)

    def draw_interactive(self):
        fig = plt.figure(figsize=(5, 5))
        fig.add_axes(InteractiveCube(self))
        return fig
コード例 #27
0
    def __init__(self, cube=None,
                 interactive=True,
                 view=(0, 0, 10),
                 fig=None, rect=[0, 0.16, 1, 0.84],
                 **kwargs):
        if cube is None:
            self.cube = Cube(3)
        elif isinstance(cube, Cube):
            self.cube = cube
        else:
            self.cube = Cube(cube)

        self._view = view
        self._start_rot = Quaternion.from_v_theta((1, -1, 0),
                                                  -np.pi / 6)

        if fig is None:
            fig = plt.gcf()

        # disable default key press events
        callbacks = fig.canvas.callbacks.callbacks
        del callbacks['key_press_event']

        # add some defaults, and draw axes
        kwargs.update(dict(aspect=kwargs.get('aspect', 'equal'),
                           xlim=kwargs.get('xlim', (-2.0, 2.0)),
                           ylim=kwargs.get('ylim', (-2.0, 2.0)),
                           frameon=kwargs.get('frameon', False),
                           xticks=kwargs.get('xticks', []),
                           yticks=kwargs.get('yticks', [])))
        super(InteractiveCube, self).__init__(fig, rect, **kwargs)
        self.xaxis.set_major_formatter(plt.NullFormatter())
        self.yaxis.set_major_formatter(plt.NullFormatter())

        self._start_xlim = kwargs['xlim']
        self._start_ylim = kwargs['ylim']

        # Define movement for up/down arrows or up/down mouse movement
        self._ax_UD = (1, 0, 0)
        self._step_UD = 0.01

        # Define movement for left/right arrows or left/right mouse movement
        self._ax_LR = (0, -1, 0)
        self._step_LR = 0.01

        self._ax_LR_alt = (0, 0, 1)

        # Internal state variable
        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._event_xy = None  # store xy position of mouse event
        self._shift = False  # shift key pressed
        self._digit_flags = np.zeros(10, dtype=bool)  # digits 0-9 pressed

        self._current_rot = self._start_rot  #current rotation state
        self._face_polys = None
        self._sticker_polys = None

        self._draw_cube()

        # connect some GUI events
        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_press_event',
                                       self._key_press)
        self.figure.canvas.mpl_connect('key_release_event',
                                       self._key_release)

        self._initialize_widgets()

        # write some instructions
        self.figure.text(0.05, 0.05,
                         "Mouse/arrow keys adjust view\n"
                         "U/D/L/R/B/F keys turn faces\n"
                         "(hold shift for counter-clockwise)",
                         size=10)
コード例 #28
0
    def __init__(self,
                 cube=None,
                 interactive=True,
                 view=(0, 0, 10),
                 fig=None,
                 rect=[0, 0.16, 1, 0.84],
                 **kwargs):
        if cube is None:
            self.cube = Cube(3)
        elif isinstance(cube, Cube):
            self.cube = cube
        else:
            self.cube = Cube(cube)

        self._view = view
        self._start_rot = Quaternion.from_v_theta((1, -1, 0), -np.pi / 6)

        if fig is None:
            fig = plt.gcf()

        # disable default key press events
        callbacks = fig.canvas.callbacks.callbacks
        del callbacks['key_press_event']

        # add some defaults, and draw axes
        kwargs.update(
            dict(aspect=kwargs.get('aspect', 'equal'),
                 xlim=kwargs.get('xlim', (-2.0, 2.0)),
                 ylim=kwargs.get('ylim', (-2.0, 2.0)),
                 frameon=kwargs.get('frameon', False),
                 xticks=kwargs.get('xticks', []),
                 yticks=kwargs.get('yticks', [])))
        super(InteractiveCube, self).__init__(fig, rect, **kwargs)
        self.xaxis.set_major_formatter(plt.NullFormatter())
        self.yaxis.set_major_formatter(plt.NullFormatter())

        self._start_xlim = kwargs['xlim']
        self._start_ylim = kwargs['ylim']

        # Define movement for up/down arrows or up/down mouse movement
        self._ax_UD = (1, 0, 0)
        self._step_UD = 0.01

        # Define movement for left/right arrows or left/right mouse movement
        self._ax_LR = (0, -1, 0)
        self._step_LR = 0.01

        self._ax_LR_alt = (0, 0, 1)

        # Internal state variable
        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._event_xy = None  # store xy position of mouse event
        self._shift = False  # shift key pressed
        self._digit_flags = np.zeros(10, dtype=bool)  # digits 0-9 pressed

        self._current_rot = self._start_rot  #current rotation state
        self._face_polys = None
        self._sticker_polys = None

        self._draw_cube()

        # connect some GUI events
        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_press_event', self._key_press)
        self.figure.canvas.mpl_connect('key_release_event', self._key_release)

        self._initialize_widgets()

        # write some instructions
        self.figure.text(0.05,
                         0.05, "Mouse/arrow keys adjust view\n"
                         "U/D/L/R/B/F keys turn faces\n"
                         "(hold shift for counter-clockwise)",
                         size=10)
コード例 #29
0
    def __init__(self,
                 cube=None,
                 interactive=True,
                 view=(0, 0, 10),
                 fig=None,
                 rect=[0, 0.16, 1, 0.84],
                 **kwargs):
        if cube is None:
            self.cube = Cube(3)
        elif isinstance(cube, Cube):
            self.cube = cube
        else:
            self.cube = Cube(cube)

        self._view = view
        self._start_rot = Quaternion.from_v_theta((1, -1, 0), -np.pi / 6)

        if fig is None:
            fig = plt.gcf()

        # Desabilita eventos de pressionar teclas
        callbacks = fig.canvas.callbacks.callbacks
        del callbacks['key_press_event']

        #  Adicionar alguns padroes e desenha eixos
        kwargs.update(
            dict(aspect=kwargs.get('aspect', 'equal'),
                 xlim=kwargs.get('xlim', (-2.0, 2.0)),
                 ylim=kwargs.get('ylim', (-2.0, 2.0)),
                 frameon=kwargs.get('frameon', False),
                 xticks=kwargs.get('xticks', []),
                 yticks=kwargs.get('yticks', [])))
        super(InteractiveCube, self).__init__(fig, rect, **kwargs)
        self.xaxis.set_major_formatter(plt.NullFormatter())
        self.yaxis.set_major_formatter(plt.NullFormatter())

        self._start_xlim = kwargs['xlim']
        self._start_ylim = kwargs['ylim']

        # Define o movimento cima/baixo do mouse e teclado
        self._ax_UD = (1, 0, 0)
        self._step_UD = 0.01

        # Define o movimento de esquerda/direita do mouse e teclado
        self._ax_LR = (0, -1, 0)
        self._step_LR = 0.01

        self._ax_LR_alt = (0, 0, 1)

        # Variavel de estado interno
        self._active = False  #  Verdade quando o mouse estiver sobre os eixos
        self._button1 = False  # Verdadeiro quando o botão 1 é pressionado
        self._button2 = False  # Verdadeiro quando o botão 2 é pressionado
        self._event_xy = None  # Armazena a posição xy de um evento do mouse
        self._shift = False  # tecla SHIFT pressionada
        self._digit_flags = np.zeros(10,
                                     dtype=bool)  # digitos 0-9 pressionados

        self._current_rot = self._start_rot  #Atual estado de rotacao
        self._face_polys = None
        self._sticker_polys = None

        self._draw_cube()

        # Conecta alguns eventos da GUI
        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_press_event', self._key_press)
        self.figure.canvas.mpl_connect('key_release_event', self._key_release)

        self._initialize_widgets()

        # escrever algumas instrucoes
        self.figure.text(0.05,
                         0.05, "Mouse/setas para andar pelo cubo\n"
                         "U/D/L/R/B/F para movimentos\n"
                         "(segure SHIFT para anti-horario)",
                         size=10)
コード例 #30
0
class InteractiveCube(plt.Axes):
    # Define some attributes
    base_face = np.array(
        [[1, 1, 1], [1, -1, 1], [-1, -1, 1], [-1, 1, 1], [1, 1, 1]],
        dtype=float)
    stickerwidth = 0.9
    stickermargin = 0.5 * (1. - stickerwidth)
    stickerthickness = 0.001
    (d1, d2, d3) = (1 - stickermargin, 1 - 2 * stickermargin,
                    1 + stickerthickness)
    base_sticker = np.array([[d1, d2, d3], [d2, d1, d3], [-d2, d1, d3],
                             [-d1, d2, d3], [-d1, -d2, d3], [-d2, -d1, d3],
                             [d2, -d1, d3], [d1, -d2, d3], [d1, d2, d3]],
                            dtype=float)

    base_face_centroid = np.array([[0, 0, 1]])
    base_sticker_centroid = np.array([[0, 0, 1 + stickerthickness]])

    # Define rotation angles and axes for the six sides of the cube
    x, y, z = np.eye(3)
    rots = [
        Quaternion.from_v_theta(x, theta) for theta in (np.pi / 2, -np.pi / 2)
    ]
    rots += [
        Quaternion.from_v_theta(y, theta)
        for theta in (np.pi / 2, -np.pi / 2, np.pi, 2 * np.pi)
    ]

    def __init__(self,
                 N,
                 sess=None,
                 inputTensPH=None,
                 outputTens=None,
                 state=None,
                 interactive=True,
                 view=(0, 0, 10),
                 fig=None,
                 rect=[0, 0.16, 1, 0.84],
                 **kwargs):
        self._move_list = []

        self.N = N
        self.sess = sess
        self.inputTensPH = inputTensPH
        self.outputTens = outputTens
        self._prevStates = []

        self.Environment = Cube(N=3, moveType="qtm")

        self._view = view
        self._start_rot = Quaternion.from_v_theta((1, -1, 0), -np.pi / 6)

        if fig is None:
            fig = plt.gcf()

        # disable default key press events
        callbacks = fig.canvas.callbacks.callbacks
        del callbacks['key_press_event']

        # add some defaults, and draw axes
        kwargs.update(
            dict(aspect=kwargs.get('aspect', 'equal'),
                 xlim=kwargs.get('xlim', (-2.0, 2.0)),
                 ylim=kwargs.get('ylim', (-2.0, 2.0)),
                 frameon=kwargs.get('frameon', False),
                 xticks=kwargs.get('xticks', []),
                 yticks=kwargs.get('yticks', [])))
        super(InteractiveCube, self).__init__(fig, rect, **kwargs)
        self.xaxis.set_major_formatter(plt.NullFormatter())
        self.yaxis.set_major_formatter(plt.NullFormatter())

        self._start_xlim = kwargs['xlim']
        self._start_ylim = kwargs['ylim']

        # Define movement for up/down arrows or up/down mouse movement
        self._ax_UD = (1, 0, 0)
        self._step_UD = 0.01

        # Define movement for left/right arrows or left/right mouse movement
        self._ax_LR = (0, -1, 0)
        self._step_LR = 0.01

        self._ax_LR_alt = (0, 0, 1)

        # Internal state variable
        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._event_xy = None  # store xy position of mouse event
        self._shift = False  # shift key pressed
        self._digit_flags = np.zeros(10, dtype=bool)  # digits 0-9 pressed

        self._current_rot = self._start_rot  #current rotation state
        self._face_polys = None
        self._sticker_polys = None

        self.plastic_color = 'black'

        # WHITE:0 - U, YELLOW:1 - D, BLUE:2 - L, GREEN:3 - R, ORANGE: 4 - B, RED: 5 - F
        self.face_colors = [
            "w", "#ffcf00", "#ff6f00", "#cf0000", "#00008f", "#009f0f", "gray",
            "none"
        ]

        self._initialize_arrays()

        self._draw_cube()

        # connect some GUI events
        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_press_event', self._key_press)
        self.figure.canvas.mpl_connect('key_release_event', self._key_release)

        #self._initialize_widgets()

        # write some instructions
        """
        self.figure.text(0.05, 0.05,
                         "Mouse/arrow keys adjust view\n"
                         "U/D/L/R/B/F keys turn faces\n"
                         "(hold shift for counter-clockwise)",
                         size=10)
        """

        if state is not None:
            self._colors = np.array([int(x) for x in state.split(",")])
            self._draw_cube()

    def _initialize_arrays(self):
        # initialize centroids, faces, and stickers.  We start with a
        # base for each one, and then translate & rotate them into position.

        # Define N^2 translations for each face of the cube
        cubie_width = 2. / self.N
        translations = np.array(
            [[[-1 + (i + 0.5) * cubie_width, -1 + (j + 0.5) * cubie_width, 0]]
             for i in range(self.N) for j in range(self.N)])

        # Create arrays for centroids, faces, stickers
        face_centroids = []
        faces = []
        sticker_centroids = []
        stickers = []
        colors = []

        factor = np.array([1. / self.N, 1. / self.N, 1])

        for i in range(6):
            M = self.rots[i].as_rotation_matrix()
            faces_t = np.dot(factor * self.base_face + translations, M.T)
            stickers_t = np.dot(factor * self.base_sticker + translations, M.T)
            face_centroids_t = np.dot(self.base_face_centroid + translations,
                                      M.T)
            sticker_centroids_t = np.dot(
                self.base_sticker_centroid + translations, M.T)
            #colors_i = i + np.zeros(face_centroids_t.shape[0], dtype=int)
            colors_i = np.arange(i * face_centroids_t.shape[0],
                                 (i + 1) * face_centroids_t.shape[0])

            # append face ID to the face centroids for lex-sorting
            face_centroids_t = np.hstack(
                [face_centroids_t.reshape(-1, 3), colors_i[:, None]])
            sticker_centroids_t = sticker_centroids_t.reshape((-1, 3))

            faces.append(faces_t)
            face_centroids.append(face_centroids_t)
            stickers.append(stickers_t)
            sticker_centroids.append(sticker_centroids_t)

            colors.append(colors_i)

        self._face_centroids = np.vstack(face_centroids)
        self._faces = np.vstack(faces)
        self._sticker_centroids = np.vstack(sticker_centroids)
        self._stickers = np.vstack(stickers)
        self._colors = np.concatenate(colors)

    def reset(self):
        self._colors = self.Environment.solvedState

    def getState(self):
        return (self._colors)

    def _initialize_widgets(self):
        self._ax_reset = self.figure.add_axes([0.75, 0.05, 0.2, 0.075])
        self._btn_reset = widgets.Button(self._ax_reset, 'Reset View')
        self._btn_reset.on_clicked(self._reset_view)

        self._ax_solve = self.figure.add_axes([0.55, 0.05, 0.2, 0.075])
        self._btn_solve = widgets.Button(self._ax_solve, 'Solve Cube')
        self._btn_solve.on_clicked(self._solve_cube)

    def _project(self, pts):
        return project_points(pts, self._current_rot, self._view, [0, 1, 0])

    def _draw_cube(self):
        stickers = self._project(self._stickers)[:, :, :2]
        faces = self._project(self._faces)[:, :, :2]
        face_centroids = self._project(self._face_centroids[:, :3])
        sticker_centroids = self._project(self._sticker_centroids[:, :3])

        plastic_color = self.plastic_color
        #self._colors[np.ravel_multi_index((0,1,2),(6,N,N))] = 10
        #self._colors[self.Environment.colorsToGet] = 54
        colors = np.asarray(self.face_colors)[self._colors / (self.N**2)]
        face_zorders = -face_centroids[:, 2]
        sticker_zorders = -sticker_centroids[:, 2]

        if self._face_polys is None:
            # initial call: create polygon objects and add to axes
            self._face_polys = []
            self._sticker_polys = []

            for i in range(len(colors)):
                fp = plt.Polygon(faces[i],
                                 facecolor=plastic_color,
                                 zorder=face_zorders[i])
                sp = plt.Polygon(stickers[i],
                                 facecolor=colors[i],
                                 zorder=sticker_zorders[i])

                self._face_polys.append(fp)
                self._sticker_polys.append(sp)
                self.add_patch(fp)
                self.add_patch(sp)
        else:
            # subsequent call: update the polygon objects
            for i in range(len(colors)):
                self._face_polys[i].set_xy(faces[i])
                self._face_polys[i].set_zorder(face_zorders[i])
                self._face_polys[i].set_facecolor(plastic_color)

                self._sticker_polys[i].set_xy(stickers[i])
                self._sticker_polys[i].set_zorder(sticker_zorders[i])
                self._sticker_polys[i].set_facecolor(colors[i])

        self.figure.canvas.draw()

    def rotate(self, rot):
        self._current_rot = self._current_rot * rot

    def rotate_face(self, f, n=1, layer=0):
        self._move_list.append((f, n, layer))

        if not np.allclose(n, 0):
            self._colors = self.Environment.next_state(self._colors, [f, n],
                                                       layer=layer)
            self._draw_cube()

    def move(self, move, draw=True):
        self._colors = self.Environment.next_state(self._colors, move)
        if draw:
            self._draw_cube()

    def _reset_view(self, *args):
        self.set_xlim(self._start_xlim)
        self.set_ylim(self._start_ylim)
        self._current_rot = self._start_rot
        self._draw_cube()

    def _solve_cube(self, *args):
        move_list = self._move_list[:]
        for (face, n, layer) in move_list[::-1]:
            self.rotate_face(face, -n, layer)
        self._move_list = []

    def _solve_cube_kociemba(self):
        # WHITE:0 - U, YELLOW:1 - D, BLUE:2 - L, GREEN:3 - R, ORANGE: 4 - B, RED: 5 - F
        moves = Kociemba.solve(self._colors)

        #print "Solution length: %i" % (len(moves))
        for face, n in moves:
            self.rotate_face(face, n, 0)

    def _solve_cube_nnet(self):
        startTime = time.time()
        BestFS_solve = search_utils.BestFS_solve([self._colors], self.sess,
                                                 self.inputTensPH,
                                                 self.outputTens,
                                                 self.Environment)
        isSolved, solveSteps = BestFS_solve.run(numParallel=200, verbose=True)

        ### Make move
        moves = solveSteps[0]
        #print("Cube scrambled %i times. Neural network found solution of length %i (%s)" % (len(self._move_list),len(moves),time.time()-startTime))
        for face, n in moves:
            self.rotate_face(face, n, 0)
            time.sleep(0.1)

    def _key_press(self, event):
        """Handler for key press events"""
        if event.key == 'shift':
            self._shift = True
        elif event.key.isdigit():
            self._digit_flags[int(event.key)] = 1
        elif event.key == 'right':
            if self._shift:
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR, 5 * self._step_LR))
        elif event.key == 'left':
            if self._shift:
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR, -5 * self._step_LR))
        elif event.key == 'up':
            self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                                5 * self._step_UD))
        elif event.key == 'down':
            self.rotate(
                Quaternion.from_v_theta(self._ax_UD, -5 * self._step_UD))
        elif event.key.upper() in 'LRUDBF':
            if self._shift:
                direction = -1
            else:
                direction = 1

            if np.any(self._digit_flags[:N]):
                for d in np.arange(N)[self._digit_flags[:N]]:
                    self.rotate_face(event.key.upper(), direction, layer=d)
            else:
                self.rotate_face(event.key.upper(), direction)

        elif event.key.upper() in 'QWEA':
            if event.key.upper() == 'Q':
                self._colors = self.Environment.transpose(
                    self._colors, 0, indexType="position").flatten()
                self._colors = np.argsort(self._colors)
            elif event.key.upper() == 'W':
                self._colors = self.Environment.transpose(
                    self._colors, 2, indexType="position").flatten()
                self._colors = np.argsort(self._colors)
            elif event.key.upper() == 'E':
                self._colors = self.Environment.transpose(
                    self._colors, 4, indexType="position").flatten()
                self._colors = np.argsort(self._colors)
            elif event.key.upper() == 'A':
                self._colors = self.Environment.transpose(
                    self._colors, -1, indexType="position").flatten()
                self._colors = np.argsort(self._colors)

        elif event.key.upper() == 'K':
            self._solve_cube_kociemba()

        elif event.key.upper() == 'O':
            self._solve_cube_korf()

        elif event.key.upper() == 'N':
            self._solve_cube_nnet()

        elif event.key.upper() == 'P':
            self.figure.savefig('cubeSnapshot.eps')

        self._draw_cube()
        isSolved = self.Environment.checkSolved(self._colors)
        if isSolved:
            print("SOLVED!")
            self._move_list = []
            self._prevStates = []

    def _key_release(self, event):
        """Handler for key release event"""
        if event.key == 'shift':
            self._shift = False
        elif event.key.isdigit():
            self._digit_flags[int(event.key)] = 0

    def _mouse_press(self, event, event_x=None, event_y=None):
        """Handler for mouse button press"""
        if event_x != None and event_y != None:
            self._event_xy = (event_x, event_y)
            self._button1 = True
        else:
            self._event_xy = (event.x, event.y)
            if event.button == 1:
                self._button1 = True
            elif event.button == 3:
                self._button2 = True

    def _mouse_release(self, event):
        """Handler for mouse button release"""
        self._event_xy = None
        if event.button == 1:
            self._button1 = False
        elif event.button == 3:
            self._button2 = False

    def _mouse_motion(self, event, event_x=None, event_y=None):
        """Handler for mouse motion"""
        if self._button1 or self._button2:
            if event_x != None and event_y != None:
                dx = event_x - self._event_xy[0]
                dy = event_y - self._event_xy[1]
                self._event_xy = (event_x, event_y)
            else:
                dx = event.x - self._event_xy[0]
                dy = event.y - self._event_xy[1]
                self._event_xy = (event.x, event.y)

            if self._button1:
                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_cube()

            if self._button2:
                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()
コード例 #31
0
class Cube:
    """Rubik's Cube Representation"""
    # define some attribues
    default_init_state = np.array([
        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 5
    ])

    # move indices
    moveInds = { \
    "U": 0, "U2": 1 , "R": 2, "R2": 3, "F": 4, "F2": 5\
    }

    # move definitions
    moveDefs = np.array([ \
    [  2,  0,  3,  1,  6,  7,  8,  9, 10, 11,  4,  5, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23], \
     [  3,  2,  1,  0,  8,  9, 10, 11,  4,  5,  6,  7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23], \
    [  0,  7,  2, 15,  4,  5,  6, 21, 16,  8,  3, 11, 12, 13, 14, 23, 17,  9,  1, 19, 20, 18, 22, 10], \
    [  0, 21,  2, 23,  4,  5,  6, 18, 17, 16, 15, 11, 12, 13, 14, 10,  9,  8,  7, 19, 20,  1, 22,  3], \
    [  0,  1, 13,  5,  4, 20, 14,  6,  2,  9, 10, 11, 12, 21, 15,  7,  3, 17, 18, 19, 16,  8, 22, 23], \
    [  0,  1, 21, 20,  4, 16, 15, 14, 13,  9, 10, 11, 12,  8,  7,  6,  5, 17, 18, 19,  3,  2, 22, 23], \
    ])

    # piece definitions
    pieceDefs = np.array([ \
    [  0, 11,  4], \
    [  2,  5,  6], \
    [  3,  7,  8], \
    [  1,  9, 10], \
    [ 20, 14, 13], \
    [ 21, 15, 15], \
    [ 23, 18, 17], \
    ])

    default_plastic_color = 'black'
    default_face_colors = [
        "w", "#ffcf00", "#00008f", "#009f0f", "#ff6f00", "#cf0000", "gray",
        "none"
    ]
    base_face = np.array(
        [[1, 1, 1], [1, -1, 1], [-1, -1, 1], [-1, 1, 1], [1, 1, 1]],
        dtype=float)
    face_element_width = 0.9
    face_element_margin = 0.5 * (1. - face_element_width)
    face_element_thickness = 0.001
    (d1, d2, d3) = (1 - face_element_margin, 1 - 2 * face_element_margin,
                    1 + face_element_thickness)
    base_face_element = np.array(
        [[d1, d2, d3], [d2, d1, d3], [-d2, d1, d3], [-d1, d2, d3],
         [-d1, -d2, d3], [-d2, -d1, d3], [d2, -d1, d3], [d1, -d2, d3],
         [d1, d2, d3]],
        dtype=float)

    base_face_centroid = np.array([[0, 0, 1]])
    base_face_element_centroid = np.array([[0, 0, 1 + face_element_thickness]])

    # apply a move to a state
    def doMove(self, move):
        return self.state[self.moveDefs[self.moveInds[m]]]

    # apply a string sequence of moves to a state
    def doAlgStr(self, alg):
        moves = alg.split(" ")
        for m in moves:
            if m in self.moveInds:
                self.state = self.state[self.moveDefs[self.moveInds[m]]]
        self._printCube()

    # print state of the cube
    def _printCube(self):
        print("      ┌──┬──┐")
        print("      │ {}│ {}│".format(self.state[0], self.state[1]))
        print("      ├──┼──┤")
        print("      │ {}│ {}│".format(self.state[2], self.state[3]))
        print("┌──┬──┼──┼──┼──┬──┬──┬──┐")
        print("│ {}│ {}│ {}│ {}│ {}│ {}│ {}│ {}│".format(
            self.state[4], self.state[5], self.state[6], self.state[7],
            self.state[8], self.state[9], self.state[10], self.state[11]))
        print("├──┼──┼──┼──┼──┼──┼──┼──┤")
        print("│ {}│ {}│ {}│ {}│ {}│ {}│ {}│ {}│".format(
            self.state[12], self.state[13], self.state[14], self.state[15],
            self.state[16], self.state[17], self.state[18], self.state[19]))
        print("└──┴──┼──┼──┼──┴──┴──┴──┘")
        print("      │ {}│ {}│".format(self.state[20], self.state[21]))
        print("      ├──┼──┤")
        print("      │ {}│ {}│".format(self.state[22], self.state[23]))
        print("      └──┴──┘")

    # Define rotation angles and axes for the six sides of the cube
    x, y, z = np.eye(3)
    rots = [
        Quaternion.from_v_theta(np.eye(3)[0], theta)
        for theta in (np.pi / 2, -np.pi / 2)
    ]
    rots += [
        Quaternion.from_v_theta(np.eye(3)[1], theta)
        for theta in (np.pi / 2, -np.pi / 2, np.pi, 2 * np.pi)
    ]

    # define face movements
    facesdict = dict(F=z, B=-z, R=x, L=-x, U=y, D=-y)

    def __init__(self, N=2, plastic_color=None, face_colors=None):
        self.N = N
        if plastic_color is None:
            self.plastic_color = self.default_plastic_color
        else:
            self.plastic_color = plastic_color

        if face_colors is None:
            self.face_colors = self.default_face_colors
        else:
            self.face_colors = face_colors

        self.state = np.array([
            0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5,
            5, 5
        ])
        #self.state = np.array(['00000', '00001', '00010', '00011', '00100', '00101', '00110', '00111', '01000', '01001', '01010', '01011', '01100', '01101', '01110', '01111', '10000', '10001', '10010', '10011', '10100', '10101', '10110', '10111'])

        self._move_list = []
        self._solution = []
        self._initialize_arrays()

    def _initialize_arrays(self):
        # initialize centroids, faces, and face elements.  We start with a
        # base for each one, and then translate & rotate them into position.

        # Define N^2 translations for each face of the cube
        cubie_width = 2. / self.N
        translations = np.array(
            [[[-1 + (i + 0.5) * cubie_width, -1 + (j + 0.5) * cubie_width, 0]]
             for i in range(self.N) for j in range(self.N)])

        # Create arrays for centroids, faces, face elements, and colors
        face_centroids = []
        faces = []
        face_element_centroids = []
        face_elements = []
        colors = []

        factor = np.array([1. / self.N, 1. / self.N, 1])

        for i in range(6):
            M = self.rots[i].as_rotation_matrix()
            faces_t = np.dot(factor * self.base_face + translations, M.T)
            face_elements_t = np.dot(
                factor * self.base_face_element + translations, M.T)
            face_centroids_t = np.dot(self.base_face_centroid + translations,
                                      M.T)
            face_element_centroids_t = np.dot(
                self.base_face_element_centroid + translations, M.T)
            colors_i = i + np.zeros(face_centroids_t.shape[0], dtype=int)

            # append face ID to the face centroids for lex-sorting
            face_centroids_t = np.hstack(
                [face_centroids_t.reshape(-1, 3), colors_i[:, None]])
            face_element_centroids_t = face_element_centroids_t.reshape(
                (-1, 3))

            faces.append(faces_t)
            face_centroids.append(face_centroids_t)
            face_elements.append(face_elements_t)
            face_element_centroids.append(face_element_centroids_t)
            colors.append(colors_i)

        self._face_centroids = np.vstack(face_centroids)
        self._faces = np.vstack(faces)
        self._face_element_centroids = np.vstack(face_element_centroids)
        self._face_elements = np.vstack(face_elements)
        self._colors = np.concatenate(colors)

        self._sort_faces()

    def _sort_faces(self):
        # use lexsort on the centroids to put faces in a standard order.
        ind = np.lexsort(self._face_centroids.T)
        self._face_centroids = self._face_centroids[ind]
        self._face_element_centroids = self._face_element_centroids[ind]
        self._face_elements = self._face_elements[ind]
        self._colors = self._colors[ind]
        self._faces = self._faces[ind]

    def rotate_face(self, f, n=1, layer=0):
        self.doAlgStr(f)
        """Rotate Face"""
        if layer < 0 or layer >= self.N:
            raise ValueError('layer should be between 0 and N-1')

        try:
            f_last, n_last, layer_last = self._move_list[-1]
        except:
            f_last, n_last, layer_last = None, None, None

        if (f == f_last) and (layer == layer_last):
            ntot = (n_last + n) % 4
            if abs(ntot - 4) < abs(ntot):
                ntot = ntot - 4
            if np.allclose(ntot, 0):
                self._move_list = self._move_list[:-1]
            else:
                self._move_list[-1] = (f, ntot, layer)
        else:
            self._move_list.append(f)

        v = self.facesdict[f]
        r = Quaternion.from_v_theta(v, n * np.pi / 2)
        M = r.as_rotation_matrix()

        proj = np.dot(self._face_centroids[:, :3], v)
        cubie_width = 2. / self.N
        flag = ((proj > 0.9 - (layer + 1) * cubie_width) &
                (proj < 1.1 - layer * cubie_width))

        for x in [
                self._face_elements, self._face_element_centroids, self._faces
        ]:
            x[flag] = np.dot(x[flag], M.T)
        self._face_centroids[flag, :3] = np.dot(self._face_centroids[flag, :3],
                                                M.T)

    def draw_interactive(self):
        fig = plt.figure(figsize=(5, 5))
        fig.add_axes(InteractiveCube(self))
        return fig
コード例 #32
0
    def __init__(self,
                 cube=None,
                 interactive=True,
                 view=(0, 0, 10),
                 fig=None,
                 rect=[0, 0.16, 1, 0.84],
                 **kwargs):
        if cube is None:
            self.cube = Cube(3)
        elif isinstance(cube, Cube):
            self.cube = cube
        else:
            self.cube = Cube(cube)

        self._view = view
        self._start_rot = Quaternion.from_v_theta((1, -1, 0), -np.pi / 6)

        if fig is None:
            fig = plt.gcf()

        callbacks = fig.canvas.callbacks.callbacks
        del callbacks['key_press_event']

        kwargs.update(
            dict(aspect=kwargs.get('aspect', 'equal'),
                 xlim=kwargs.get('xlim', (-2.0, 2.0)),
                 ylim=kwargs.get('ylim', (-2.0, 2.0)),
                 frameon=kwargs.get('frameon', False),
                 xticks=kwargs.get('xticks', []),
                 yticks=kwargs.get('yticks', [])))
        super(InteractiveCube, self).__init__(fig, rect, **kwargs)
        self.xaxis.set_major_formatter(plt.NullFormatter())
        self.yaxis.set_major_formatter(plt.NullFormatter())

        self._start_xlim = kwargs['xlim']
        self._start_ylim = kwargs['ylim']

        self._ax_UD = (1, 0, 0)
        self._step_UD = 0.01

        self._ax_LR = (0, -1, 0)
        self._step_LR = 0.01

        self._ax_LR_alt = (0, 0, 1)

        self._active = False
        self._button1 = False
        self._button2 = False
        self._event_xy = None
        self._shift = False
        self._digit_flags = np.zeros(10, dtype=bool)

        self._current_rot = self._start_rot
        self._face_polys = None
        self._sticker_polys = None

        self._draw_cube()

        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_press_event', self._key_press)
        self.figure.canvas.mpl_connect('key_release_event', self._key_release)

        self._initialize_widgets()

        self.figure.text(0.05,
                         0.05, "Mouse/arrow keys adjust view\n"
                         "U/D/L/R/B/F keys turn faces\n"
                         "(hold shift for counter-clockwise)",
                         size=10)
コード例 #33
0
    def __init__(self,
                 N,
                 sess=None,
                 inputTensPH=None,
                 outputTens=None,
                 state=None,
                 interactive=True,
                 view=(0, 0, 10),
                 fig=None,
                 rect=[0, 0.16, 1, 0.84],
                 **kwargs):
        self._move_list = []

        self.N = N
        self.sess = sess
        self.inputTensPH = inputTensPH
        self.outputTens = outputTens
        self._prevStates = []

        self.Environment = Cube(N=3, moveType="qtm")

        self._view = view
        self._start_rot = Quaternion.from_v_theta((1, -1, 0), -np.pi / 6)

        if fig is None:
            fig = plt.gcf()

        # disable default key press events
        callbacks = fig.canvas.callbacks.callbacks
        del callbacks['key_press_event']

        # add some defaults, and draw axes
        kwargs.update(
            dict(aspect=kwargs.get('aspect', 'equal'),
                 xlim=kwargs.get('xlim', (-2.0, 2.0)),
                 ylim=kwargs.get('ylim', (-2.0, 2.0)),
                 frameon=kwargs.get('frameon', False),
                 xticks=kwargs.get('xticks', []),
                 yticks=kwargs.get('yticks', [])))
        super(InteractiveCube, self).__init__(fig, rect, **kwargs)
        self.xaxis.set_major_formatter(plt.NullFormatter())
        self.yaxis.set_major_formatter(plt.NullFormatter())

        self._start_xlim = kwargs['xlim']
        self._start_ylim = kwargs['ylim']

        # Define movement for up/down arrows or up/down mouse movement
        self._ax_UD = (1, 0, 0)
        self._step_UD = 0.01

        # Define movement for left/right arrows or left/right mouse movement
        self._ax_LR = (0, -1, 0)
        self._step_LR = 0.01

        self._ax_LR_alt = (0, 0, 1)

        # Internal state variable
        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._event_xy = None  # store xy position of mouse event
        self._shift = False  # shift key pressed
        self._digit_flags = np.zeros(10, dtype=bool)  # digits 0-9 pressed

        self._current_rot = self._start_rot  #current rotation state
        self._face_polys = None
        self._sticker_polys = None

        self.plastic_color = 'black'

        # WHITE:0 - U, YELLOW:1 - D, BLUE:2 - L, GREEN:3 - R, ORANGE: 4 - B, RED: 5 - F
        self.face_colors = [
            "w", "#ffcf00", "#ff6f00", "#cf0000", "#00008f", "#009f0f", "gray",
            "none"
        ]

        self._initialize_arrays()

        self._draw_cube()

        # connect some GUI events
        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_press_event', self._key_press)
        self.figure.canvas.mpl_connect('key_release_event', self._key_release)

        #self._initialize_widgets()

        # write some instructions
        """
        self.figure.text(0.05, 0.05,
                         "Mouse/arrow keys adjust view\n"
                         "U/D/L/R/B/F keys turn faces\n"
                         "(hold shift for counter-clockwise)",
                         size=10)
        """

        if state is not None:
            self._colors = np.array([int(x) for x in state.split(",")])
            self._draw_cube()
コード例 #34
0
    def _key_press(self, event):
        """Handler for key press events"""
        if event.key == 'shift':
            self._shift = True
        elif event.key.isdigit():
            self._digit_flags[int(event.key)] = 1
        elif event.key == 'right':
            if self._shift:
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR, 5 * self._step_LR))
        elif event.key == 'left':
            if self._shift:
                ax_LR = self._ax_LR_alt
            else:
                ax_LR = self._ax_LR
            self.rotate(Quaternion.from_v_theta(ax_LR, -5 * self._step_LR))
        elif event.key == 'up':
            self.rotate(Quaternion.from_v_theta(self._ax_UD,
                                                5 * self._step_UD))
        elif event.key == 'down':
            self.rotate(
                Quaternion.from_v_theta(self._ax_UD, -5 * self._step_UD))
        elif event.key.upper() in 'LRUDBF':
            if self._shift:
                direction = -1
            else:
                direction = 1

            if np.any(self._digit_flags[:N]):
                for d in np.arange(N)[self._digit_flags[:N]]:
                    self.rotate_face(event.key.upper(), direction, layer=d)
            else:
                self.rotate_face(event.key.upper(), direction)

        elif event.key.upper() in 'QWEA':
            if event.key.upper() == 'Q':
                self._colors = self.Environment.transpose(
                    self._colors, 0, indexType="position").flatten()
                self._colors = np.argsort(self._colors)
            elif event.key.upper() == 'W':
                self._colors = self.Environment.transpose(
                    self._colors, 2, indexType="position").flatten()
                self._colors = np.argsort(self._colors)
            elif event.key.upper() == 'E':
                self._colors = self.Environment.transpose(
                    self._colors, 4, indexType="position").flatten()
                self._colors = np.argsort(self._colors)
            elif event.key.upper() == 'A':
                self._colors = self.Environment.transpose(
                    self._colors, -1, indexType="position").flatten()
                self._colors = np.argsort(self._colors)

        elif event.key.upper() == 'K':
            self._solve_cube_kociemba()

        elif event.key.upper() == 'O':
            self._solve_cube_korf()

        elif event.key.upper() == 'N':
            self._solve_cube_nnet()

        elif event.key.upper() == 'P':
            self.figure.savefig('cubeSnapshot.eps')

        self._draw_cube()
        isSolved = self.Environment.checkSolved(self._colors)
        if isSolved:
            print("SOLVED!")
            self._move_list = []
            self._prevStates = []
コード例 #35
0
class Cube:
    """Magic Cube Representation"""
    # define some attribues
    default_plastic_color = 'black'
    default_face_colors = [
        "w", "#ffcf00", "#00008f", "#009f0f", "#ff6f00", "#cf0000", "gray",
        "none"
    ]
    base_face = np.array(
        [[1, 1, 1], [1, -1, 1], [-1, -1, 1], [-1, 1, 1], [1, 1, 1]],
        dtype=float)
    stickerwidth = 0.9
    stickermargin = 0.5 * (1. - stickerwidth)
    stickerthickness = 0.001
    (d1, d2, d3) = (1 - stickermargin, 1 - 2 * stickermargin,
                    1 + stickerthickness)
    base_sticker = np.array([[d1, d2, d3], [d2, d1, d3], [-d2, d1, d3],
                             [-d1, d2, d3], [-d1, -d2, d3], [-d2, -d1, d3],
                             [d2, -d1, d3], [d1, -d2, d3], [d1, d2, d3]],
                            dtype=float)

    base_face_centroid = np.array([[0, 0, 1]])
    base_sticker_centroid = np.array([[0, 0, 1 + stickerthickness]])

    # Define rotation angles and axes for the six sides of the cube
    x, y, z = np.eye(3)
    rots = [
        Quaternion.from_v_theta(x, theta) for theta in (np.pi / 2, -np.pi / 2)
    ]
    rots += [
        Quaternion.from_v_theta(y, theta)
        for theta in (np.pi / 2, -np.pi / 2, np.pi, 2 * np.pi)
    ]

    # define face movements
    facesdict = dict(F=z, B=-z, R=x, L=-x, U=y, D=-y)

    def __init__(self, N=3, plastic_color=None, face_colors=None):
        self.N = N
        if plastic_color is None:
            self.plastic_color = self.default_plastic_color
        else:
            self.plastic_color = plastic_color

        if face_colors is None:
            self.face_colors = self.default_face_colors
        else:
            self.face_colors = face_colors

        self._move_list = []
        self._initialize_arrays()

    def _initialize_arrays(self):
        # initialize centroids, faces, and stickers.  We start with a
        # base for each one, and then translate & rotate them into position.

        # Define N^2 translations for each face of the cube
        cubie_width = 2. / self.N
        translations = np.array(
            [[[-1 + (i + 0.5) * cubie_width, -1 + (j + 0.5) * cubie_width, 0]]
             for i in range(self.N) for j in range(self.N)])

        # Create arrays for centroids, faces, stickers, and colors
        face_centroids = []
        faces = []
        sticker_centroids = []
        stickers = []
        colors = []

        factor = np.array([1. / self.N, 1. / self.N, 1])

        for i in range(6):
            M = self.rots[i].as_rotation_matrix()
            faces_t = np.dot(factor * self.base_face + translations, M.T)
            stickers_t = np.dot(factor * self.base_sticker + translations, M.T)
            face_centroids_t = np.dot(self.base_face_centroid + translations,
                                      M.T)
            sticker_centroids_t = np.dot(
                self.base_sticker_centroid + translations, M.T)
            colors_i = i + np.zeros(face_centroids_t.shape[0], dtype=int)

            # append face ID to the face centroids for lex-sorting
            face_centroids_t = np.hstack(
                [face_centroids_t.reshape(-1, 3), colors_i[:, None]])
            sticker_centroids_t = sticker_centroids_t.reshape((-1, 3))

            faces.append(faces_t)
            face_centroids.append(face_centroids_t)
            stickers.append(stickers_t)
            sticker_centroids.append(sticker_centroids_t)
            colors.append(colors_i)

        self._face_centroids = np.vstack(face_centroids)
        self._faces = np.vstack(faces)
        self._sticker_centroids = np.vstack(sticker_centroids)
        self._stickers = np.vstack(stickers)
        self._colors = np.concatenate(colors)

        self._sort_faces()

    def _sort_faces(self):
        # use lexsort on the centroids to put faces in a standard order.
        ind = np.lexsort(self._face_centroids.T)
        self._face_centroids = self._face_centroids[ind]
        self._sticker_centroids = self._sticker_centroids[ind]
        self._stickers = self._stickers[ind]
        self._colors = self._colors[ind]
        self._faces = self._faces[ind]

    def rotate_face(self, f, n=1, layer=0):
        """Rotate Face"""
        if layer < 0 or layer >= self.N:
            raise ValueError('layer should be between 0 and N-1')

        try:
            f_last, n_last, layer_last = self._move_list[-1]
        except:
            f_last, n_last, layer_last = None, None, None

        if (f == f_last) and (layer == layer_last):
            ntot = (n_last + n) % 4
            if abs(ntot - 4) < abs(ntot):
                ntot = ntot - 4
            if np.allclose(ntot, 0):
                self._move_list = self._move_list[:-1]
            else:
                self._move_list[-1] = (f, ntot, layer)
        else:
            self._move_list.append((f, n, layer))

        v = self.facesdict[f]
        r = Quaternion.from_v_theta(v, n * np.pi / 2)
        M = r.as_rotation_matrix()

        proj = np.dot(self._face_centroids[:, :3], v)
        cubie_width = 2. / self.N
        flag = ((proj > 0.9 - (layer + 1) * cubie_width) &
                (proj < 1.1 - layer * cubie_width))

        for x in [self._stickers, self._sticker_centroids, self._faces]:
            x[flag] = np.dot(x[flag], M.T)
        self._face_centroids[flag, :3] = np.dot(self._face_centroids[flag, :3],
                                                M.T)

    def draw_interactive(self):
        fig = plt.figure(figsize=(5, 5))
        fig.add_axes(InteractiveCube(self))
        return fig
コード例 #36
0
    def __init__(self,
                 cube=None,
                 interactive=True,
                 view=(0, 0, 10),
                 fig=None,
                 rect=[0, 0.16, 1, 0.84],
                 **kwargs):
        if cube is None:
            self.cube = Cube(3)
        elif isinstance(cube, Cube):
            self.cube = cube
        else:
            self.cube = Cube(cube)

        self._view = view
        self._start_rot = Quaternion.from_v_theta((1, -1, 0), -np.pi / 6)

        if fig is None:
            fig = plt.gcf()

        # disable default key press events
        callbacks = fig.canvas.callbacks.callbacks
        del callbacks['key_press_event']

        # add some defaults, and draw axes
        kwargs.update(
            dict(aspect=kwargs.get('aspect', 'equal'),
                 xlim=kwargs.get('xlim', (-2.0, 2.0)),
                 ylim=kwargs.get('ylim', (-2.0, 2.0)),
                 frameon=kwargs.get('frameon', False),
                 xticks=kwargs.get('xticks', []),
                 yticks=kwargs.get('yticks', [])))
        super(InteractiveCube, self).__init__(fig, rect, **kwargs)
        self.xaxis.set_major_formatter(plt.NullFormatter())
        self.yaxis.set_major_formatter(plt.NullFormatter())

        self._start_xlim = kwargs['xlim']
        self._start_ylim = kwargs['ylim']

        # Define movement for up/down arrows or up/down mouse movement
        self._ax_UD = (1, 0, 0)
        self._step_UD = 0.01

        # Define movement for left/right arrows or left/right mouse movement
        self._ax_LR = (0, -1, 0)
        self._step_LR = 0.01

        self._ax_LR_alt = (0, 0, 1)

        # Internal state variable
        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._event_xy = None  # store xy position of mouse event
        self._shift = False  # shift key pressed
        self._digit_flags = np.zeros(10, dtype=bool)  # digits 0-9 pressed

        self._current_rot = self._start_rot  #current rotation state
        self._face_polys = None
        self._sticker_polys = None

        self._draw_cube()

        # connect some GUI events
        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_press_event', self._key_press)
        self.figure.canvas.mpl_connect('key_release_event', self._key_release)

        self._initialize_widgets()

        # write some instructions
        self.figure.text(0.05,
                         0.05, "Mouse/flechas ajustan vista\n"
                         " Teclas U/D/L/R/B/F Mueven las caras\n"
                         "L: Vertical Izquierda\n"
                         "R: Vertical Derecha\n"
                         "U: Horizontal Arriba\n"
                         "D: Horizontal Abajo\n"
                         "F: Rotación Adelante\n"
                         "B: Rotación Atras\n"
                         "(shift+tecla para rotar inverso)",
                         size=10)

        #Definitions for cube solving A* algorithm
        self.movList = ['L', 'R', 'U', 'D', 'F', 'B']
        self.deordering_movs = []
        self.prev_movs = []
        self.next_movs = []
        self.solve_movs = []
        self.mov_index = 0
        self.prev_index = 0
        self.cubo_org = [
            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
            19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
            36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
            53
        ]