You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 22:24:17