… or even a half-decent programmer, but I’d like to have a stab at doing a “Rubik’s Cube” type animation on my Uno-controlled 8x8x8 RGB LED Cube.
Obviously it’s 8x8x8, so could go for an 8-cube : 4x4x4, or a 64-cube : 2x2x2 arrangement.
I have total control over each LED, and the whole cube is driven by x, y, and z co-ordinates - all 0-7.
Co-ordinate system is straightforward - 0,0,0 is the left-hand, bottom, nearest LED, and 7,7,7 the right-hand, top, furthest LED.
Now, just like a Rubik’s Cube, I’m only going to be lighting the 6 outer faces, so only need 6 colours.
I haven’t really got a clue where to start with the math involved in rotating a side, to simulate a Rubik’s Cube plane spin… obviously I could do all this manually, and punch in the co-ordinates/colours into a table in the code, but I’d like the display to be random, i.e. not repeating itself every time this particular animation comes round. I’d therefore like the code to generate the transforms itself based on a random choice of which plane to “spin”.
Hoping someone has done something similar, and can put me on the right track…
I’m struggling to decide whether to manipulate the x,y,z co-ordinates during transforms, or perhaps to use the attached diagram as the basis (I’ll obviously have to make it 4x4x4).
I’m thinking each row and column in the diagram can be a shift register for plane spins, and square faces can be “rotated” as applicable. Once each move is made, map the diagram to the SetPixel(x,y,z,colour) function.
Without that diagram, I can’t think of a way of mathematically manipulating the x,z,y co-ords directly.
I would think the position engine to figure out the sides would resemble the physical cube.
If you take a real cube apart you could consider the center hub as a fixed point in a coordinate system.
Always at (0,0,0)
Each piece then has coordinate to locate relative to the center (x,y,z) plus and minus.
So there are 6 centers 12 edges and 8 corners.
The centers could be considered fixed at (0,0,1)(0,0,-1)(0,1,0)(0,-1,0)(1,0,0) and (-1,0,0).
(they don’t have to be, but start here)
The next problem is the color and orientation of the face.
You could use a Color and normal direction for each type.
A corner defined could be (R,0,1,0)+(Y,0,0,1)+(B,-1,0,0)
You read this corner as Red face is on the +Y side, Yellow +Z side, and Blue -X side.
If this corner is at (-1,1,1), the red face is at -1,2,1 add together color + plus location.
This is your led ID and color. For each face in the element add and map the color.
An edge is similar but needs 2 face elements (R,0,1)+(B,-1,0)…
You now have a coordinate system to “paint” the cube to your display.
All moves are a rotation in a plane and involve the 8 parts that move.
Rotate about x y or z. A corner at (-1,1,1) rotated + 90 degrees about Y becomes (1,1,1)
Rotate 180 becomes (1,1,-1) rotate 270 (-1,1,-1).
You notice the Y never changes as the corner rotates about.
An edge initially at (-1,1,0) becomes 90deg(0,1,1) @180 (1,1,0) @ 270(0,1,-1)
You can program these interchanges into a sub routine for each axis and direction.
That would be 6 routines and a lot of code. This is not the most elegant, but will work.
The faces are also rotated and moved.
You said you were not great at math… But this is worth taking a look.
Look at the 90 degree rotation matrix under common rotations.
All of those coordinates may be proceed thru a matrix multiplication to get the new ordinate locations.
Thanks Qsilverrdc, some of what you said started to make some sense, and I'll certainly take a look at the link you posted.
I sort of got the idea about placing the x,y,z origin at the centre of the cube, it might make the transforms easier to work with, but then the picture you attached threw me a lot... how can any co-ordinate be more 1 away from the centre on a 3x3x3 ??
I think, until I know better, I'm going to pursue the "sliding blocks" method (shift registers), build the wrap-around rules etc., and then finalise each move with a mapping into my conventional x,y,z matrix.
I think the level of my math skills can work with that scenario more easily.
I only need to do a 4x4x4 matrix, as each location would map to 4 pixels on my 8x8x8 cube. The face rotations might look clunky, but it's a brief moment for each movement, so shouldn't look too bad....
I sort of got the idea about placing the x,y,z origin at the centre of the cube, it might make the transforms easier to work with, but then the picture you attached threw me a lot… how can any co-ordinate be more 1 away from the centre on a 3x3x3 ??
I was trying to show you that the face color can be considered to be 1 unit away as the center. (see attached)
The face then has a unique location and you can process the face thru the same function. Then add together to get the mapping.
The final coordinates, the results of the add, you will get 6 faces from the centers.
24 faces from the 12 edges. And 24 faces from the 8 corner pieces.
That adds up to the 54 total faces which is good.
So the center face on X is at (2,0,0) the negative side is (-2,0,0)
A corner (1,1,1) that consists of 3 faces would be something like,
(2,1,1), (1,2,1), and (1,1,2)
But some parts are connected so you also need a piece identifier so add the ID
ID,Color,x,y,z (remember the xyz’s are -2 to +2)
These would need to be initialized.
I would also probably add a rotate needed flag RotF
The rotate about a layer function would find all the faces and related faces, flag for rotate, then perform the appropriate rotate on the X,Y,Z’s for those elements.