Сделайте объектную модель кубика Рубика - PullRequest
2 голосов
/ 30 июля 2011

Я сделал небольшой алгоритм, который позволяет мне распознать кубик рубика на бумаге.

Теперь я хочу реализовать это, но не могу найти представление объекта, которое меня удовлетворило.

Я легко вижу объект rubiksCube и объект "куб", который может быть реализован гранью, углом или ребром.

Но мне нужно несколько объектов между ними, чтобы указать, на каком месте какой куб.

Конечная цель состоит в том, чтобы я мог легко повернуть ее.

У вас есть идея о том, как это представить?

Большое спасибо

Ответы [ 3 ]

3 голосов
/ 30 июля 2011

Эта статья CodeProject выглядит именно то, что вам нужно.Он имеет все функции и решает функции.

2 голосов
/ 18 ноября 2012

Представляет кубик Рубика с помощью матрицы цветов 5 x 5 x 5, в которой для представления цветов используются только позиции центра матрицы 3 x 3 каждой из 6 поверхностей матрицы.

enter image description here

Чтобы повернуть граничный срез кубика Рубика, вам нужно будет повернуть два граничных среза матрицы. Центральные срезы можно вращать, поворачивая только один срез матрицы. Преимущество этого подхода заключается в том, что вы можете выполнять простые повороты матрицы и делать все в 3D. Вам не нужно восстанавливать трехмерный вид из какой-то плоской 2D-проекции.


Примечание. Этот «преувеличенный» размер необходим, поскольку вы можете хранить только один цвет на ячейку матрицы. Взяв вместе две матрицы-среза, вы можете хранить два цвета для краев и три цвета для углов.

2 голосов
/ 30 июля 2011

Я бы построил что-то вроде этого:

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) (или другой произвольный набор плиток), что не имеет смысла.Но делать это было бы глупо ... так что не делай этого;)

...