# Help with a exercise (making circle packing 3d)

Hello! I need help turning

this 2d code into 3d. I have recently started using processing, so 3d processing is a bit of a stretch for me. I am basically just trying to turn the circles into spheres, nothing more extreme, but I have no idea what I should do

The initial code is this

Box [] boxes;
int minSize = 20;
int maxSize = 50;
boolean collide = false;
void setup()
{
size(500, 500);
rectMode(CENTER);
ellipseMode(CENTER);
boxes = new Box;
for (int i = 0; i < boxes.length; i++)
{
boxes[i] = new Box(random(maxSize, width-maxSize), random(maxSize, height-maxSize), random(minSize, maxSize), color(0, random(10, 255), random(10, 255)));
}
}
void draw()
{
//background(200);
fill(200, 10);
rect(width/2, height/2, width+2, height+2);
for (int i = 0; i < boxes.length; i++)
{
boxes[i].draw();
}
//check distances between all the other boxes and attracts and collide!
for (int j = 0; j < boxes.length; j++)
{
for (int k = 0; k < boxes.length; k++)
{
if (j != k)
{
boxes[j].collide(boxes[k]);
boxes[j].attract(boxes[k]);
}
}
}
}
void mousePressed()
{
for (int i = 0; i < boxes.length; i++)
{
boxes[i].jiggle();
}
}

and the box class:

class Box
{
// step 1 = variables declaration
int frame = 0;
float posX;
float posY;
float velX;
float velY;
float side;
color c;
// step 2 = constructor, initializes the class
Box(float _posX, float _posY, float _side, color _c)
{
posX = _posX;
posY = _posY;
velX = random(-0.8, 0.8);
velY = random(-0.8, 0.8);
side = _side;
c = _c;
}
// step 3 = functions, functionality of the class
void draw()
{
posX += velX;
posY += velY;
pushMatrix();
translate(posX, posY);
ellipse(0, 0, side, side);
popMatrix();
//don’t let the boxes run away from the frame!
if ((posX < side || posX >= width-side)||(posY < side || posY >= height-side))
{
velX = -0.99velX;
velY = -0.99
velY;
}
//slow circles down over time
velX = .98velX;
velY = .98
velY;
}
void attract(Box b)
{
float d = dist(posX, posY, b.posX, b.posY); // calculate dist between boxes
float diffX = b.posX - posX; // difference of position in X
float diffY = b.posY - posY; // difference of position in Y
velX += 0.08*(diffX / (sq(d))); // change velocity by a ratio between dist and pos difference
velY += 0.08*(diffY / (sq(d)));
}
void collide(Box b)
{
float dis = dist(posX, posY, b.posX, b.posY);
//if (dis <= (sqrt(sq(side) + sq(side/2)) + sqrt(sq(b.side/2) + sq(b.side/2)))) // for boxes
float overlap = (side/2 + b.side/2) - dis;
if (overlap>0)
{
float diffX = b.posX - posX; // difference of position in X
float diffY = b.posY - posY; // difference of position in Y
float unitX = diffX/dis;
float unitY = diffY/dis;
velX -= 0.1unitXoverlap;
velY -= 0.1unitYoverlap;
}
}
void jiggle()
{
velX = random(-1, 1);
velY = random(-1, 1);
}
}

Thank you!

so im a beginner too but I know that you can call P3D to work in 3d.

you need to call it within size: size(500,500,P3D)

1 Like

yes, indeed, but that won’t turn the circles into spheres, it just changes the ‘world’ they live in.

I have tried few things, but I keep encountering an error saying posZ can not be float

here is a runable version of your code

Apologies, you posted in a way that some code was not correct anymore

``````

Box [] boxes;
int minSize = 20;
int maxSize = 50;
boolean collide = false;

// ----------------------------------------------------------------------
void setup() {
size(500, 500);
rectMode(CENTER);
ellipseMode(CENTER);
boxes = new Box;
for (int i = 0; i < boxes.length; i++)
{
boxes[i] = new Box(
random(maxSize, width-maxSize), random(maxSize, height-maxSize),
random(minSize, maxSize),
color(0, random(10, 255), random(10, 255)));
}
}

// ----

void draw() {
//background(200);
fill(200, 10);
rect(width/2, height/2, width+2, height+2);
for (int i = 0; i < boxes.length; i++)
{
boxes[i].draw();
}
//check distances between all the other boxes and attracts and collide!
for (int j = 0; j < boxes.length; j++)
{
for (int k = 0; k < boxes.length; k++)
{
if (j != k)
{
boxes[j].collide(boxes[k]);
boxes[j].attract(boxes[k]);
}
}
}
}

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

void mousePressed()
{
for (int i = 0; i < boxes.length; i++)
{
boxes[i].jiggle();
}
}

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

class Box
{
// step 1 = variables declaration
int frame = 0;
float posX;
float posY;
float velX;
float velY;
float side;
color c;

// step 2 = constructor, initializes the class
Box(float _posX, float _posY,
float _side,
color _c)
{
posX = _posX;
posY = _posY;
velX = random(-0.8, 0.8);
velY = random(-0.8, 0.8);
side = _side;
c = _c;
}

// -------

// step 3 = functions, functionality of the class
void draw()
{
posX += velX;
posY += velY;
pushMatrix();
translate(posX, posY);
fill(c);
ellipse(0, 0, side, side);
popMatrix();
//don’t let the boxes run away from the frame!
if ((posX < side || posX >= width-side)||(posY < side || posY >= height-side))
{
velX = -0.99*velX;
velY = -0.99*velY;
}
//slow circles down over time
velX = .98*velX;
velY = .98*velY;
}
void attract(Box b)
{
float d = dist(posX, posY, b.posX, b.posY); // calculate dist between boxes
float diffX = b.posX - posX; // difference of position in X
float diffY = b.posY - posY; // difference of position in Y
velX += 0.08*(diffX / (sq(d))); // change velocity by a ratio between dist and pos difference
velY += 0.08*(diffY / (sq(d)));
}
void collide(Box b)
{
float dis = dist(posX, posY, b.posX, b.posY);
//if (dis <= (sqrt(sq(side) + sq(side/2)) + sqrt(sq(b.side/2) + sq(b.side/2)))) // for boxes
float overlap = (side/2 + b.side/2) - dis;
if (overlap>0)
{
float diffX = b.posX - posX; // difference of position in X
float diffY = b.posY - posY; // difference of position in Y
float unitX = diffX/dis;
float unitY = diffY/dis;
velX -= 0.1*unitX*overlap;
velY -= 0.1*unitY*overlap;
}
}
void jiggle()
{
velX = random(-1, 1);
velY = random(-1, 1);
}
}//class
//

``````

Chrisir

oh, thank you!
do you have any idea how I could change it to 3d?

1 Like

here is a VERY quick change to 3D.

You have to make all collide and attract etc. stuff to 3D too…

Have you read the 3D tutorial: https://www.processing.org/tutorials/p3d/

Hey, and welcome to the forum!

Great to have you here!

Chrisir

``````

Box [] boxes;
int minSize = 20;
int maxSize = 50;
boolean collide = false;

// ----------------------------------------------------------------------
void setup() {
size(500, 500, P3D);
rectMode(CENTER);
ellipseMode(CENTER);
boxes = new Box;
for (int i = 0; i < boxes.length; i++)
{
boxes[i] = new Box(
random(maxSize, width-maxSize), random(maxSize, height-maxSize), random(maxSize, height-maxSize),
random(minSize, maxSize),
color(0, random(10, 255), random(10, 255)));
}
}

// ----

void draw() {
background(200);
lights();

fill(200, 10);
rect(width/2, height/2, width+2, height+2);

for (int i = 0; i < boxes.length; i++) {
boxes[i].draw();
}

//check distances between all the other boxes and attracts and collide!
for (int j = 0; j < boxes.length-1; j++)
{
for (int k = j+1; k < boxes.length; k++)
{
if (j != k)
{
boxes[j].collide(boxes[k]);
boxes[j].attract(boxes[k]);
}
}
}
}

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

void mousePressed()
{
for (int i = 0; i < boxes.length; i++)
{
boxes[i].jiggle();
}
}

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

class Box
{
// step 1 = variables declaration
int frame = 0;
float posX;
float posY;
float posZ;

float velX;
float velY;
float side;
color c;

// step 2 = constructor, initializes the class
Box(float _posX, float _posY, float _posZ,
float _side,
color _c)
{
posX = _posX;
posY = _posY;
posZ= _posZ;
velX = random(-0.8, 0.8);
velY = random(-0.8, 0.8);
side = _side;
c = _c;
}

// -------

// step 3 = functions, functionality of the class
void draw()
{
posX += velX;
posY += velY;
pushMatrix();
translate(posX, posY, posZ);
noStroke();
fill(c);
// ellipse(0, 0, side, side);
sphere(side);
popMatrix();
//don’t let the boxes run away from the frame!
if ((posX < side || posX >= width-side)||(posY < side || posY >= height-side))
{
velX = -0.99*velX;
velY = -0.99*velY;
}
//slow circles down over time
velX = .98*velX;
velY = .98*velY;
}
void attract(Box b)
{
float d = dist(posX, posY, b.posX, b.posY); // calculate dist between boxes
float diffX = b.posX - posX; // difference of position in X
float diffY = b.posY - posY; // difference of position in Y
velX += 0.08*(diffX / (sq(d))); // change velocity by a ratio between dist and pos difference
velY += 0.08*(diffY / (sq(d)));
}
void collide(Box b)
{
float dis = dist(posX, posY, b.posX, b.posY);
//if (dis <= (sqrt(sq(side) + sq(side/2)) + sqrt(sq(b.side/2) + sq(b.side/2)))) // for boxes
float overlap = (side/2 + b.side/2) - dis;
if (overlap>0)
{
float diffX = b.posX - posX; // difference of position in X
float diffY = b.posY - posY; // difference of position in Y
float unitX = diffX/dis;
float unitY = diffY/dis;
velX -= 0.1*unitX*overlap;
velY -= 0.1*unitY*overlap;
}
}
void jiggle()
{
velX = random(-1, 1);
velY = random(-1, 1);
}
}//class
//

``````
1 Like

oh, that’s amazing! I see now where and what I was doing wrong!
Thank you for the help

1 Like

Yeah, especially you need to make the dist() check 3D

also in jiggle and in the draw function (the one in the class) where it says:

``````//don’t let the boxes run away from the frame!
``````

Remark

in `draw()` (the one outside the class) I changed

``````    for (int k = j+1; k < boxes.length; k++)
``````

but I am not sure!!!

It looks very nice though!

Chrisir

1 Like

thank you! this was very helpful! I don’t know why, I was trying to change the class first, and being a beginner I did not know wheater the issues were logical or just bad writing

thank you a lot for your help

1 Like

why is it

`````` //check distances between all the other boxes and attracts and collide!
for (int j = 0; j < boxes.length-1; j++)
``````

I’m referring to the ‘-1’ bit.
Thank you

1 Like

that’s because of the for-loop with k (see above)

``````//check distances between all the other boxes and attracts and collide!
for (int j = 0; j < boxes.length; j++)
{
for (int k = 0; k < boxes.length; k++)
{
``````

Chrisir

Hey, thank you again for your help! I did change it to have all the z values, but it seems like the camera is cutting through the spheres. is there any way I can fix that? It seems like it is not bouncing back to what would it be the ‘front’
I have attached the code below

``````Box [] boxes;
int minSize = 20;
int maxSize = 50;
boolean collide = false;

// ----------------------------------------------------------------------
void setup() {
size(500, 500, P3D);
rectMode(CENTER);
ellipseMode(CENTER);
boxes = new Box;
for (int i = 0; i < boxes.length; i++)
{
boxes[i] = new Box(
random(maxSize, width-maxSize), random(maxSize, height-maxSize), random(maxSize, height-maxSize),
random(minSize, maxSize),
color(0, random(10, 255), random(10, 255)));
}
}

// ----

void draw() {
background(200);
lights();

fill(200, 10);
rect(width/2, height/2, width+2, height+2);

for (int i = 0; i < boxes.length; i++) {
boxes[i].draw();
}

//check distances between all the other boxes and attracts and collide!
for (int j = 0; j < boxes.length; j++)
{
for (int k = 0; k < boxes.length; k++)
{
if (j != k)
{
boxes[j].collide(boxes[k]);
boxes[j].attract(boxes[k]);
}
}
}
}

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

void mousePressed()
{
for (int i = 0; i < boxes.length; i++)
{
boxes[i].jiggle();
}
}
``````

box class

``````class Box
{
// step 1 = variables declaration
int frame = 0;
float posX;
float posY;
float posZ;

float velX;
float velY;
float velZ;
float side;
color c;

// step 2 = constructor, initializes the class
Box(float _posX, float _posY, float _posZ,
float _side,
color _c)
{
posX = _posX;
posY = _posY;
posZ= _posZ;
velX = random(-0.8, 0.8);
velY = random(-0.8, 0.8);
velZ = random(-0.8, 0.8);
side = _side;
c = _c;
}

// -------

// step 3 = functions, functionality of the class
void draw()
{
posX += velX;
posY += velY;
posZ += velZ;
pushMatrix();
translate(posX, posY, posZ);
noStroke();
fill(c);
// ellipse(0, 0, side, side);
sphere(side);
popMatrix();
//don’t let the boxes run away from the frame!
if ((posX < side || posX >= width-side)||(posY < side || posY >= height-side) || (posZ < side || posZ >=  width + height - side))
{
velX = -0.99*velX;
velY = -0.99*velY;
velZ = -0.99*velZ;
}
//slow circles down over time
velX = .98*velX;
velY = .98*velY;
velZ = .98*velZ;
}
void attract(Box b)
{
float d = dist(posX, posY, posZ, b.posX, b.posY, b.posZ); // calculate dist between boxes
float diffX = b.posX - posX; // difference of position in X
float diffY = b.posY - posY; // difference of position in Y
float diffZ = b.posZ - posZ; // difference of position in Z
velX += 0.08*(diffX / (sq(d))); // change velocity by a ratio between dist and pos difference
velY += 0.08*(diffY / (sq(d)));
velZ += 0.08*(diffZ / (sq(d)));
}
void collide(Box b)
{
float dis = dist(posX, posY, posZ,  b.posX, b.posY, b.posZ);
//if (dis <= (sqrt(sq(side) + sq(side/2)) + sqrt(sq(b.side/2) + sq(b.side/2)))) // for boxes
float overlap = (side/2 + b.side/2) - dis;
if (overlap>0)
{
float diffX = b.posX - posX; // difference of position in X
float diffY = b.posY - posY; // difference of possition in Y
float diffZ = b.posZ - posZ; // difference of position in Z
float unitX = diffX/dis;
float unitY = diffY/dis;
float unitZ = diffZ/dis;
velX -= 0.1*unitX*overlap;
velY -= 0.1*unitY*overlap;
velZ -= 0.1*unitZ*overlap;
}
}
void jiggle()
{
velX = random(-1, 1);
velY = random(-1, 1);
velZ = random(-1, 1);
}
}
``````

Thank you for all your help! It made 3d processing a lot more clearer! I just needed a bit of guidance

``````  // avoid clipping (at camera):