我试图通过在圆形图形中绘制一定数量的顶点(由stepCount确定)来在p5js中创建一些自定义形状,然后连接这些点。

根据stepCount,形状可以是直线,矩形,五边形,六边形等,一直到圆形。当我对stepCount进行硬编码并刷新页面时,更改将按预期反映。

问题是我想使用dat.GUI从页面实时操作stepCount。当我这样做时,我得到了一个闪烁的轮廓,其中剪切了预期的形状。

这是我的代码如下:



let p;
let x;
let y;

function setup() {
  createCanvas(windowWidth, windowHeight);
  p = new Planet();
  console.log("Planet generated.");
  let gui = new dat.GUI();
  gui.add(p, 'radius', 0, 500);
  gui.add(p, 'stepCount', 0, 50)

}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
}

function draw() {
  background(100);
  makePlanet();
}

function Planet() {
  this.radius = 200;
  this.angle = 0;
  this.stepCount = 20;
  this.step = TWO_PI / this.stepCount;
  this.angle = 0;
}

function makePlanet() {
  beginShape();
  for (i = 0; i < p.stepCount + 1; i++) {
    x = p.radius * sin(p.angle);
    y = p.radius * cos(p.angle);
    vertex(windowWidth / 2 - x, windowHeight / 2 - y);
    p.angle = p.angle + p.step;
    if (i >= p.stepCount) {
      endShape();
    }
  }
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>





我知道这与p.angle = p.angle + p.step循环运行有关,但是我很难弄清楚解决方案是数学的还是在于将变量存储在Planet()中的方式。

任何指导都将不胜感激,我只想学习。

最佳答案

您必须round p.stepCount为整数值。一步的角度取决于步数,因此必须重新计算(p.steps)。从每帧开始,应在每个帧中重置p.angle

function makePlanet() {
    // round stepCount
    stepCount =  round(p.stepCount);
    // calculate step angle
    p.steps = TWO_PI / stepCount;
    // reset start angle
    p.angle = 0;
    // create shape
    beginShape();
    for (i = 0; i <= stepCount; i++) {
        x = p.radius * sin(p.angle);
        y = p.radius * cos(p.angle);
        vertex(windowWidth / 2 - x, windowHeight / 2 - y);
        p.angle = p.angle + p.steps;
        if (i >= stepCount) {
            endShape();
        }
    }
}


此外,最小步骤数应为3:

gui.add(p, 'stepCount', 3, 50)


看例子



let p, x, y;

function setup() {
    createCanvas(windowWidth, windowHeight);
    p = new Planet();
    console.log("Planet generated.");
    let gui = new dat.GUI();
    gui.add(p, 'radius', 0, 500);
    gui.add(p, 'stepCount', 3, 50)
}

function windowResized() {
    resizeCanvas(windowWidth, windowHeight);
}

function draw() {
    background(100);
    makePlanet();
}

function Planet() {
    this.radius = 50;
    this.angle = 0;
    this.stepCount = 5
    this.step = TWO_PI / this.stepCount;
    this.angle = 0;
}

function makePlanet() {
    // round stepCount
    stepCount =  round(p.stepCount);
    // calculate step angle
    p.steps = TWO_PI / stepCount;
    // reset start angle
    p.angle = 0;
    // create shape
    beginShape();
    for (i = 0; i <= stepCount; i++) {
        x = p.radius * sin(p.angle);
        y = p.radius * cos(p.angle);
        vertex(windowWidth / 2 - x, windowHeight / 2 - y);
        p.angle = p.angle + p.steps;
        if (i >= stepCount) {
            endShape();
        }
    }
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>

09-19 09:53