【问题标题】:Make an object model of a rubik's cube制作魔方的对象模型
【发布时间】:2011-10-16 12:07:41
【问题描述】:

我做了一个小算法,可以让我解决纸上的魔方。

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

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

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

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

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

非常感谢

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 我会看一下,但有几件事我现在还不完全理解。谢谢
    • 这是一个仅链接的答案,这在 SO 上通常是不可接受的。
    【解决方案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 中),您会得到 ​​p>

    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)(或其他任意的瓷砖集合),这是没有意义的。但是这样做会很愚蠢......所以不要这样做;)

    【讨论】:

    • 我认为使用这种结构,很难进行旋转(而且这不是面向对象的)
    • 但我不明白方向是如何建模的。你只有 x-y-z 位置,所以现在我们将 A 放在位置 W,但是哪个面有哪个方向?
    • 我希望我的上一次编辑能帮助你理解我的想法……我不为人脸建模,我只为瓦片建模(一个人脸由 9 个瓦片组成)。
    • 我知道您只想对每个“立方体”的一个面进行建模,但我对矩阵表示法/操作不够熟悉,无法理解,例如:Why the top layer has elements which在您的示例中,Y=1 和 Y=2?一维的大小是多少?绝对不是面向对象的
    【解决方案3】:

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

    为了旋转魔方的边界切片,您必须旋转矩阵的两个边界切片。可以通过仅旋转一个矩阵切片来旋转中心切片。这种方法的优点是您可以执行简单的矩阵旋转,并且您可以在 3D 中做任何事情。您不必从一些平面 2D 投影重建 3D 外观。


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

    【讨论】:

      猜你喜欢
      • 2012-07-31
      • 2012-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-24
      • 1970-01-01
      • 1970-01-01
      • 2018-05-02
      相关资源
      最近更新 更多