p5.js像素控制螺旋粗细渲染结果异常问题
问题原因
代码存在3个核心问题,导致像素采样错位、渲染结果不符合预期:
- 坐标体系不匹配:螺旋计算得到的
x1/y1是以画布中心为原点的相对坐标,取值包含负数;但Img.get()需要传入以图像左上角为原点的绝对坐标,取值必须落在[0, 图像宽度]、[0, 图像高度]区间内。直接传入相对中心的坐标时,3/4区域的采样坐标要么为负、要么超出图像边界,无法读取到正确的像素值。 - 初始螺旋半径设置错误:初始半径设为
width(500px),但画布中心到边缘的距离仅为250px,超过70%的螺旋点会落在画布可视区域外,属于无效绘制。 - 冗余操作影响性能:循环内反复执行
push()/translate()/pop(),还计算了从未使用的x2/y2变量,额外增加了运行开销。
另外你开启了HSB颜色模式但并未使用HSB相关功能,可能干扰brightness()函数的计算结果。
修正后可运行代码
const FG = '#222323'; const BG = '#f0f6f0'; let Img; function preload() { Img = loadImage('black.png'); } function setup() { createCanvas(500, 500); Img.resize(500, 500); background(BG); fill(FG); noLoop(); noStroke(); // 提前将坐标原点移到画布中心,避免循环内重复变换 translate(width/2, height/2); } function draw() { // 初始半径设为画布半宽,刚好覆盖整个画布区域 let r = width / 2; let a = 0; while (r > 1) { const x1 = r * cos(a); const y1 = r * sin(a); a += 0.01; r -= 0.03; // 转换为图像采样所需的左上角原点坐标 const sampleX = round(width/2 + x1); const sampleY = round(height/2 + y1); // 跳过超出图像边界的采样点,避免读取无效像素 if (sampleX < 0 || sampleX >= width || sampleY < 0 || sampleY >= height) { continue; } const pixelColor = Img.get(sampleX, sampleY); const pixelBrightness = brightness(pixelColor); // 黑色(亮度0)对应最大点尺寸,白色(亮度255)对应最小点尺寸,若明暗反转可交换10和1的位置 const dotSize = map(pixelBrightness, 0, 255, 10, 1); ellipse(x1, y1, dotSize, dotSize); } }
调整说明
- 修正了采样坐标的转换逻辑,保证每个在画布内的点都能读到对应位置的正确像素值
- 修正了初始螺旋半径,所有点都落在画布可视区域内
- 移除了冗余的坐标变换、无用变量计算和不必要的HSB颜色模式设置
- 增加了采样边界判断,彻底解决单象限尺寸异常的问题
- 调整了尺寸映射逻辑,匹配黑圆白底测试素材:黑色区域点更大,白色区域点更小,如果实际效果明暗反转,把
map最后两个参数调换即可。
内容的提问来源于stack exchange,提问作者AbbyDabby
相关产品推荐
相关产品推荐

