簡體   English   中英

p5.js:如何使用小橢圓而不是 line() 函數在兩點之間畫一條線?

[英]p5.js: how can I draw a line between two points using tiny ellipses instead of the line() function?

我如何使用一串小橢圓而不是 p5.js 中的 stock line()函數連接兩點?

我正在嘗試創建一個更“藝術”的函數來替換 p5.js 中的 stock line()函數。 為實現這一點,我想編寫一個函數,其中給定兩個點 (x, y) 和 (x1, y1),沿連接兩點的直線密集且一致地繪制小圓圈。

我嘗試編寫一個函數,首先找到所有可能的 x 和 y 點,然后使用條件僅在ij和 (x1, y1) 之間的斜率與 (x, y) 和 (x1) 給出的斜率匹配時繪制橢圓, y1).

如果 (x, y) 和 (x1, y1) 的斜率為 0、1 或未定義,這只會給出我想要的結果; 點間距隨任何其他斜率而顯着變化。 我無法弄清楚如何沿着我輸入的任何行獲得一致放置的點。

我的功能如下:

function customLine(x, y, x1, y1) {
  for (var i = x; i >= x && i <= x1; i ++) { 
   for (var j = y; j >= y && j <= y1; j ++) {
    if ((j - y) / (i - x) == (y1 - y) / (x1 - x)) {
     fill(0);
     circle(i, j, 5);
   }
  }
 }
}

我還附上了一張圖片,顯示我對 0、未定義或 1 的斜率值得到了我想要的效果,但當斜率是分數時卻沒有:上面代碼的輸出,說明問題

我該如何修復我的功能? 或者有沒有更簡單的方法來做到這一點? 非常感謝!

我認為您正在尋找兩點之間的lerp (線性插值)。 例如,

 let anchor; function setup() { createCanvas(innerWidth, innerHeight); noLoop(); anchor = createVector(innerWidth / 2, innerHeight / 2); } function draw() { drawDottedLine(anchor, createVector(mouseX, mouseY)); } function mouseMoved() { clear(); drawDottedLine(anchor, createVector(mouseX, mouseY)); } const drawDottedLine = (p1, p2) => lerpLine(p1, p2).forEach(({x, y}) => circle(x, y, 10)); const lerpLine = (p1, p2, steps = 10) => [...Array(steps)].map((_, i) => p5.Vector.lerp(p1, p2, norm(i, 0, steps)));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>

如果您希望間距保持一致並使用可變數量的點,則可以將兩點之間的距離作為步數傳遞:

 let anchor; let mouse; function setup() { createCanvas(innerWidth, innerHeight); noLoop(); anchor = createVector(innerWidth / 2, innerHeight / 2); mouse = createVector(0, 0); } function draw() { drawDottedLine(anchor, mouse, anchor.dist(mouse) / 16); } function mouseMoved() { clear(); mouse.x = mouseX; mouse.y = mouseY; drawDottedLine(anchor, mouse, floor(anchor.dist(mouse) / 16)); } const drawDottedLine = (p1, p2, steps) => lerpLine(p1, p2, steps).forEach(({x, y}) => circle(x, y, 10)); const lerpLine = (p1, p2, steps = 10) => [...Array(steps)].map((_, i) => p5.Vector.lerp(p1, p2, norm(i, 0, steps)));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>

或者添加離散化:

 let anchor; let mouse; function setup() { createCanvas(innerWidth, innerHeight); noLoop(); anchor = createVector(innerWidth / 2, innerHeight / 2); mouse = createVector(0, 0); } function mouseMoved() { clear(); const spacing = 10; mouse.x = floor(mouseX / spacing) * spacing; mouse.y = floor(mouseY / spacing) * spacing; const steps = floor(anchor.dist(mouse) / spacing); drawDottedLine(anchor, mouse, steps); } const drawDottedLine = (p1, p2, steps) => lerpLine(p1, p2, steps).forEach(({x, y}) => circle(x, y, 10)); const lerpLine = (p1, p2, steps = 10) => [...Array(steps)].map((_, i) => p5.Vector.lerp(p1, p2, norm(i, 0, steps)));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>

我認為這里最簡單的方法是使用一些向量和三角函數,請試試這個:

 function setup() { createCanvas(windowWidth, windowHeight); v = createVector(); } function draw() { background(255); customLine(width / 2, height / 2, mouseX, mouseY); } function customLine(x, y, x1, y1) { vx = x1 - x; vy = y1 - y; for (let i = 0; i < v.mag(); i++) { fill(0).circle(x + i * cos(v.heading()), y + i * sin(v.heading()), 5); } }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.js"></script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM