制作魔方的对象模型

发布于 2024-11-27 05:57:52 字数 223 浏览 1 评论 0原文

我制作了一个小算法,可以让我解决纸上的魔方问题。

我现在想实现它,但我找不到令我满意的对象表示。

我很容易就能看到一个 rubiksCube 对象,以及一个“立方体”对象,它可以通过面、角或边来实现。

但我需要它们之间的一些对象,以指定哪个位置是哪个立方体。

最终目标是我可以轻松地对其进行一些旋转。

您知道如何表示这一点吗?

非常感谢

I've made a small algo which allows me to resolve a rubik's cube on the paper.

I now want to implement it, but I can't found an object representation which satisfied me.

I easily can see a rubiksCube object, and a "cube" object, which can be implemented by a face, a corner or an edge.

But I need some objects between, to specify on which place is which cube.

The final goal is that I can easily make some rotation on it.

Do you have an idea about how to represent this?

Thank you very much

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

久随 2024-12-04 05:57:52

这篇 CodeProject 的文章看起来正是您所需要的。它也具有所有运动和解算器功能。

This CodeProject's article looks exactly what you need. It has all the movements and solvers funcs as well.

陌生 2024-12-04 05:57:52

我会构建这样的东西:

class Cube
    {
        List<Tile> Tiles = new List<Tile>(){
            // Front Face
            new Tile(Color.blue, -1, 1, 2), //top left corner tile
            new Tile(Color.blue,  0, 1, 2), //top middle tile
            new Tile(Color.blue,  1, 1, 2), //top right corner tile
            new Tile(Color.blue, -1, 0, 2), //middle left tile
            new Tile(Color.blue,  0, 0, 2), //center tile of this face
            new Tile(Color.blue,  0, 1, 2), //…
            new Tile(Color.blue, -1,-1, 2),
            new Tile(Color.blue,  0,-1, 2),
            new Tile(Color.blue,  1,-1, 2), //bottom right corner tile
            …
        };

立方体的中心是 (0, 0, 0),你可以想象这些点漂浮在实际的立方体上。小瓷砖被抽象为点,因此不需要定向。这样,所有正面图块的 z 坐标为 2,所有顶面图块的 y 坐标为 2,所有左面图块的 x 坐标为 -2,依此类推。

        IEnumerable<Tile> TopLayer
        {
            get
            {
                return Tiles.Where(f => f.Position.Y == 2 || f.Position.Y == 1);
            }
        }

        IEnumerable<Tile> BottomLayer {…}

        Color getTileColor(int x,int y,int z)
        {
            return Tiles.Single(t => t.Position.X == x && t.Position.Y == y && t.Position.Z == z).Color;
        }

看一下旋转矩阵。旋转矩阵的美妙之处在于它们总是围绕坐标系的中心 (0, 0, 0) 旋转,当你有一堆点时(就像这里),旋转更像是圆周运动。
如果将 θ 设置为 90°(在 Rx 中),则

1  0  0
0  0 -1
0  1  0

可以将其转换为以下方法:

static void rotateLayerX(IEnumerable<Tile> layer)
{
    foreach (var tile in layer)
    {
        var x = tile.Position.X;
        var y = tile.Position.Y;
        var z = tile.Position.Z;
        tile.Position = new Point3D(x, -z, y);
    }
}

您只需调用 Cube.rotateLayerX(cube.LeftLayer) 即可。

    } // class cube

    class Tile
    {
        public Tile (Color c, int x, int y, int z)
        {
            Color  = c;
            Position = new Point3D(x,y,z);
        }

        Color Color { get; private set; } // enum Color {...}

        Point3D Position { get; set; }
    }

这只是一个简单的彩色点云。

你是对的,这个东西不是严格类型化的,它可以调用 Cube.rotateLayerX(Cube.TopLayer) (或其他任意的图块集合),这是没有意义的。但这样做是愚蠢的……所以不要这样做;)

I would build something like this:

class Cube
    {
        List<Tile> Tiles = new List<Tile>(){
            // Front Face
            new Tile(Color.blue, -1, 1, 2), //top left corner tile
            new Tile(Color.blue,  0, 1, 2), //top middle tile
            new Tile(Color.blue,  1, 1, 2), //top right corner tile
            new Tile(Color.blue, -1, 0, 2), //middle left tile
            new Tile(Color.blue,  0, 0, 2), //center tile of this face
            new Tile(Color.blue,  0, 1, 2), //…
            new Tile(Color.blue, -1,-1, 2),
            new Tile(Color.blue,  0,-1, 2),
            new Tile(Color.blue,  1,-1, 2), //bottom right corner tile
            …
        };

The center of the cube would be (0, 0, 0) and you could imagine these points floating over the actual cube. The little tiles are abstracted to points and therefor need no orientation. This way all front face tiles have a z-coordinate of 2, all top face tiles have a y-coordinate of 2, all left face tiles have a x-coordinate of -2 and so on.

        IEnumerable<Tile> TopLayer
        {
            get
            {
                return Tiles.Where(f => f.Position.Y == 2 || f.Position.Y == 1);
            }
        }

        IEnumerable<Tile> BottomLayer {…}

        Color getTileColor(int x,int y,int z)
        {
            return Tiles.Single(t => t.Position.X == x && t.Position.Y == y && t.Position.Z == z).Color;
        }

Take a look at rotation matrices. The beauty of rotation matrices is that they always rotate about the center of the coordinate system (0, 0, 0) and when you have a bunch of points(like here) the rotation is more like a circular movement.
If you set θ to 90°(in Rx) you get

1  0  0
0  0 -1
0  1  0

Which could be translated to the following Method:

static void rotateLayerX(IEnumerable<Tile> layer)
{
    foreach (var tile in layer)
    {
        var x = tile.Position.X;
        var y = tile.Position.Y;
        var z = tile.Position.Z;
        tile.Position = new Point3D(x, -z, y);
    }
}

Than you only have to call Cube.rotateLayerX(cube.LeftLayer).

    } // class cube

    class Tile
    {
        public Tile (Color c, int x, int y, int z)
        {
            Color  = c;
            Position = new Point3D(x,y,z);
        }

        Color Color { get; private set; } // enum Color {...}

        Point3D Position { get; set; }
    }

It's just a simple colored point cloud.

And you're right this thing is not strictly typed and it's possible call Cube.rotateLayerX(Cube.TopLayer)(or an other arbitrary collection of tiles), which makes no sense. But doing this would be stupid… so don't do it ;)

迷荒 2024-12-04 05:57:52

用 5 x 5 x 5 颜色矩阵表示魔方,其中仅使用 6 个矩阵表面中每一个的 3 x 3 中心矩阵位置来表示颜色。

在此处输入图像描述

为了旋转 Rubic 立方体的边界切片,您必须旋转矩阵的两个边界切片。可以通过仅旋转一个矩阵切片来旋转中心切片。这种方法的优点是您可以执行简单的矩阵旋转,并且可以在 3D 中执行所有操作。您不必从某些平面 2D 投影重建 3D 外观。


注意:这种“夸张”的大小是必需的,因为每个矩阵单元只能存储一种颜色。将两个矩阵切片放在一起,可以存储边缘的两种颜色和角的三种颜色。

Represent Rubik's cube by a 5 x 5 x 5 matrix of colors where only the 3 x 3 center matrix positions of each of the 6 matrix surfaces are used to represent the colors.

enter image description here

In order to rotate a border slice of Rubic's cube, you will have to rotate two border slices of the matrix. The center slices can be rotated by rotating the one matrix slice only. The advantage of this approach is that you can perform simple matrix rotations and that you can do everthing in 3D. You don't have to reconstruct the 3D appearance from some flat 2D projection.


Note: This "exaggerated" size is required, since you can only store one color per matrix cell. Taking two matrix-slices together, allows you to store two colors for the edges and three colors for the corners.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文