我如何在 canvas 上的 2 个位置之间为 P5.js 创建点?

How would I create dots in-between 2 positions on a canvas for P5.js?

所以最终我想找出一个可以在两点之间创建点的循环。如果有人能解决这个问题,我们将不胜感激!

let pos1 = {x:383,y:202};
let pos2 = {x:754,y:387};

let dotRadius = 5;

let divisions = 10; 

// Try to create 'divisions' amount of dots between pos1 and pos2

function setup() {
  createCanvas(768,768);
  
}

function draw() {
  background(50,50,50);
  rectMode(CENTER);
  
  stroke(180,180,180);
  
  circle(pos1.x, pos1.y,dotRadius);
  circle(pos2.x, pos2.y,dotRadius);
  
  noLoop();
}

您可以使用 for 循环和条件来绘制在每次迭代中增加 x 和 y 值的圆。

let pos1 = {x:383,y:202};
let pos2 = {x:754,y:387};

let dotRadius = 5;

let divisions = 10;

// Try to create 'divisions' amount of dots between pos1 and pos2

let increment_x = (pos2.x-pos1.x)/(divisions+1)
let increment_y = (pos2.y-pos1.y)/(divisions+1)


function setup() {
  createCanvas(768,768);
  
}

function draw() {
  background(50,50,50);
  rectMode(CENTER);
  
  stroke(180,180,180);
  
  circle(pos1.x, pos1.y,dotRadius);
  circle(pos2.x, pos2.y,dotRadius);

  let y=pos1.y
  
  for (let x=pos1.x; x<pos2.x; x+=increment_x) {
    if (y<pos2.y){
      circle(x, y,dotRadius);
    }
    y+=increment_y
  }
}

计算两点之间的点的主要方法是获取 x-difference 和 y-difference。

let my = pos2.y - pos1.y;
let mx = pos2.x - pos1.x;

那么每个x-和y-coordinate之间可以根据起始位置、结束位置、分割数计算

完整代码(参见 p5.js Editor 上的 运行 示例):

let pos1 = { x: 383, y: 202 };
let pos2 = { x: 754, y: 387 };
let dotRadius = 5;
let divisions = 10;

// Try to create 'divisions' amount of dots between pos1 and pos2
function drawDivisions() {
  // Get the y-distance
  let my = pos2.y - pos1.y;

  // Get the x-distance
  let mx = pos2.x - pos1.x;

  // Add 1 to divisions so that it creates 'divisions' points between, not including start nor end
  let div = divisions + 1;

  // get the step value for y
  let dy = my / div;

  // get the step value for x
  let dx = mx / div;

  // Set a different color just to set these new dots apart
  stroke(240, 40, 180);

  // Enter the loop and create 'divisions' points
  for (let i = 1; i <= divisions; i++) {
    let x = pos1.x + dx * i;
    let y = pos1.y + dy * i;
    circle(x, y, dotRadius);
  }
}

function setup() {
  createCanvas(768, 768);
}

function draw() {
  background(50, 50, 50);
  rectMode(CENTER);

  stroke(180, 180, 180);

  circle(pos1.x, pos1.y, dotRadius);
  circle(pos2.x, pos2.y, dotRadius);

  // Enter our function to draw dots between start and end
  drawDivisions();

  noLoop();
}

现有的答案很好 (+1)。

我想为您指出另一种选择:线性插值(lerp())。

您将 fromto 值作为前两个参数传递,第三个参数控制将返回这两个值之间的金额。 第三个值是标准化值(即介于 0.0 和 1.0 之间)。 您可以将其视为百分比,其中:

  • 0.0 = 0 % = 第一个值
  • 1.0 = 100% = 第二个值
  • 0.5 = 50% = 在第一和第二之间 (按照这个逻辑,你可以使用这个十次,增量为 .1 以获得 10 个分区):

let pos1 = {x:383,y:202};
let pos2 = {x:754,y:387};

let dotRadius = 5;

let divisions = 10; 

// Try to create 'divisions' amount of dots between pos1 and pos2

function setup() {
  createCanvas(768,768);
  
}

function draw() {
  background(50,50,50);
  rectMode(CENTER);
  
  stroke(180,180,180);
  
  circle(pos1.x, pos1.y,dotRadius);
  circle(pos2.x, pos2.y,dotRadius);
  // in between points
  stroke(32);
  for(let i = 0 ; i < divisions; i++){
    // map 0-9 counter to 0.0 -> 1.0 lerp range
    let interpolationAmount = map(i, 0, divisions - 1, 0.0, 1.0);
    // calculate interpolated position
    let interpolatedX = lerp(pos1.x, pos2.x, interpolationAmount);
    let interpolatedY = lerp(pos1.y, pos2.y, interpolationAmount);
    // render dot (smaller as a way to visualise overlap with pos1, pos2)
    circle(interpolatedX, interpolatedY, dotRadius * 0.5);
  }
  
  noLoop();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>

(我们还使用了上面的 map():在这种情况下简单地将 i 除以 10 会很相似,但总的来说这是一个非常有用的函数)

此外,p5.js 已经提供了一个具有 x,y 属性的对象:p5.Vector. It can do a lot of cool things, but one of them is actually lerp()(查看示例)。

下面是使用 p5.Vector 的上述版本:

let pos1 = new p5.Vector(383,202);
let pos2 = new p5.Vector(754,387);

let dotRadius = 5;

let divisions = 10; 

// Try to create 'divisions' amount of dots between pos1 and pos2

function setup() {
  createCanvas(768,768);
  
}

function draw() {
  background(50,50,50);
  rectMode(CENTER);
  
  stroke(180,180,180);
  
  circle(pos1.x, pos1.y,dotRadius);
  circle(pos2.x, pos2.y,dotRadius);

  stroke(32);
  for(let i = 0 ; i < divisions; i++){
    // notice we're using p5.Vector.lerp() instead of pos1.lerp(pos2,...) so pos1 x,y remain intact
    let inBetween = p5.Vector.lerp(pos1, pos2, map(i, 0, divisions - 1, 0.0, 1.0));
    circle(inBetween.x, inBetween.y, dotRadius * 0.5);
  }
  
  noLoop();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>

希望这些在将来有用,但目前现有的答案已经足够了。