【问题标题】:Drawing rectangles of different sizes in a loop在循环中绘制不同大小的矩形
【发布时间】:2021-01-07 18:41:53
【问题描述】:

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

这是我的小sn-p:

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

感谢您的任何帮助!

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

【问题讨论】:

    标签: java loops processing rectangles


    【解决方案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;
      }
      
    }
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.2.0/p5.min.js"&gt;&lt;/script&gt;

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

    【讨论】:

    • 嗨,乔治!也谢谢你!真的很感激!我刚刚发现我做了一些愚蠢的事情……在我的问题中,我想在一行中绘制与其行号一样多的矩形——比如第一行、1 个矩形、第 2 行、两个矩形、第 3 行、三个矩形……但在我的视觉中解释我没有这样做,为什么 - 我做了递归......所以我试图用你的代码改变它,但无法弄清楚:-(
    【解决方案2】:

    回归时间!!!

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

    按照我的理解,你可以用下面的伪代码来实现:

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

    就是这样。有很多方法可以做你想做的事,所以其他答案可能和这个一样好,但是......我喜欢这个。如果您对 cme​​ts 中的此代码有任何疑问,我会随时待命。

    玩得开心!

    【讨论】:

    • 糟糕,我忘记了您想循环执行此操作。我希望没关系,否则请告诉我,我会考虑其他事情!
    • 是的,就是这样!完美的!非常感谢你!也为了向我解释得这么好——我真的很感激!谢谢!
    【解决方案3】:

    +++编辑+++

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

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

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

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

    感谢您的任何帮助!

    【讨论】:

    • float(width)/(y+1) 表示矩形的宽度将等于屏幕宽度除以您当前所在的“行号”。这就是为什么每行总是多一个矩形。它是动态计算的。
    • 矩形在循环内循环绘制。外循环迭代“线”,内循环绘制矩形,所以如果你在第 3 行,你应该有 3 个矩形。在第 3 行,rectStepwidth / 3,因此您可以在该行中放置 3 个矩形。矩形坐标是x * recstep,所以它们是并排的,这就是为什么recstep必须在外循环中重新计算:每一行的值都不同。
    • rectHeight 有点棘手,因为它不像您的图像所示那样工作:在代码 sn-p 中,它只计算一次,所以每一行都有相同的高度。为了让它像在图像中一样工作,它需要动态计算。最简单的方法是使用 2 个变量:一个是“当前 y”,一个是“当前矩形高度”。当前的 y 将在每行之后增加矩形高度的量,矩形高度将减少...大约 * 0.75 我会说,但这取决于你来设置。
    • 小修正:“所以如果你在第 3 行,你应该有 4 个矩形。在第 3 行,rectStep 是 'width / 3 + 1',所以你可以容纳 4 个矩形行”。
    • 嗨兰斯洛特!非常感谢您的解释!我会检查并告诉你!祝一切顺利!西里尔
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    相关资源
    最近更新 更多