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

p5.js画布Resize后pixels[]无法返回正确颜色值的问题排查求助

p5.js画布Resize后pixels[]无法返回正确颜色值的问题排查求助

我正在做一个生成艺术项目,目前遇到了pixels函数相关的问题。我的算法需要在画布上只有背景色的区域绘制圆形(也就是树木),所以用pixels数组来对比画布像素和背景色。但现在的问题是,当调整画布大小并重绘时,有些圆形会消失,另一些又随机出现——哪怕是在明显只有背景色的区域也会这样。我排查后发现,pixels数组并没有返回那些明显匹配背景色的像素的正确颜色值。

我已经确认算法里的概率部分不是问题,而且随机函数用了固定种子,所以重绘时所有内容应该保持一致。问题肯定出在颜色检查这块,有没有人能帮忙分析一下?

class ArrayList extends Array {
    constructor() {super(...[]);}
    size() {return this.length;}
    add(x) {this.push(x);}
    get(i) {return this[i];}
    remove(i) {this.splice(i,1);}
}

 // Variable initialization
var turns = 0; 
var avgAngle; 
var trees;
var numberStands;
var turnAngles = new Array( ); 
var otPoints = new ArrayList();
var colorSets; 
var colorSetIndex;
var colorSetNames;
var cName;
var circleCandidates = new ArrayList(); 
var turnList = new ArrayList(); 
var allStandIndices = new Array(); 
var pitPointIndex0 = 0; 
var pitPointIndex1 = 1;
var pd = 1;
var canvasMin;
var seed;

// Class for defining a point.
class Point { 
    constructor( x , y ) { 
        this.x = x; 
        this.y = y; 
    } 
} 

// Class for line
class Line { 
    constructor( p1 , p2 ) { 
        this.p1 = p1; 
        this.p2 = p2; 
    } 
}

// Class for a quad
class Quad {
    // Upper left = p0
    // Upper right = p1
    // Lower right = p2
    // Lower left = p3
    constructor( p0 , p1 , p2 , p3 ) {
        this.p0 = p0;
        this.p1 = p1;
        this.p2 = p2;
        this.p3 = p3; 
    } 
}

// Create an array list of points defining each turn
function getTurns ( centerPoint , w , h ) { 
    let turnArray = new ArrayList();
    let xRadius = 0;
    let yRadius = 0;
    let centerPx = centerPoint.x;
    let centerPy = centerPoint.y;
    let prevRadius = 0;
    let absMaxRad = 0; 
  
    // Iterate through turns to define points for each turn
    for ( let i = 0 ; i < turns; i++ ) {
        // Determine the angle at which this point will be drawn
        let startAngle = avgAngle * i;
        let actAngle = startAngle + avgAngle;
        turnAngles = append(turnAngles, actAngle);
        // Determine max radius
        // Check all angle scenarios to determine max radius
        let maxRadius = canvasMin / 100;
        if (actAngle == 0) {
            maxRadius = w-centerPx;
        } else if (actAngle > 0 && actAngle < atan((h-centerPy) / (w-centerPx))) {
            maxRadius = (w-centerPx) / cos(actAngle);
        } else if (actAngle == atan((h-centerPy) / (w-centerPx))) {
            maxRadius = sqrt(sq(w-centerPx) + sq(h-centerPy));
        } else if (actAngle > atan((h-centerPy) / (w-centerPx)) && actAngle < HALF_PI) {
            maxRadius = (h-centerPy) / cos(HALF_PI-actAngle);
        } else if (actAngle == HALF_PI) {
            maxRadius = h-centerPy;
        } else if (actAngle > HALF_PI && actAngle < atan(centerPx / (h-centerPy)) + HALF_PI) {
            maxRadius = (h-centerPy) / cos(actAngle-HALF_PI);
        } else if (actAngle == atan(centerPx / (h-centerPy)) + HALF_PI) {
            maxRadius = sqrt(sq(centerPx) + sq(h-centerPy));
        } else if (actAngle > atan(centerPx / (h-centerPy)) + HALF_PI && actAngle < PI) {
            maxRadius = centerPx / cos(PI-actAngle);
        } else if (actAngle == PI) {
            maxRadius = centerPx;
        } else if (actAngle > PI && actAngle < atan(centerPy / centerPx) + PI) {
            maxRadius = centerPx / cos(actAngle-PI);
        } else if (actAngle == atan(centerPy / centerPx) + PI) {
            maxRadius = sqrt(sq(centerPx) + sq(centerPy));
        } else if (actAngle > atan(centerPy/centerPx) + PI && actAngle < PI+ HALF_PI) {
            maxRadius = centerPy / cos(PI+ HALF_PI- actAngle);
        } else if (actAngle == PI+ HALF_PI) {
            maxRadius = centerPy;
        } else if (actAngle > PI+ HALF_PI && actAngle < atan((w-centerPx)/centerPy) + PI + HALF_PI) {
            maxRadius = centerPy / cos(PI + HALF_PI - actAngle);
        } else if (actAngle == atan((w-centerPx) / centerPy) + PI + HALF_PI) {
            maxRadius = sqrt(sq(w-centerPx) + sq(centerPy));
        } else if (actAngle > atan((w-centerPx)/centerPy) + PI + HALF_PI && actAngle < TWO_PI) {
            maxRadius = (w-centerPx) / cos(TWO_PI-actAngle);
        } else if (actAngle == TWO_PI) {
            maxRadius = canvasMin-centerPx;
        } 
    if (i == 0) {
        prevRadius = min(maxRadius - canvasMin / 15 , canvasMin / 1.25); 
    } 
    
    // Record turn points for main track
    let actRadius = random(prevRadius-canvasMin / 4 , min(prevRadius + canvasMin / 2 , maxRadius - canvasMin / 15 ));
    if (actRadius > absMaxRad) {
        absMaxRad = actRadius;
    }
    xRadius = centerPx + actRadius * cos(actAngle);
    yRadius = centerPy + actRadius * sin(actAngle);
    turnArray.add(new Point (xRadius, yRadius));
    
    // Record turn points for outer track
    let otRadius = max(actRadius * 1.4 + canvasMin/200, (actRadius + absMaxRad) / 2);
    let otXRadius = centerPx + otRadius * cos(actAngle);
    let otYRadius = centerPy + otRadius * sin(actAngle);
    otPoints.add(new Point (otXRadius, otYRadius));
  }
  return turnArray;
} 

// Draw roads leaving the exterior track
function drawExitRoads(trackPoints) {
    let roads = new ArrayList();
    for (let i = 0; i < trackPoints.size(); i++) {
        let turnAngle = turnAngles[i];
        let x = 0;
        let y = 0;
        let variance = 50;
        let p = trackPoints.get(i);
        let px = p.x;
        let py = p.y;
        if (turnAngle >= 0 && turnAngle < PI/ 4) {
            x = canvasMin;
            y = random(py - variance,py + variance);
        } else if (turnAngle >= PI * 0.25 && turnAngle < PI * 0.75) {
            x = random(px - variance,px + variance);
            y = canvasMin;
        } else if (turnAngle >= PI * 0.75 && turnAngle < PI * 1.25) {
            x = 0;
            y = random(py - variance,py + variance);
        } else if (turnAngle >= PI * 1.25 && turnAngle < PI * 1.75) {
            x = random(px - variance,px + variance);
            y = 0;
        } else {
            x = canvasMin;
            y = random(py - variance,py + variance);
        } if (x != 0 || y != 0) {
            circleCandidates.add(new Point (px,py));
            beginShape( );
            vertex(px,py);
            vertex(x,y);
            endShape( );
            roads.add(new Line(new Point(px,py), new Point(x,y)));
        }
    }
  
    return roads;
}

// Function to draw random trees in areas where the background color exists and 
// when a point exists within a certain probability distribution of a line or 
// set of lines
// bg: background color
// treeColor: the color of trees to be drawn on the canvas
function drawTrees(bg,treeColor) {
  
    fill(treeColor);
    noStroke( );
  
    // Generate an array of lines that will be used to determine where to plot the tree distributions
    let numClusters = 0;
    if (trees > 0) {
        numClusters = Math.floor(random(3,8));
    }
    let lines = new ArrayList();
    for (let l = 0; l < numClusters; l++) {
        let p0x = random(0, 1) * canvasMin;
        let p0y = random(0, 1) * canvasMin;
        let p1x = random(0, 1) * canvasMin;
        let p1y = random(0, 1) * canvasMin;
        let p0 = new Point(p0x, p0y);
        let p1 = new Point(p1x, p1y);
        lines.add(new Line(p0,p1));
    }
  
    // Iterate through all pixels, per treeSpacing value
    loadPixels();
    for (let i = 0; i < 10000; i += 1) {
    
        // Set a random point
        let xPixP = random(0, 1) * canvasMin;
        let yPixP = random(0, 1) * canvasMin;
        let xPix = Math.round(xPixP);
        let yPix = Math.round(yPixP);
    
        // Check if the pixels around the point are only the background color
        let clear = true;
        let d = pixelDensity();
        let clearance = Math.floor(canvasMin/200);
        for (let j = -clearance; j < clearance; j++) {
            for (let k = -clearance; k < clearance; k++) {
                let index = 4 * d * ((yPix + j) * d * canvasMin + xPix + k);
                let cR1 = pixels[index];
                let cG1 = pixels[index + 1];
                let cB1 = pixels[index + 2];
                let cA1 = pixels[index + 3];
                let cR2 = red(bg);
                let cG2 = green(bg);
                let cB2 = blue(bg);
                let cA2 = alpha(bg);
                if (cR1 != cR2 || cG1 != cG2 || cB1 != cB2) {
                    clear = false;
                }
            }
        }
  
        // Check closeness to each line
        let maxDist = canvasMin / random(4, 40);
        let prob = 0;
        for (let l = 0; l < lines.size(); l++) {
            let distFromL = getDistanceFromLine(lines.get(l), new Point(xPixP,yPixP));
            if (distFr

备注:内容来源于stack exchange,提问作者Tom

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 03:23:07