循环绘制不同大小的矩形

Drawing rectangles of different sizes in a loop

我在 Processing 中写了这段代码,它通过循环绘制矩形……随着代码循环遍历行,每个矩形都稍微宽了……到目前为止一切顺利……但我真正想要实现的是第一行是 1 个矩形,第二行是 2 个,第三行是 3 个,依此类推……换句话说,每一行中的矩形数与其行号一样多…… 但我真的被困在这里。我想到了嵌套循环。有了它,我可以在 X 轴和 Y 轴上绘制……但是如何将它与 with 结合起来?这与分形有关吗?

这是我的小片段:

 int rows = 100;

void setup() {
  size(1080, 1080);
  rectMode(CENTER);
}

void draw() {
  background(0);
  fill(255);
  translate(0, height/rows/2);
  
  for (int y=0; y < rows; y ++) {
  rect(width/2, (height/rows)*y, width/rows*y, height/rows);
  }
  
}

感谢您的帮助!

祝一切顺利,谢谢! 我添加了一张图片来展示我试图实现的目标:

递归时间!!!

请原谅我的热情,但我喜欢递归并且我没有太多机会使用它(主要是因为它在大多数时候都可以避免,而且因为在错误的时间使用它是直接的白痴) .

按照我的看法,您可以使用以下伪代码实现:

Draw a rectangle
Draw 2 smaller rectangles underneath the last one
Use this logic on each of the smaller rectangles

现在,递归最重要的事情是你需要一个退出条件。在这里,我想您可以输入所需的“线”数,或者在矩形太小而不能被视为矩形时停止编写矩形。为什么不兼得?让我们写两个:

void setup() {
  size(800, 600);
  background(0);
  stroke(255);
  noFill();
  
  // drawing a couple lines of squares
  DrawRectangles(new PVector(0,0), 200, width, 6); // for 6 lines of rectangles
  // if you try it with a stupid number, like 600 iterations, it'll stop anyway when the rectangles are so small that they can't be seen
}

void draw() {}

void DrawRectangles(PVector position, int squareHeight, int squareWidth, int iterations) {
  // if you can draw more rectangles it'll continue, else it stops
  // a recursive method MUST have a stop condition, or else it becomes an infinite loop!
  if (squareHeight > 0 && iterations > 0) {
    // draw a rectangle and call this method twice for the next line
    rect(position.x, position.y, squareWidth, squareHeight);
    DrawRectangles(new PVector(position.x, position.y + squareHeight), (int)(squareHeight/2), (int)(squareWidth/2), iterations-1);
    DrawRectangles(new PVector(position.x + squareWidth/2, position.y + squareHeight), (int)(squareHeight/2), (int)(squareWidth/2), iterations-1); 
  }
}

就是这个主意。有很多方法可以做你想做的事,所以其他答案可能和这个一样好,但是......我喜欢这个。如果您在评论中对此代码有疑问,我会在附近闲逛。

玩得开心!

Laancelot 的解决方案很优雅(+1)。

这是使用嵌套 for 循环的注释变体:

void setup() {
  size(1024, 512);
  
  noFill();
  stroke(255);
  strokeWeight(3);
  
  background(0);
  // number of rows: this should fill the screen, more will be hard to see
  int rows = 6;  
  // the initial height of a box 
  float boxHeight = height / 2;
  // the initial y position of the box
  float y = boxHeight;
  // the initial number of boxes
  int hCount = 2;
  
  // for each row
  for(int row = 0; row < rows; row++){
    
    // compute the width per box
    float boxWidth = width / hCount;
    
    // for each box per row
    for(int i = 0; i < hCount; i++){
      // draw the box, offset on X
      rect(boxWidth * i, y, boxWidth, boxHeight);
    }
    // increment values for next row...
    // half the height
    boxHeight /= 2;
    // move boxes lower
    y += boxHeight;
    // draw twice as many boxes on the next row
    hCount *= 2;
  }
  
}

您可以 运行 下面的演示:

function setup() {
  createCanvas(1024, 512);
  
  noFill();
  stroke(255);
  strokeWeight(3);
  
  background(0);
  // number of rows: this should fill the screen, more will be hard to see
  let rows = 6;  
  // the initial height of a box 
  let boxHeight = height / 2;
  // the initial y position of the box
  let y = boxHeight;
  // the initial number of boxes
  let hCount = 2;
  
  // for each row
  for(let row = 0; row < rows; row++){
    
    // compute the width per box
    let boxWidth = width / hCount;
    
    // for each box per row
    for(let i = 0; i < hCount; i++){
      // draw the box, offset on X
      rect(boxWidth * i, y, boxWidth, boxHeight);
    }
    // increment values for next row...
    // half the height
    boxHeight /= 2;
    // move boxes lower
    y += boxHeight;
    // draw twice as many boxes on the next row
    hCount *= 2;
  }
  
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.2.0/p5.min.js"></script>

这似乎与分形有关,尤其是 Cantor Set

+++编辑+++

这是我的问题的正确视觉草图 – 我的错 – 你的回答对我的第一个视觉草图完全正确并且非常有帮助!

我几乎就在这里放弃了这段代码,但我还不能保持第一个给定的比例(第一个矩形的比例)然后让它们缩小——就像我上面的视觉涂鸦一样:

    int rows = 20;
float rectHeight;
float rectStep;
void setup() {
  size(1080, 1080);
  noFill();
  stroke(255);
  rectHeight = float(height)/rows;
}
void draw() {
  background(0);
  for (int y=0; y < rows; y++) {
    rectStep = float(width)/(y+1);
    for(int x = 0; x <= y+1*2; x++){
      rect(x*rectStep, y*rectHeight, rectStep, rectHeight);
    }
  }
}

它们从第一行向下缩小的系数不同: 2、1.5、1.3、1.2、1.1、1.1、1.1、1.0 等等……

我不知道它背后的数学是什么...... 有人有想法吗?

感谢您的帮助!