Creation of a tower with boxes

we have a homework which asks us to create a tower, I directly thought of using iterations with boxes to create a wall which I will then turn according to a certain angle to form a tower I expected it to be feasible and logical but I was immediately confronted with a result that displeased me. Can anyone suggest an improvement to my code ?


void draw(){
  
  background(0,255,255);
  drawWall(60,12,PI/2);
  drawWall(60,12,0);

}

void drawWall(int h,int l,float r){
  
   for(int i = 0; i < l ;i++){
    for(int j=0; j < h ; j++){
      pushMatrix();
      rotateY(r);
      translate(i*15,-j*5,0);
      fill(255,0,0);
      box(15,5,5);
      popMatrix();
    }
  
  }

Hello @Smail_OUABED,

It is! Keep at it!

Here is a partial example without the for() loops:

size(600, 600, P3D);

translate(width/2, 400); // origin is a center of screen
rotateX(radians(80)); // So you can see it!

noFill();
circle(0, 0, 200);

pushMatrix();
rotateZ(radians(10)); 
translate(100, 0, 0);
fill(255, 0, 0);
box(15, 5, 5);
popMatrix();

pushMatrix();
rotateZ(radians(20));
translate(100, 0, 0);
fill(255, 0, 0);
box(15, 5, 5);
popMatrix();

pushMatrix();
rotateZ(radians(30));
translate(100, 0, 0);
fill(255, 0, 0);
box(15, 5, 5);
popMatrix();

pushMatrix();
rotateZ(radians(40));
translate(100, 0, 0);
fill(255, 0, 0);
box(15, 5, 5);
popMatrix();

// And so on...

// And then the next layer...

pushMatrix();
rotateZ(radians(0));
translate(100, 0, 20);
fill(255, 0, 0);
box(15, 5, 5);
popMatrix();

pushMatrix();
rotateZ(radians(10));
translate(100, 0, 20);
fill(255, 0, 0);
box(15, 5, 5);
popMatrix();

pushMatrix();
rotateZ(radians(20));
translate(100, 0, 20);
fill(255, 0, 0);
box(15, 5, 5);
popMatrix();

pushMatrix();
rotateZ(radians(30));
translate(100, 0, 20);
fill(255, 0, 0);
box(15, 5, 5);
popMatrix();

pushMatrix();
rotateZ(radians(40));
translate(100, 0, 20);
fill(255, 0, 0);
box(15, 5, 5);
popMatrix();

// And so on...

Code generates this:

Look for patterns that repeat and increment that you can use in a nested for() loop.

You can reduce the above to nested for() loops to generate:

:)

3 Likes

Hi @Smail_OUABED,

just as an inspiration …

if you get rid of the standard box function and create your own, you could get more into lovely details for your tower. :nerd_face:

Cheers
— mnse

PS: This could just be a beginning … :wink:

ezgif.com-gif-maker (7)

PPS: Not posting code because of homework policy …

4 Likes

Hello, thank you for your answer you guys are really kind, it seems much easier to implement and better for my solution, quick question, is it possible to do that with a square ?
Sorry, I didn’t know about the homework policy, although I read the article I must have missed some details so I delete it or? I will be careful about the future

Thank you for you help, this solutions seems to be more appropriate to what i wanna do, but quick question, is it possible to do with a square shape cause the tower must be square shaped

Presumably what you want is to draw a tower with four flat walls in a square. Your original drawWall function is fine for that, but you want the rotate to happen outside of the wall rather than within it. Your code would look something like:

drawWall    // from 0,0 to l,0
rotate 90 degrees
drawWall    // from 0,0 to 0,l
translate to opposite corner l,l
rotate 180 degrees
drawWall  // from l,l to l,0
rotate 90 degrees
drawWall  // from l,l to 0,l
1 Like

Hi @Smail_OUABED,

Don’t delete the homework flag for your post, as it is a homework…

It is the same approach, no matter if square or rectangular shape.

Take the Infos from @glv 's post and the visual approach of how to building up a tower from my vid and try to implement a solution.
Come back if you stuck or have concrete questions regarding this topic and include your code that one can verify the possible issues…

Cheers
— mnse

1 Like

thank you, you are the best i will try my hard to do it, god bless you all <3 <3

2 Likes

I agree with @Scudly. You’re on the right track with the code that you have; you just need to draw a couple more walls to complement the two you already have. Your initial post is missing a setup() function so you need to add that and include a P3D renderer. You also need to translate the origin out of the left upper corner of the window and relocate it to the middle so that the tower is more centered. By translating the origin a couple of more times (once per wall) and adding a rotater for the tower you should be able to get the output shown below:

3 Likes

i already did that but i want a solid smoth corners and not something like this ( the walls are nested )


what i have to do is really something like this, I managed to do it but as soon as I change the height and width of my walls I would have to find the rate of translation of the walls each time so that it looks good…
I tried to find a way that It’s calculated automatically but I didn’t succeed

here is my latest progress in my code if you can help me it will not be refused and I thank you all in advance <3


void setup(){
 size(800,400,P3D);
 //Params Camera
  PVector p;
  p = new PVector(height/2, 0, width/2);
  Camera cam = new Camera(this);
  cam.setPosition(p);
}

void draw(){
  //Arrière plan
  background(0,255,255);
  translate(height/2,width/2,0);
  DrawTour();
}

void DrawTour(){
  DrawTwoWallsAgaints(30,5);
  rotateY(PI);
  pushMatrix();
  translate(-65,0,65);
  DrawTwoWallsAgaints(30,5);
  popMatrix();
  
}

void drawWall(int h,int l,float r,int xb,int yb,int zb){
   
   for(int i = 0; i <= l ;i++){
    for(int j=0; j <= h ; j++){
      pushMatrix();
      rotateY(r);//retation d'un murs
      translate(xb/3,0,zb/5);
      translate(i*15,-j*5,0);//Translation pour dessiner le murs par rraport a la taille des bos (a automatiser après) 
      fill(245, 173, 66); //Couleur des box 
      box(xb,yb,zb);
      popMatrix();
    }
  }
}

/*
void drawWall(int h,int l,float r,int x,int y,int z){
  
   translate(x,y,z);
   for(int i = 0; i < l ;i++){
    for(int j=0; j < h ; j++){
      pushMatrix();
      rotateY(r);
      translate(i*15,-j*5,0);
      fill(245, 173, 66);
      box(15,5,5);
      popMatrix();
    }
  }
}
*/

void DrawTwoWallsAgaints(int h,int l){
  drawWall(h,l,0,15,5,5);
  drawWall(h,l,PI/2,15,5,5);
}


Hello @Smail_OUABED,

I found it helpful to work with a birds eye view:

void draw(){
  //Arrière plan
  background(0,255,255);
  translate(width/2-50, height/2-50, 200);
  rotateX(TAU/4);
  DrawTour();
}

Next:

//translate(xb/3,0,zb/5); // Did not use this
translate(i*15 +offx, -j*5 +offy, 0);`  // Add offset to the x and y to adjust

You know the size of the box and a visual examination of the overlap you can make a good guess of what the offset should be.

To get this:

And finally adjust this:

translate(-65, 0, 65);  // Needs to be adjusted!

To get this:

Corners overlap but that can also be addressed in your code later.

Keep at it!

I suggest you draw one wall at a time and transform (rotate\translate\scale) as required.

Keep working on your current code first and don’t let below distract you from that.

One wall with staggered bricks (every other row had an offset) is achievable with your code:

Thanks for the topic! I am having fun with this.
I will definitely use this as a topic for my young programming enthusiasts when we meet next!

:)

1 Like

this looks more beautiful, thank you for all your feedback <3, and i’m already sorry for young programming enthusiasts lmaoo

1 Like

juste a little problem, when a draw two walls that are adjacent with a 90° i got some holes in it how can i fix this ?

void drawWall(int h, int l, float r) {  
  for (int i = 0; i < l; i++) {
    for (int j = 0; j < h; j++) {
      pushMatrix();
      
      rotateY(r); // Rotation de l'ensemble du mur

      // Ajoutez un décalage à la position en x pour chaque deuxième rangée (sauf au début et à la fin)
      float xOffset = (i != 0 && i != l - 1 && j % 2 == 1) ? 7.5 : 0; // Décalage de 7.5 unités pour chaque deuxième rangée (sauf au début et à la fin)
      translate(i * 15 + 5 + xOffset, -j * 5, 0);  // Ajouter un décalage à la position en x
      
      fill(255, 222, 112); // Couleur de la boîte
      box(15, 5, 5);
      
      popMatrix();
    }
  }
}

1 Like

Some pointers:

  • You need an odd number of columns to fit these walls together at the corners

  • if you only rotate the same wall at the corner it will not fit into the adjacent wall

      //float xOffset = (i != 0 && i != l - 1 && j % 2 == 1) ? 7.5 : 0;  // I removed this
      float xOffset = (j % 2 == 1) ? 5 : 0; // Shifts odd rows. Changed block sizes!

I did not used that extra code in that first line to simplify.
You could pass a variable in function to select between odd or even rows.

You can then:

  • add code to shift even rows over for the rotated wall

OR

  • translate the entire wall to the other side so it fits

These will fit and I separated them so you could see this.

Your block sizes must fit together! It appears you are shifting a block of length 15 by half the amount 7.5. If you are fitting a rotated block that is only 5 wide into this there will be a gap!

I used blocks that were 10x5x5 for simplicity so they interlocked without a gap.

:)

There is a challenge to learning anything new. And this is certainly worth the challenge!
Crawl, walk, run… you tumble a few times along the way but hopefully you keep getting up and keep going and enjoy your adventures! :)

Some words of advice here from Daniel Shiffman
[https://www.youtube.com/watch?v=4JzDttgdILQ&t=1800s](https://Creative Coding for Beginners - Full Course!)

Text from video:

But the thing is, you’re here learning to code.
And I hope you’re enjoying this, and learning something,
And maybe I’m doing a halfway decent job of making this video.
But the real skill – the real thing that you need to practice is not listening to somebody else tell you how to do it,
but kind of trial and erroring your way through it,
and reading the documentation which covers all the ins and outs of all these functions, because there are a lot of them.
Coding is not about memorizing them or just knowing how to do it.
It’s about figuring out how to look things up and trying it yourself.
So let’s look at that.

I shared some pointers with the challenges I had with this.

Keep working through this!

Sometimes it helps to start from scratch and start with a new perspective.

:)

1 Like

Tower:

(I wrote this earlier but I now see that you had the idea already)

On a corner, the left and
right Wall could be connected
in a way that the stones in the corner
are each part of both walls.

So in the lowest row, the leftmost stone in the right wall
stands with its left side out from the right wall, and so be part of the left wall (which lowest row in turn is moved half a stone to the left, making space for the stone of the right wall).

For the next row up, it’s the other way round.

1 Like

I did it I figure it before you tell me it was easy yeah, thank you so much !!

2 Likes

So now I’m struggling to draw a door in a wall, I did create something that doesn’t draw in an interval, but I want now to not apply the offset when it in the door interval there is my function:


void drawWallDoor(int h, int l) {  
  for (int i = 0; i < l; i++) {
    for (int j = 0; j < h; j++) {
      if ((i > 0.60*l  || i < 0.30*l ) || (j > 0.45*h)) {
        pushMatrix();
        rotateY(0); 
        float xOffset = (j % 2 == 1 )? 5 : 0 ; // Décalage de 7.5 unités pour chaque deuxième rangée
        translate(i * 10 + xOffset , -j * 5, 0);  // Ajouter un décalage à la position en x
        fill(145, 145, 145); // Couleur de la boîte
        box(10, 5, 5);
        popMatrix();
      }
    }
  }

1 Like

Try to fill() them.

Approach below worked at my end.

if (conditions) // Or an else if()
  {
  pushMatrix();
  translate(?); 
  fill(255, 0, 0);
  box(5, 5, 5);
  popMatrix();
  }

Above is one side.

image

:)