循环绘制不同大小的矩形
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 等等……
我不知道它背后的数学是什么......
有人有想法吗?
感谢您的帮助!
我在 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 等等……
我不知道它背后的数学是什么...... 有人有想法吗?
感谢您的帮助!