如何在Processing中生成可随机旋转的瓦片网格?
单个瓦片随机旋转的Processing实现方案
原始网格生成代码
原本的代码可以从加载的图片中随机选取瓦片,生成12×12的网格:
static int img_count = 6; PImage[] img; void setup() { size(1200, 800); img = new PImage[img_count]; for (int i = 0; i < img_count; i++) { img[i] = loadImage("./1x/Artboard " + (i+1) + ".png"); } } void draw() { for (int i = 0; i < 12; i++) { for (int j = 0; j < 12; j++) { int rand_index = int(random(img_count)); image(img[rand_index], 100 * i, 100 * j, 100, 100 ); } } }
错误尝试的问题
直接在循环中调用rotate()会旋转整个画布的坐标系,导致后续所有瓦片都基于之前的旋转角度绘制,完全偏离预期的网格位置:
void draw() { for (int i = 0; i < 12; i++) { for (int j = 0; j < 12; j++) { float r = int(random(4)) * HALF_PI; // 计算随机旋转角度 rotate(r); // 旋转整个画布 int rand_index= int(random(img_count)); image(img[rand_index], 100 * i, 100 * j, 100, 100 ); } } }
正确实现单个瓦片旋转的代码
使用pushMatrix()和popMatrix()隔离每个瓦片的坐标系变换,确保旋转只作用于当前瓦片:
static int img_count = 6; static int tileSize = 100; // 统一定义瓦片尺寸,方便修改 PImage[] img; void setup() { size(1200, 800); img = new PImage[img_count]; for (int i = 0; i < img_count; i++) { img[i] = loadImage("./1x/Artboard " + (i+1) + ".png"); } } void draw() { background(255); // 每次绘制前清空画布,避免叠加 for (int i = 0; i < 12; i++) { for (int j = 0; j < 12; j++) { int randIndex = int(random(img_count)); float rotation = int(random(4)) * HALF_PI; // 随机生成0/90/180/270度旋转角度 pushMatrix(); // 保存当前坐标系状态 translate(i * tileSize, j * tileSize); // 平移到瓦片左上角位置 translate(tileSize / 2, tileSize / 2); // 再平移到瓦片中心,作为旋转轴 rotate(rotation); // 执行旋转 // 绘制瓦片,此时原点在中心,所以偏移负半尺寸让图片填满格子 image(img[randIndex], -tileSize/2, -tileSize/2, tileSize, tileSize); popMatrix(); // 恢复坐标系,不影响后续瓦片绘制 } } noLoop(); // 无需实时刷新时添加,提升性能 }
关键逻辑说明
- 坐标系隔离:
pushMatrix()和popMatrix()成对使用,前者保存当前的平移、旋转状态,后者恢复到初始状态,保证每个瓦片的变换独立。 - 旋转中心调整:默认旋转以画布原点为中心,通过两次平移将旋转轴移到瓦片中心,避免旋转后瓦片偏移出网格。
- 绘制位置修正:旋转后坐标系原点在瓦片中心,所以绘制时从
(-tileSize/2, -tileSize/2)开始,确保图片刚好覆盖目标网格格子。
内容的提问来源于stack exchange,提问作者Miguel Henrique Salviatti
相关产品推荐
相关产品推荐

