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

191
Views
Mutual repulsion force in js

I have a 1-dimensional dataset (a list of elements with only a horizontal position (+ circle radius)).

I want to implement a simple layout algorithm to show this dataset as circles in a scale. The problem is the collisions.

enter image description here

I want to implement a "simple" repulsion force to avoid collisions. I don't mind the circles won't have a precise position anymore. The result I'm looking for is simple as that:

enter image description here

I'm not using D3, it is plain js (and svg.js), where to start looking for theoretical information about this layout? What is the common name with which this force is referred to? Is there any example of similar things?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

I've added min_gap for minimum margin between elements. So the solution is to move two intersected elements with most intersected distance on a small step at a time.

const elements = [{pos:10, radius:5}, {pos:15, radius: 20}, {pos:20, radius:10}, {pos:150, radius:5}];

const field_size = [0, 300];

const min_gap = 5;
const step = 1;

moveIntersected(elements);

console.log(elements);

function detectCollisions(arr=[]){
    const result = [];
    for(let i=0; i < arr.length - 1; i++){
        let dist = (arr[i+1].pos - arr[i+1].radius) - (arr[i].pos + arr[i].radius);
        if(dist < min_gap){
            result.push([i + 0.5, dist]);
        }
    }
    return result;
}

function moveIntersected(arr=[]){

    const collisions = detectCollisions(arr);
    if(collisions.length < 1) return;
    
    const most_intersected = collisions.sort((a,b) => a[1] - b[1])[0];
    const left = arr[Math.floor(most_intersected[0])];
    const right = arr[Math.ceil(most_intersected[0])];
    
    if(left.pos - left.radius - step >= field_size[0]){
        left.pos -= step;
    } else {
        right.pos += step*2;
    }
    
    if(right.pos + right.radius + step <= field_size[1]){
        right.pos += step;
    } else {
        left.pos -= step*2;
    }
    moveIntersected(arr);
}

about 4 years ago · Juan Pablo Isaza 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!