[英]p5.js: how can I draw a line between two points using tiny ellipses instead of the line() function?
How can I connect two points using a string of tiny ellipses instead of the stock line()
function in p5.js?我如何使用一串小椭圆而不是 p5.js 中的 stock
line()
函数连接两点?
I am trying to create a more 'artistic' function to replace the stock line()
function in p5.js.我正在尝试创建一个更“艺术”的函数来替换 p5.js 中的 stock
line()
函数。 To achieve this, I want to write a function where given two points (x, y) and (x1, y1), tiny circles are densely & consistently drawn along the line connecting the two points.为实现这一点,我想编写一个函数,其中给定两个点 (x, y) 和 (x1, y1),沿连接两点的直线密集且一致地绘制小圆圈。
I tried writing a function that first finds all possible x & y points and then use a conditional to only draw an ellipse if the slope between i
and j
and (x1, y1) matches the slope given by (x, y) and (x1, y1).我尝试编写一个函数,首先找到所有可能的 x 和 y 点,然后使用条件仅在
i
和j
和 (x1, y1) 之间的斜率与 (x, y) 和 (x1) 给出的斜率匹配时绘制椭圆, y1).
This only gives my desired result if (x, y) and (x1, y1) have a slope of 0, 1, or undefined;如果 (x, y) 和 (x1, y1) 的斜率为 0、1 或未定义,这只会给出我想要的结果; the dot spacings change dramatically with any other slope.
点间距随任何其他斜率而显着变化。 I can't figure out how to get consistently placed dots along any line I input.
我无法弄清楚如何沿着我输入的任何行获得一致放置的点。
My function is as follows:我的功能如下:
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);
}
}
}
}
I've also attached an image showing that I get my desired effect for slope values of 0, undefined, or 1, but not when the slope is a fraction: output of above code, illustrating issue我还附上了一张图片,显示我对 0、未定义或 1 的斜率值得到了我想要的效果,但当斜率是分数时却没有:上面代码的输出,说明问题
How can I fix my function?我该如何修复我的功能? Or is there any entirely easier way to do this?
或者有没有更简单的方法来做到这一点? Thanks so much!
非常感谢!
I think you're looking for lerp
(linear interpolation) between two points.我认为您正在寻找两点之间的
lerp
(线性插值)。 For example,例如,
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>
If you're looking for the spacing to remain consistent and use a variable number of points, you can pass the distance between the two points as the number of steps:如果您希望间距保持一致并使用可变数量的点,则可以将两点之间的距离作为步数传递:
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>
Or add discretizing:或者添加离散化:
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>
I think the easiest way here is to use some vectors and trigonometry, please try this:我认为这里最简单的方法是使用一些向量和三角函数,请试试这个:
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.