A problem that I cannot figure out: "Wrapping shapes across a screen". (Iterative math and loops problem.)

Update: Solved! I reposted the working code as the answer. Thanks u/marcusround

A problem that I cannot figure out: “Wrapping shapes across a screen”. (Iterative math and loops problem.)

This sounds like a very easy problem, but ive spent the past 3 hours not being able to figure it out. Let me describe the problem in more detail. I’m hopeful that someone here can help me figure it out.

Description: Write an algorithm so that you have a variable number of squares with a variable size extending across the screen from left to right, where if a box crosses over the righthand side of the screen it starts back at the left on a new line.

Conditions: For simplicity, lets say that the width and height of each box as well as the space between each block, as well as the margins in which these blocks are contained is all equal, and all equals 100 pixels. I want an algorithm that will wrap these blocks/squares across the visible screen, and not break regardless of the size of the box or the number thereof (unless i exceed the canvas size of course).

Let me give you an example of some starting code: (UPDATED)

  class Webpage {
    constructor(){
      this.slots = [];
      this.count = 10;
      this.slotWidth = 100;
      this.slotHeight = 100;
      this.paddingWidth = 100;
      this.paddingHeight = 100;
      this.columnWidth = this.slotWidth + this.paddingWidth;
      this.rowHeight = this.slotHeight + this.paddingHeight;
      this.numColumns = Math.floor(windowWidth/this.columnWidth);

      for (var i = 0; i < this.count; i++){
      this.slots[i] = {
      x: this.paddingWidth,
      y: this.paddingHeight,  
      column: i % this.numColumns,
      row: Math.floor(i/this.numColumns),
      id: 0
    }
    
    }

    }
    display(){

      background(0);
      fill(255);
      this.columnWidth = this.slotWidth + this.paddingWidth;
      this.rowHeight = this.slotHeight + this.paddingHeight;
      this.numColumns = Math.floor(windowWidth/this.columnWidth);

      for (var i = 0; i < this.count; i++) {

        this.slots[i].column = i % this.numColumns;
        this.slots[i].row = Math.floor(i/this.numColumns);
      
        this.slots[i].x = this.columnWidth * this.slots[i].column;
        this.slots[i].y = this.rowHeight * this.slots[i].row;
      

        rect(this.slots[i].x, this.slots[i].y, this.slotWidth, this.slotHeight);
        console.log("iteration: ", i, ", x :", this.slots[i].x, ", y ", this.slots[i].y)
        
      }
      

    }
  }

Crossposted: A problem that I cannot figure out: "Wrapping shapes across a screen". (Iterative math and loops problem.)

Edit 1: Clarification: I need a single-iteration loop. I understand this is easy to do with double-iteration (a nested loop). But i want these boxes to be hierarchically serialized from left to right, and then down a row after it runs off a screen (like a word/text -wrap).

Edit 2: Here is a visual example. I hope this helps explain what I am trying to create.

Edit 3: Solved! The answer was kinda complicated and even used a modulus, but it seems to work beautifully.

size(600,400);
int sep = 40;
int siz = 20;
int n = 58;
background(64);
noStroke();
fill(0,200,0);
for(int i=0; i<n; i++){
 rect(
   (sep * i) % width,
   sep * ((sep * i) / width),
   siz, siz);
}

Example code. YMMV. Enjoy!

This doesn’t really answer my question in the context ive asked it. Each box is a javascript object, and there is an array of them. I need to set X and Y values, not immediately jump to drawing rectangles.

Also, where in this code does it wrap after it exceeds windowWidth? What makes the code wrap the shapes around the screen?

It does actually answer your question. It demonstrates what the X and Y values for your boxes should be, by drawing them at those X and Y positions.

specifically, the X position for the ith box is (sep * i) % width, and the Y value for the ith box is sep * ((sep * i) / width).

The wrapping happens because of two things. The first is that any box that is drawn past the width of the window has it’s X position drawn at that position modulo the width of the window. That’s the % width part of the X position.

The second thing is that squares that have this happen get moved down a row (or several rows!) depending on how many times past the window width the X position is.

If you take a moment to understand these two equations for the calculated X and Y positions, you can use a simple loop to pass them as arguments to box objects:

for( int i= 0; i <n; i++){
  boxes[i] = new Box( (sep * i) % width, sep * ((sep * i) / width) );
}

(Also, note that my boxes use the same sep for the amount of separation in both X and Y. In the X position, sep is X_sep. In the Y position, the first sep is Y_sep, and the second is X_sep again.)

2 Likes