Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

195
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda