如何约束随机性

How to constrain randomness

我正在 canvas 上绘制一个带有顶点的随机形状。 有时形状很窄很小。 有没有办法限制随机性,这样就不会发生这种情况。 由于我是 p5 的新手,如有任何提示,我们将不胜感激。

感谢您的宝贵时间和帮助

let noOfShapes = 3;

function setup(){
    createCanvas(1240, 1754);
    noLoop();
    background(0,230)
    colorMode(RGB)
    rectMode(CENTER);
    strokeWeight(3);

}

function draw(){
    //fill(56, 37, 34);

    for(let x = 0; x < noOfShapes; x++) {
      beginShape();
      stroke(255);
      fill(25, 255, 255,100);
      //noFill();
        for(let y = 2; y < 6; y++) {
          vertex(random(10,width), random(10,width))
          // vertex(random(10,width), random(10,width))
          // vertex(random(10,width), random(10,width))
          // vertex(random(10,width), random(10,width))
        }
      endShape(CLOSE);
    }
    stroke(255);

    for(let x=20; x<= width; x = x+20){
        blendMode(DODGE);
        //fill(200,200,200)
        stroke(255);
        beginShape();
          vertex(x, 0)
          vertex(x, height+20)
        endShape();
    }

}

为 x 和 y 坐标创建一个随机数列表:

rx = []; ry = [];
for (let y = 0; y < 4; y++) {
    rx.push(random(10, width-20));
    ry.push(random(10, height-20));
}

计算每个列表的最小值 (min) and maximum (max) 之间的差异:

drx = max(rx) - min(rx);
dry = max(ry) - min(ry);

定义一个阈值并重复该过程,只要任何差异低于该阈值:

let threshold = 200;
do {

  // [...]
}
while (drx < threshold || dry < threshold)

通过考虑沿 45° 对角线的点之间的距离,可以进一步改进算法。使用Dot product计算距离:

rd1.push(rx[y]*0.707 + ry[y]*0.707);
rd2.push(rx[y]*0.707 - ry[y]*0.707);

使用随机坐标生成形状:

let threshold = 400;
let rx, ry, drx, dry, rd1, rd2, drd1, drd2; 
do {
    rx = []; ry = []; rd1 = []; rd2 = [];
    for (let y = 0; y < 4; y++) {
        rx.push(random(10, width-20));
        ry.push(random(10, height-20));
        rd1.push(rx[y]*0.707 + ry[y]*0.707);
        rd2.push(rx[y]*0.707 - ry[y]*0.707);
    }
    drx = max(rx) - min(rx);
    dry = max(ry) - min(ry);
    drd1 = max(rd1) - min(rd1);
    drd2 = max(rd2) - min(rd2);
}
while (drx < threshold || dry < threshold || drd1 < threshold || drd2 < threshold)

beginShape();
stroke(255);
fill(25, 255, 255,100);
//noFill();
for (let y = 0; y < rx.length; y++) {
    vertex(rx[y], ry[y]);
}
endShape(CLOSE);

let noOfShapes = 1;

function setup(){
    createCanvas(1240, 1754);
    noLoop();
    background(0,230)
    colorMode(RGB)
    rectMode(CENTER);
    strokeWeight(3);
}

function draw(){
    for(let x = 0; x < noOfShapes; x++) {
       
        let threshold = 400;
        let rx, ry, drx, dry, rd1, rd2, drd1, drd2; 
        do {
            rx = []; ry = []; rd1 = []; rd2 = [];
            for (let y = 0; y < 4; y++) {
                rx.push(random(10, width-20));
                ry.push(random(10, height-20));
                rd1.push(rx[y]*0.707 + ry[y]*0.707);
                rd2.push(rx[y]*0.707 - ry[y]*0.707);
            }
            drx = max(rx) - min(rx);
            dry = max(ry) - min(ry);
            drd1 = max(rd1) - min(rd1);
            drd2 = max(rd2) - min(rd2);
        }
        while (drx < threshold || dry < threshold || drd1 < threshold || drd2 < threshold)
      
        beginShape();
        stroke(255);
        fill(25, 255, 255,100);
        //noFill();
        for (let y = 0; y < rx.length; y++) {
            vertex(rx[y], ry[y]);
        }
        endShape(CLOSE);
    }
    stroke(255);

    for(let x=20; x<= width; x = x+20){
        blendMode(DODGE);
        //fill(200,200,200)
        stroke(255);
        beginShape();
          vertex(x, 0)
          vertex(x, height+20)
        endShape();
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>