Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

336
Views
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?

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!

about 4 years ago · Santiago Trujillo
2 answers
Answer question

0

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.4.1/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.4.1/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.4.1/p5.js"></script>

about 4 years ago · Santiago Trujillo Report

0

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>

about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!