## Setting up a Rubik’s Cube in Papervision

December 31, 2008

Intro

Well it’s Christmas, and you’re right, one of the kids got a Rubik’s cube. And we’ve spent the entire break figuring it out – right down to the smallest child, even baby Na. It was a Rubik’s Cube free-for-all. And if that wasn’t enough, we had to make it virtual.

In this post, we’re going to show you a trick you can use to set up a Rubik’s Cube in just 8 lines of code. It uses the same trick that Mr. Doob uses on his blog – geometry.vertices. Below is an image of the cube you will make. Click on it to run the application.

Web Stuff

Demo

Discussion

Essentially what you want to do is create a single large cube and use its vertices to anchor the smaller cubes to create the Rubik’s cube . Large Cube

Segmenting the large cube with 2, 2, 2 (as shown in the image above)creates the coordinates of the Rubik’s cube

cubeGrid = new Cube(myMaterialsList1, mySize, mySize, mySize,2,2,2);

Placing small cubes at each vertex of the large cube is done using the geometry.vertices method.

Small Cubes

The geometry.vertices method gives you the position of each large cube vertex which is stored in the vertices array and accessed using the geometry.vertices method as shown below:

for(var i:int = 0; i<cubeGrid.geometry.vertices.length; i++)
{
var myPart:Cube = new Cube(materialArray[i], mySize/2.1,mySize/2.1,mySize/2.1,2,2,2);

myPart.x=cubeGrid.geometry.vertices[i].x;
myPart.y=cubeGrid.geometry.vertices[i].y;
myPart.z=cubeGrid.geometry.vertices[i].z;

particleArray.push(myPart);
}

That’s really all there is to it, the only other thing you need to do is to set the faces of the small cubes to the appropriate Rubiks’s Cube colors using a materials list array (materialArray). Just click the more button below to see the complete code listing.

Note: This only sets the cube up. In the book, I show you how to program a fully functioning Rubik’s Cube.

## Creating an Adjustable Carousel Primitive

November 12, 2008

Intro

Typically carousels are created by assembling single planes in a cylindrical configuration stacking rows as needed. But there is another way to do this. You can create a single primitive which constructs all the planes internally. Handling a single primitive requires fewer calculations to manipulate it than handling multiple planes. And you can do more with it.

To see a demo click on the image below. Try clicking on the images they are interactive.

Just as in the case of the cube primitive, the carousel primitive can be manipulated as a single primitive. And the number row and column numbers are adjustable.

Web Stuff

How it works

The carousel constructor function shown below gives you the ability to control the horizontal and vertical gap size, number of rows and columns, height and width, segments, and material list.

public function Carousel( materials:MaterialsList, myGap:Number=0, myHGap:Number=0 ,horizNum:int=1, vertiNum:int=1, width:Number=0, height:Number=0, segmentsW:Number=0, segmentsH:Number=0, initObject:Object=null )

Primitive Code

The carousel primitive was created by duplicating the Clickable Button Panel Primitive found in this blog and renaming the class and constructor function to Carousel. Then after adding the appropriate variables, the simple equation for a cylinder was used to place the primitives according to the angle and number created by the horizNum (number of images in a circular row).

var x :Number = myX*Math.cos(myThetaIs)+myZ*Math.sin(myThetaIs);

var z :Number = -myX*Math.sin(myThetaIs)+myZ*Math.cos(myThetaIs);

var y :Number = iy * iH -(textureY+myHGap/2)*(vertiNum/2-n);

var vertex:Vertex3D = new Vertex3D();

vertex[ “x” ] = x;
vertex[ “y” ] = y;
vertex[ “z” ] = z*10;

As the different x, y, and z values are created they are put into the vertex array just as was done in creating the clickable button panel. But notice the term vertex[ “z” ] = z*10; which has a multiplier of 10. This is an issue that must be investigated in the future.

The next issue was changing how the material was named. For the clickable button panel we used a matrix numbering scheme for the material name. We change this scheme when dealing with the carousel primitive to produce a sequential numbering system. This made the images easier to work with and the code is shown below.

var myNumber:Number= horizNum*n+m;
var myMaterial:String = “myMat”+myNumber;

Main Code

Since the carousel contains many images, we do not want to have to list them individually for the material list as we did in the Button Panel case. So we put the image address in a myBitmaps array and iterate through them as shown below to create the materials list.

var materialsList:MaterialsList = new MaterialsList();

for (var i:int = 0; i<myBitmaps.length; i++)
{

var myBitmapFileMaterial:BitmapFileMaterial = new BitmapFileMaterial(myBitmaps[i]);
trace(myBitmaps[i]);
myBitmapFileMaterial.doubleSided = true;

myBitmapFileMaterial.interactive = true;
myBitmapFileMaterial.name=”myMat”+i;

myBitmapFileMaterials.push(myBitmapFileMaterial);
trace(myBitmapFileMaterial.name);

}

for (var ik:int = 0; ik<myBitmaps.length; ik++)
{

}

This is a real time/code saver and can be used to bring in items from an external data base or xml page using HTTP Services.

The Big Problem

In Papervision, pixel measurements lose their meaning due to the 1/z parameter of perspective and as result you end up doing some adjusting. The is true for the carousel. If you change the gap or height components of the Carousel function you must readjust the following parameters to get the carousel to go to the correct image when clicking on it.