Processing中如何让像素化图形绕自身轴旋转并实现淡入?
解决你的Processing变换矩阵困惑
嘿,我完全懂你现在的头疼点——在循环里给每个独立图形做绕自身中心的旋转,Processing的变换顺序和累积特性很容易让人绕晕!问题出在你没有隔离每个图形的变换状态,而且变换的顺序也没搞对,下面给你一步步理清楚:
核心问题:变换的累积与隔离
Processing的rotate()和translate()是基于当前坐标系的,而且所有变换会累积叠加。如果你不在每次循环里重置坐标系,前一个图形的旋转会直接影响下一个图形的位置和角度,这就是你之前出错的原因。解决这个的关键是用pushMatrix()和popMatrix()来包裹每个图形的变换操作,它们会帮你保存和恢复坐标系状态,让每个图形的变换完全独立。
正确的变换步骤(绕自身中心旋转)
因为你已经设置了shapeMode(CENTER),但要实现绕自身中心旋转,正确的操作顺序应该是:
- 保存当前坐标系状态(
pushMatrix()) - 将坐标系原点平移到当前图形的中心位置(这一步是关键!)
- 围绕新的原点(也就是图形中心)旋转
- 绘制图形(此时图形的位置参数用(0,0),因为原点已经移到中心了)
- 恢复之前的坐标系状态(
popMatrix())
修改后的代码片段
把你draw()函数里的循环部分改成这样:
void draw() { background(123); // 把tileWidth和tileHeight提到循环外面,避免重复计算提升性能 float tileWidth = width / (float)img.width; float tileHeight = height / (float)img.height; for (int gridX = 0; gridX < img.width; gridX++) { for (int gridY = 0; gridY < img.height; gridY++) { float posX = tileWidth * gridX; float posY = tileHeight * gridY; color c = img.pixels[gridY*img.width+gridX]; int greyscale = round(red(c)*0.222+green(c)*0.707+blue(c)*0.071); int gradientToIndex = round(map(greyscale, 0, 255, 0, shapeCount-1)); // 淡入+旋转参数 float wave = map(sin(radians(frameCount*4)), -1, 1, 0, 2); float rotateAngle = radians(wave * 90); // 可调整倍数控制旋转幅度,默认wave范围0-2角度太小 // 关键:隔离每个图形的变换 pushMatrix(); // 平移到当前tile的中心 translate(posX + tileWidth/2, posY + tileHeight/2); // 绕中心旋转 rotate(rotateAngle); // 绘制图形,位置用(0,0),因为已经平移到中心了 shape(shapes[gradientToIndex], 0, 0, tileWidth * wave, tileHeight * wave); popMatrix(); } } }
额外说明
- 把
tileWidth和tileHeight移到循环外,避免每次循环重复计算,小细节但能提升运行效率 - 旋转角度的倍数
*90是为了让旋转效果更明显,你可以根据需求调整这个数值,比如改成*180让旋转幅度更大
这样修改后,每个“像素图形”都会在淡入缩放的同时,绕自己的中心旋转,而且不会互相干扰啦!
内容的提问来源于stack exchange,提问作者Cyrill
相关产品推荐
相关产品推荐

