views:

260

answers:

3

I'm trying to create a Rubik's Cube in Flash & Papervision and i'm really stuck here. I'm up to the point where i can rotate any plane of cubes once, but after that...it's messed up because all local coordinate systems are messy.

I dont really know where to go from here, can anybody give any advice on what do do? I'm not looking for 'read about transformation matrices', i know i should (and i am doing that), but i'm not really sure what to look for. My idea is that, after each rotation, i should fix each coordinate system of each cube again, but i have no idea how. Any hints on what i want to achieve (in words), and why, are much appreciated.

http://dl.dropbox.com/u/250155/rubik/main.html (use cursorkeys + A & D)

A: 

Perhaps you could store the position and orientation of each of the 26 cubes that make up a Rubik's cube, and calculate the coordinates and colors when you need to display.

For instance, the front face (however you define front) would have the position (0,0,0) through (2,2,0). I'm using x, y, and z; where x goes from left to right, y goes from top to bottom, and z moves through the cube.

The orientation would be from 0 - 5, and correspond to the color on the face of each small cube.

You would have to take into account the position of the user in relation to the front when drawing the Rubik's cube.

I'm not sure this would make the rotation methods easier, but at least your cube orientations would be correct.

Gilbert Le Blanc
+1  A: 

Hate to say it but, matrices are handy:

http://wonderfl.net/c/mwdp

papervision rubiks

Code is nicely commented too.

Another thing that comes to mind, if matrix are overkill is grouping/reparenting DisplayObject3D instances on the fly.

Say you have something as basic as this:

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

Those groups would only help for a few situations, but not all, the thing to keep in mind is you can name and group DO3D's

Say you click and drag one tiny cube:

  1. figure out if it's position on the current active face(collection of 3X3 boxes).
  2. based on that you know what group of 3 it belongs, therefore, what group of 3X3X1 cubes to rotate as a group
  3. based on the current mouse position minus the previous one, you know what direction to rotate towards.

HTH, George

George Profenza
@Eindbaas this just popped on the papervision mailing list, check it out: http://setvelocity.blogspot.com/2010/03/first-ever-papervision3d-experiment.html
George Profenza
A: 

Here you can find an ACM paper that describes alternatives of the Rubik’s cube representation.

When I was doing the Rubik's cube in Ruby I was short in time and decided to monkey-code the logic myself. It works rather well for the 3×3×3 cube, but the realization is very bad.

gist.github.com/377665

I was using the following matrix to represent the cube in memory:

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

I outlined a set of rules for shifts of rows or columns and rotations for outer sides for specific moves. I placed these rules as leaves into a tree. Higher-level nodes of this tree were guidelines for move types, directions, and row or column numbers. For a specific situation, I was extracting a correspondent set of rules for transformation of the 2-D array that was representing the Rubik’s cube and then performing them one by one.

Here is the source file in Ruby (creepy code warning!):

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

Please consider checking the RubikStructure class, the RubikStructure::RULES hash, and the RubikStructure#rotate method.

I hope it will help somehow.

toksaitov.d