p5.j​​s:如何使用小椭圆形而不是line()函数在两个点之间绘制一条线?

发布于 2025-01-23 20:52:38 字数 896 浏览 2 评论 0原文

如何使用P5.JS中的一串小椭圆()函数连接两个点?

我正在尝试创建一个更“艺术”功能,以替换P5.js中的库存 函数。为了实现这一目标,我想编写一个函数,在给定两个点(x,y)和(x1,y1)的情况下,微小的圆圈密集&一贯沿着连接两个点的线绘制。

我尝试编写一个函数,该功能首先找到了所有可能的X& y点,然后使用有条件地绘制椭圆形,如果iJ和(x1,y1)之间的斜率与(x,y)给出的斜率匹配(x1,y1) (x1,y1)。

如果(x,y)和(x1,y1)的斜率为0、1或未定义,这只会给出我所需的结果;点间距随着任何其他坡度发生巨大变化。我无法弄清楚如何沿 任何线I输入的点放置点。

我的功能如下:

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的斜率值获得了期望的效果,但是当斜率是一个分数时,我却没有。 上述代码的输出,说明问题

我该如何修复我的功能?还是有什么完全更简单的方法可以做到这一点?非常感谢!

How can I connect two points using a string of tiny ellipses instead of the stock line() function in p5.js?

I am trying to create a more 'artistic' function to replace the stock line() function in p5.js. 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.

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).

This only gives my desired result if (x, y) and (x1, y1) have a slope of 0, 1, or undefined; 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

How can I fix my function? Or is there any entirely easier way to do this? Thanks so much!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浪漫人生路 2025-01-30 20:52:38

我认为您正在寻找两个点之间的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.6.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.6.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.6.0/p5.js"></script>

I think you're looking for lerp (linear interpolation) between two points. 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.6.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.6.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.6.0/p5.js"></script>

海未深 2025-01-30 20:52:38

我认为这里最简单的方法是使用一些向量和三角学,请尝试以下操作:

function setup() {
  createCanvas(windowWidth, windowHeight);
  v = createVector();
}

function draw() {
  background(255);
  customLine(width / 2, height / 2, mouseX, mouseY);
}

function customLine(x, y, x1, y1) {
  v.x = x1 - x;
  v.y = 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>

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) {
  v.x = x1 - x;
  v.y = 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>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文