How
to draw the Rubik’s Cube?
(Compare with the method drawCube (int number) in DrawRubiksCube.class)
First we produce one little cube drawing and scaling
only its visible sides . Each little cube is added to its own TransformGroup.
This TransformGroup sets the little cube to its position in the Rubik’s
Cube.
In this way the whole Rubik’s Cube is put together.
All the TransformGroups of the little cubes are
combined to one TransformGroup.
So it is possible to manipulate the little cubes
(scaling/ setting transparency/ making the inside of the little cubes visible)
and the Rubik’s Cube (scaling/ rotating).
Our algorithm draws the Rubik’s Cube in the following way:
The parameter number of drawCube (int number) decides
if a 2x2x2, 3x3x3, 4x4x4, 5x5x5 or 6x6x6 Cube is drawn.
A vertical column is fixed. The lowest row is drawn
from front to back, then the row above and so on.
In this manner all the other columns are drawn.
Problem:
The Rubik’s Cube must be set exactly in the origin,
so that the animation of each possible Rubik’s Cube is correct.
How to calculate the positions of each little cube?
Our solution:
The length of the edges is given and for each size
of the Rubik’s Cube the same.
Then you have to spread the number of the little
cubes in one row /column over the given length of the edge.
(E.g. in a 3x3x3 Rubik’s Cube you have to distribute
3 little cubes)
You have to calculate exactly the start position
of the first little cube . After that you have to determine the distance
between the centres of the little cubes, so that the cubes can be set to
the right position. Dependent on the distance you have to scale the surfaces
of the little cubes.
In our program the start positions of the different
Rubik’s Cubes are constant values.
The distance and the scale are computed at runtime.
The first little cube is set to the start position. All the following
cubes are set in the computed distance.
Here
are the formulas we have used to calculate the start position:
-
Length of the edge
= 0.42 (this value was laid down by us)
-
Surface area of one little cube = length of the edge / number of the little
cubes in one row
-
Distance to the next little cube = 2 * surface area of one little cube
-
Start position
= ((number of the little cubes in one row – 1) * distance to the next
little cube) / 2
Each cube has six faces. We have called them FRONT, RIGHT,BACK, LEFT,
TOP and BOTTOM. The front is coloured orange, the right is red, back is
green, left is yellow, top is white and the bottom is blue. The colour
of each little face is saved with a number from 0 to 5 in each MyShape3Dof
RealCubes. And all MyTransformGroups where a RealCube is hanging have three
numbers, one for x-direction, one
for y and one for z. This numbers are set if the Rubik's cube is drawing.
If you want to rotate a face (the togglebutton cube/face must be on
face) you must draw the mouse over a black line. The algorithm ComputeDirection
in PickFaceAndRotateBehavior computes the first and the last little cube
which you have choosen. With the result it computes the direction and it
calls ComputeSiteOfRotation in DrawRubiksCube class. ComputeSiteOfRotation
encodes (kodieren ???) all the results and calls RotateSite. RotateSite
computes all the little cubes which must be rotated. A thread is started
and in this thread a loop counts the steps of tiny rotations, so that the
full rotation is ninety degrees. The appearance is an animated rotation.
We used no Interpolators of Java3D classes because we have so many little
cubes. With so many Interpolators the performance would be bad.
After the matrix multiplications the number of faces must be updated
so that all little cubes have their same names relative to each other as
it is before the rotation. The surfaces are colourful but the names of
the faces are already the same to each other. The x,y and z-values of MyTransformGroup
are updated with the same principle. So you can always use this algorithm.
The whole cube is usually the same as the beginning.