制作一个魔方的对象模型

时间:2011-07-30 11:32:43

标签: c# object data-modeling rubiks-cube

我做了一个小算法,允许我在纸上解决一个魔方。

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

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

但我之间需要一些对象,以指定哪个地方是哪个立方体。

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

您对如何表示这一点有所了解吗?

非常感谢

3 个答案:

答案 0 :(得分:3)

This CodeProject's article看起来正是您所需要的。它还具有所有运动和求解器功能。

答案 1 :(得分:2)

我会建立这样的东西:

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;
        }

看看rotation matrices。旋转矩阵的优点在于它们总是围绕坐标系的中心(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)(或其他任意的瓷砖集合),这没有任何意义。但这样做会很愚蠢......所以不要这样做;)

答案 2 :(得分:2)

用5 x 5 x 5的颜色矩阵表示Rubik的立方体,其中只有6个矩阵表面中每个矩阵表面的3 x 3中心矩阵位置用于表示颜色。

enter image description here

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


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