在循环中绘制不同大小的矩形

问题描述

我在 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);
  }
  
}

感谢您的任何帮助!

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

This is what I want to draw with the loop

解决方法

回归时间!!!

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

在我看来,您可以使用以下伪代码实现这一点:

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

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

RECURSION! RECURSION! AT LAST!

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,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;
  }
  
}

subdivided rectangles a-la Cantor Set

您可以在下面运行演示:

function setup() {
  createCanvas(1024,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,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

,

+++编辑+++

这是我的问题的正确视觉草图 - 我的不好 - 你的答案对我的第一个视觉草图完全正确,非常有帮助!

right one

我在这里使用了这段代码,但我还没有设法保持第一个给定的比例(第一个矩形的),然后让它们缩小——就像我上面的视觉涂鸦一样:

    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.0 等等……

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

感谢您的任何帮助!