# How can I create a sphere (or other shape) with cubes? (3D)

Hi everyone I am new generally in coding ( not only in Processing) so I need your help if you can. What I want to do is to design 10 types of cubes with different color shades ( from white to totally black) without having the same dimension and with those cubes to fill (create) a 3D shape for instance a sphere or a cone. I have seen some tutorials on Youtube and I found the below simple code in which I tried to change in order to do what I want, but guess what, I did nothing

size(400,300);
background(0);
strokeWeight(2);
stroke(255);
fill(127);

for (int y = 0; y < height; y = y+20) {
for (int x = 0; x < width; x = x+20){
fill(random(255));

rect(x, y, 20, 20);

}
}

You need a 3D Sketch when I understand you correctly.

I’ll be back in a second with an example.

Hey, and welcome to the forum!

Great to have you here!

Warm regards,

Chrisir

Sketch

Click mouse to enter a new cube. You can move the last cube in 3D with cursor keys and p and “l” (“L”). You need to add a size changer (e.g. + and - ) and add automatic color from white to black.
You could save the cube position on Hard Drive (hard to do) or make a screen shot (command save() associated with key ‘s’ for example).

• So you can make a sphere or a cone from cubes. I wouldn’t know how to do this automatically. Well, we could try.
// constants
final color BLACK  = color(0);
final color WHITE  = color(255);

final color RED    = color(255, 0, 0);
final color GREEN  = color(0, 255, 0);
final color BLUE   = color(0, 0, 255);

final color YELLOW = (#FFF80A);

// the cubes
ArrayList<Cube> cubes = new ArrayList();

// -------------------------------------------------------------------------------------

void setup() {
size( 1200, 900, P3D ); // 3D Mode

//text
textMode(SHAPE);

// add one cube - delete this
Cube newCube = new Cube();
newCube.pos=new PVector(60, 310, -60);
newCube.colorForCube = color ( RED ) ;
cubes.add(newCube);
//
}//func

void draw() {

background(0);

// 3D part ---
lights();

for (Cube currentCube : cubes) {
currentCube.display();
}

// 2D part ---
showMessages();
}//func

// -----------------------------------------------------------------------------

void showMessages() {
// 2D part ---

// prepare for 2D
hint(DISABLE_DEPTH_TEST);
camera();
noLights();

// 2D code
fill(255);
text("Place cubes with Mouse. Move last cube in Z with Cursor up and down (and left/right and p/l)", 17, 17);
if (cubes.size()>0) {
text("Last cube x,y,z: "
+cubes.get(cubes.size()-1).pos.x
+","
+cubes.get(cubes.size()-1).pos.y
+","
+cubes.get(cubes.size()-1).pos.z, 17, 35);
}

// reset for 3D again
hint(ENABLE_DEPTH_TEST);
}

// ------------------------------------------------------------------------
// Inputs

void mousePressed() {
// add cube at mouse pos with z = 0.
addCube(new PVector(mouseX, mouseY, 0));
}

void keyPressed() {

if (key==CODED) {

// CODED

switch(keyCode) {
case UP:
cubes.get(cubes.size()-1).pos.z-=10;
break;

case DOWN:
cubes.get(cubes.size()-1).pos.z += 10;
break;

case LEFT:
cubes.get(cubes.size()-1).pos.x-=10;
break;

case RIGHT:
cubes.get(cubes.size()-1).pos.x += 10;
break;
}//switch 1
}
//-------

else {

// not CODED

switch(key) {
case 'p':
cubes.get(cubes.size()-1).pos.y-=10;
break;

case 'l':
cubes.get(cubes.size()-1).pos.y += 10;
break;
}//switch 2
} // else
}//func

// ------------------------------------------------------------------------
// Tools

void addCube(PVector pos_) {

Cube newCube = new Cube();
newCube.pos=pos_.copy();
newCube.colorForCube = color ( RED ) ;

cubes.add(newCube);
//
} // func

// =======================================================================

class Cube {

// one cube

PVector pos;
color colorForCube;

void display() {
pushMatrix();
stroke(111);
fill(colorForCube);
translate(pos.x, pos.y, pos.z);
box(60);
popMatrix();
}
//
}//class
//

You can use Pythagoras to test whether a 3d position is inside a 3d field. I think there is no definition for dist (x,y,z,x2,y2,z2) but you can apply pythagoras twice:

boolean insideSphere(
float cx,  float cy, float cz,   /*center*/
float radius,                           /*radius*/
float px, float py, float pz   /*test point*/
)
{
float x=px-cx;
float y=py-cy;
float cz=pz-cz;
float R=radius*radius;
if (R<(x*x+y*y+z*z)){
return TRUE;
}
return FALSE;
}

Please note I left maths when I was 15 years old. So maybe there is an easier way.

thanks!

A few minor typos, check this:

boolean insideSphere(
float cx, float cy, float cz, /*center*/
float radius, /*radius*/
float px, float py, float pz   /*test point*/
)
{
float x=px-cx;
float y=py-cy;
float z=pz-cz;
float R=radius*radius;
if ((x*x+y*y+z*z) < R) {
return true;
}
return false;
}

can be shortened to

boolean insideSphere (
float cx, float cy, float cz, // center
float radius, // radius
float px, float py, float pz    // test point
) {
PVector center = new PVector(cx, cy, cz);
PVector testPoint = new PVector(px, py, pz);
return center.dist(testPoint) < radius;
}

Full code with peasy cam (and some PVector stuff):

import peasy.*;

PeasyCam peasyCam;

PVector center;  // center
PVector testPoint=new PVector();  // test point

// -------------------------------------------

void setup() {
size(1400, 940, P3D);
peasyCam = new PeasyCam(this, 1000);
center = new PVector(0, 0, 0);
}

void draw() {
background(255);
lights();
fill(255, 0, 0);

int radiusSphere=200;
for (int x=-radiusSphere; x<radiusSphere; x+=22) {
for (int y=-radiusSphere; y<radiusSphere; y+=22) {
for (int z=-radiusSphere; z<radiusSphere; z+=22) {

if (insideSphere(radiusSphere/2,
x, y, z)) {
pushMatrix();
translate(x, y, z);
box(22-1);
popMatrix();
}
}
}
}

peasyCam.beginHUD();
noLights();
fill(0);
text("Use PeasyCam by dragging the mouse, pan etc. ", 12, 12);
peasyCam.endHUD();
}

// -------------------------------------------

boolean insideSphere ( float radius, // radius
float px, float py, float pz    // test point
) {
testPoint.set(px, py, pz);
return
center.dist(testPoint) < radius;
}
//

1 Like

Hi! I detected my typo but I was too lazy to make a last edit to my post.

Thank you for the example with peasycam. I find wery frustrating the control of the camera. PeasyCam makes it easier!

1 Like

But still, the cubes are all the same in my example (and far too many)

That’s not really the idea

When the initial cubes have a fixed and individual size (and color) we need an array (or ArrayList) and a class Cube and some kind of optimization algorithm to pack them in a good way (when you want to do it automatically by an algorithm) - hard !

It’s unclear whether you mean

• cubes (all six faces have the same size) of different sizes or
• also cuboids (six faces of 3 different sizes) of different sizes.

Do you want to arrange the cubes or cuboids with or without overlapping? Is it really in 3D? Do you want to make the arrangement

• automatically or
• by user input, with mouse or keyboard?

Chrisir

P.S.

here is a similar example

A cube of 3x3x3 has to be filled with pieces

1 Like