While experimenting with Processing and some basic OpenGL I created some stills reminding me of star signs. I started of with 2D graphics and dots improving the visual appearance with OpenGL. Later on I switched to the third dimension. In P3D mode I dropped OpenGL and replaced the initial circles with cuboids appearing in space.

The rotation of the matrix can be controlled with the mouse position. The inspiration for that functionality originated from a fairly old blogpost I read about how to rotate a cube.

### CODE

And here is the code:

```
// set all values -1 so we can see that no point has been assigned yet
float lastX1 = -1;
float lastY1 = -1;
float lastZ1 = -1;
float lastX2 = -1;
float lastY2 = -1;
float lastZ2 = -1;
float x = -1;
float y = -1;
float z = -1;
float r;
float area;
// for the rotation
float alpha = 0.0;
float theta = 0.0;
void setup()
{
size(1500,1500,P3D);
background(0);
frameRate(10);
smooth();
}
void draw()
{
translate(0,0,-100); // zoom out a bit
// rotation -------------------------------------------------
alpha += 0.01;
translate(width/2, height/2); //translate the coordinates
int t_mouseX = mouseX - width/2; //x of mouse after translation
int t_mouseY = mouseY - height/2; //y of mouse after translation
theta = atan2(t_mouseY, t_mouseX);
float speed = sqrt(sq(t_mouseX) + sq(t_mouseY)) / (width/4); //the far the mouse to the center is, the faster it rotate
rotateZ(theta); //rotate Z first
rotateY(alpha * speed); //rotate y then
// ---------------------------------------------------------
// draw boxes and lines -------------------------------------
// colors for the box
fill(50, 150, 200, random(10,100));
stroke(50, 150, 200, random(50,100));
r = random(width/100, width/10); // size of new box
// if no value has been assigned get a random start point
if(x == -1) {
x = random(width);
y = random(height);
z = random(0,100);
// if there was a previous point already, get a new one nearby (area)
} else {
area = width*0.3;
x = lastX1 + (random(area) * random(-1,1));
x = constrain(x, -10, width+10);
y = lastY1 + (random(area) * random(-1,1));
y = constrain(y, -10, height+10);
}
// draw a new box
pushMatrix();
translate(x, y, z);
box(random(r));
popMatrix();
// draw connecting lines to the ultimate and penultimate box
if(lastX1 > -1)
{
noFill();
stroke(255,50);
strokeWeight(0.5);
line(lastX1, lastY1, lastZ1, x, y, z);
if(lastX2 > -1) {
line(lastX2, lastY2, lastZ2, x, y, z);
}
// push stored values one further in history
// to be able to draw a line to the previous point as well
lastX2 = lastX1;
lastY2 = lastY1;
lastZ2 = lastZ1;
}
// store recent values to have them available in the next round
// for drawing connecting lines
lastX1 = x;
lastY1 = y;
lastZ1 = z;
// ---------------------------------------------------------
}
```