Applying bounds to a force directed graph

Hi there,

I have a sketch that uses a force directed graph code example I found, but there’s nothing in it to stop clusters of nodes drifting off-screen due to the repulsive force, and the fact that clusters are not always connected.

I’m looking for a way to keep all nodes inside the sketch bounds.

I’m not sure which part of the code to post, but this is the updatePosition function in the GraphVertex class (the node class):

  void updatePosition( float deltaT ){
    
    float accelerationX = frc.x / mass;
    float accelerationY = frc.y / mass;
      
    setAcceleration(accelerationX, accelerationY);

    float velocityX = (vel.x + deltaT * accelerationX) * DAMPING_COEFFICIENT;
    float velocityY = (vel.y + deltaT * accelerationY) * DAMPING_COEFFICIENT;

    setVelocity(velocityX, velocityY);    
      
    float x = (float) (pos.x + deltaT * velocityX + accelerationX * Math.pow(deltaT, 2.0f) / 2.0f);
    float y = (float) (pos.y + deltaT * velocityY + accelerationY * Math.pow(deltaT, 2.0f) / 2.0f);

    setPosition( x, y );
      
  }

Thanks for reading. Any help much appreciated!

Dan

1 Like
    x = constrain(x,0,width);
    y = constrain(y,0,height);

    setPosition( x, y );
}
1 Like

Nice, thank you @TfGuy44.

That works great, except now I have another challenge: Many of my nodes are lined up along the edges (there are 1050 nodes). Is there a way to add gravity to have them drift inwards?

Their positions are limited, but there velocities and accelerations are not! A gravity pull towards the center is a small amount of acceleration towards (width/2,height/2). One simple approach might be:

For each node:

If the x position of the node is mode than width/2, add a small amount of negative acceleration. If it’s not, add a small amount of positive acceleration.

If the y position of the node is mode than height/2, add a small amount of negative acceleration. If it’s not, add a small amount of positive acceleration.

1 Like

Perfect, thanks @TfGuy44.

I was able to duplicate the applySpringForce() function and add a gravity spring on each node to the centre at width/2,height/2.

A bit of tweaking and it all sits well.
I also made the x-axis gravity slightly less so it settles neatly within the landscape format window.

Appreciate the help!

1 Like