Как исправить вращения в кубике Рубика?

Я пытаюсь создать кубик Рубика в Flash & Papervision, и я действительно застрял здесь. Я дошел до того, что могу повернуть любую плоскость кубов один раз, но после этого... это запутано, потому что все локальные системы координат запутаны.

Я действительно не знаю, куда идти отсюда, может ли кто-нибудь дать совет о том, что делать? Я не ищу «читать о матрицах преобразования», я знаю, что должен (и я это делаю), но я не совсем уверен, что искать. Моя идея состоит в том, что после каждого поворота я должен снова фиксировать каждую систему координат каждого куба, но я понятия не имею, как это сделать. Любые намеки на то, чего я хочу достичь (на словах) и почему, очень ценятся.

http://dl.dropbox.com/u/250155/rubik/main.html (используйте клавиши курсора + A и D)


person Eindbaas    schedule 16.05.2010    source источник
comment
взгляните на Rubic Cube: вращение кватерниона не работает как исключение   -  person Spektre    schedule 18.08.2016


Ответы (3)


Ненавижу это говорить, но матрицы удобны:

http://wonderfl.net/c/mwdp

http://wonderfl.net/images/capture/9/9d/9dd4/9dd41cd57b2f042f38bf450a41da77ab45348892.jpg

Код также хорошо прокомментирован.

Еще одна вещь, которая приходит на ум, если матрица излишня, — это группировка/переподчинение экземпляров DisplayObject3D на лету.

Скажем, у вас есть что-то вроде этого:

var cubes:DisplayObject3D = new DisplayObject3D();
            cubes.name = 'cubes';
            for(var i:int = 0 ; i < boxDivisions ; i++){
                var zBoxes:DisplayObject3D = new DisplayObject3D();
                zBoxes.name = 'zBoxes_'+i;
                for(var j:int = 0 ; j < boxDivisions; j++){
                    var yBoxes:DisplayObject3D = new DisplayObject3D();
                    for(var k:int = 0 ; k < boxDivisions ; k++){
                        var box:Cube = new Cube(materials,boxSize,boxSize,boxSize);
                        box.material = box.material.clone();
                        box.material.fillColor = Math.random() * 0xFFFFFF;
                        box.x = ((boxDivisions-1) - (k+1)) * (boxSize + boxSpacing);
                        box.name = 'box_'+i+''+j+''+k;
                        yBoxes.addChild(box,'box_'+i+''+j+''+k);
                    }
                    yBoxes.y = ((boxDivisions-1) - (j+1)) * (boxSize+boxSpacing);
                    yBoxes.name = 'yBoxes_'+j;
                    zBoxes.addChild(yBoxes);
                }
                zBoxes.z = ((boxDivisions-1) - (i+1)) * (boxSize+boxSpacing);
                cubes.addChild(zBoxes);
            }
            basicView.scene.addChild(cubes);

Эти группы помогут только в нескольких ситуациях, но не во всех. Следует помнить, что вы можете называть и группировать DO3D.

Скажем, вы щелкаете и перетаскиваете один крошечный куб:

  1. выяснить, является ли это положением на текущей активной грани (коллекция коробок 3X3).
  2. на основании этого вы знаете, к какой группе из 3 он принадлежит, следовательно, какую группу кубов 3X3X1 вращать как группу
  3. основываясь на текущей позиции мыши минус предыдущая, вы знаете, в каком направлении нужно повернуться.

ХТХ, Джордж

person George Profenza    schedule 17.05.2010
comment
@Eindba, поскольку это только что появилось в списке рассылки papervision, проверьте это: setvelocity.blogspot.com/2010/03/ - person George Profenza; 16.09.2010

Возможно, вы могли бы хранить положение и ориентацию каждого из 26 кубиков, составляющих кубик Рубика, и вычислять координаты и цвета, когда вам нужно их отобразить.

Например, передняя грань (как бы вы ни определили переднюю) будет иметь положение от (0,0,0) до (2,2,0). Я использую x, y и z; где x идет слева направо, y идет сверху вниз, а z движется по кубу.

Ориентация будет от 0 до 5 и будет соответствовать цвету на грани каждого маленького кубика.

При рисовании кубика Рубика вам нужно будет учитывать положение пользователя по отношению к фронту.

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

person Gilbert Le Blanc    schedule 16.05.2010

Здесь вы можете найти документ ACM, в котором описаны альтернативы Представление кубика Рубика.

Когда я собирал кубик Рубика на Ruby, у меня было мало времени, и я решил сам программировать логику. Для куба 3×3×3 это работает неплохо, но реализация очень плохая.

gist.github.com/377665

Я использовал следующую матрицу для представления куба в памяти:

Spreadsheets.google.com/ccc?key=0As1DrYDLh7F6dGROZFRoOTFDOThVMUFENjRWM0xJbVE&hl=en

Я наметил набор правил для сдвигов строк или столбцов и поворотов для внешних сторон для определенных ходов. Я разместил эти правила в виде листьев на дереве. Узлы более высокого уровня этого дерева служили ориентирами для типов движений, направлений и номеров строк или столбцов. Для конкретной ситуации я извлекал соответствующий набор правил для преобразования двумерного массива, представляющего кубик Рубика, и затем выполнял их одно за другим.

Вот исходный файл на Ruby (предупреждение о жутком коде!):

github.com/toksaitov/scenario/blob/master/lib/scenario/objects/rubik.rb

Пожалуйста, рассмотрите возможность проверки класса RubikStructure, хэша RubikStructure::RULES и метода RubikStructure#rotate.

Я надеюсь, что это поможет как-то.

person toksaitov    schedule 17.05.2010