你们好亲密!
使用pushMatrix()/popMatrix() 隔离坐标系,您绝对走在正确的轨道上,但是您可能不小心将旋转放置在popMatrix() 之后,这违背了目的。您可能打算让每个正方形彼此独立旋转,而不是将 2 * PI 累积到全局旋转。
另一个问题是,对于 for 循环中的每次迭代,您都以相同的角度 (2 * PI) 旋转,并且旋转是 360 度,因此即使您像这样修复旋转:
pushMatrix();
translate(y, y);
rotate(radians(2.0*PI));
rect(0, 0, a, a);
popMatrix();
您将获得缩放效果:
(小注 2.0 * PI 已作为 TWO_PI 常量存在于处理中)
要获得螺旋状效果,需要增加每次迭代的角度(例如 x = 0、旋转 = 0、x = 1、旋转 = 5、x = 2、旋转 = 10 等)。角度增量完全取决于您:取决于您如何将 x 增量映射到旋转角度角度,您将获得更紧或更松的螺旋。
说到映射,Processing 有一个 map() 函数,它可以非常容易地从一个数字范围(比如 x 从 0 到 19)映射到另一个数字范围(比如 0 弧度到 PI 弧度):
for (int x = 0; x < 20; x++) {
pushMatrix();
translate(y, y);
rotate(map(x, 0, 19, 0, PI));
rect(0, 0, a, a);
popMatrix();
a = a - 20;
}
这是基于您的代码的基本草图:
int a = 10;
int y = 250;
void setup() {
size(500, 500);
rectMode(CENTER);
noFill();
background(255);
recta();
}
void recta() {
for (int x = 0; x < 20; x++) {
pushMatrix();
translate(y, y);
rotate(map(x, 0, 19, 0, PI));
rect(0, 0, a, a);
popMatrix();
a = a - 20;
}
}
我删除了draw(),因为它在没有任何变化的情况下渲染相同的帧:在setup() 中绘制一次可以使用更少的 CPU/功耗实现相同的视觉效果。
您可以使用draw(),但可以添加一些交互性或动画来探索形状。以下是上面使用 cmets 的调整版本:
int y = 250;
void setup() {
size(500, 500);
rectMode(CENTER);
noFill();
}
void draw(){
background(255);
recta();
}
void recta() {
// map mouse X position to -180 to 180 degrees (as radians)
float maxAngle = map(mouseX, 0, width, -PI, PI);
// reset square size
int a = 10;
// for each square
for (int x = 0; x < 20; x++) {
// isolate coordinate space
pushMatrix();
// translate first
translate(y, y);
// then rotate: order matters
// map x value to mouse mapped maximum rotation angle
rotate(map(x, 0, 19, 0, maxAngle));
// render the square
rect(0, 0, a, a);
popMatrix();
// decrease square size
a = a - 20;
}
}
记住转换顺序很重要(例如,translate() 然后rotate() 与rotate() 然后translate() 相比会产生不同的效果)。玩得开心!