#### Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

# How to apply a repulsion force to a particle system ?

edited February 2018

Hi !

I've recently found this article from Zachary Lieberman where he provides some insights on his work. I'm particularly interested in his "recipe" to make a blob moving "organically" (almost like a fluid). This is a 2-step process:

• connect particles with springs (and connect the last particle to the first particle, making a loop)
• give the particles a repulsion force from each other that is proportional to distance (stronger force when closer) and has a maximum radius for interaction (i.e., if particles are beyond this distance, they don’t have an impact on each other)

I made both a particle and a spring class but got lost when trying to implement the repulsion force. What should I change (add ?) in the following snippet (a spring class using basic Hooke's law) to "give the particles a repulsion force from each other that is proportional to distance" ?

spring class

``````class Spring(object):

def __init__(self, x, y, l):
self.startpoint = PVector(x, y)
self.constant = .2
self.lngth = l
self.g = 10
self.mass = 4

def connect(self, p):    # p refers to the particle_class
force = PVector.sub(p.location, self.startpoint)
distance = force.mag()
stretch = distance - self.lngth

force.normalize()
force *= -1 * self.constant * stretch   # Hooke's law
force.limit(.4)
p.applyForce(force)

def displayLine(self, p):
stroke(255)
strokeWeight(1)
line(p.location.x, p.location.y, self.startpoint.x, self.startpoint.y)
``````

On a side note, I'm also curious to know how to display particles following a splatter shape (GIF above).

Tagged:

• edited February 2018 Answer ✓

UPDATE

I think I've managed to give the particles a repulsion force from each other that is proportional to distance but the result is very (very) different from what I expected:

https://media.giphy.com/media/aiFDgXqkEuD6MJWleK/giphy.gif

As you can see all the particles are interconnected with springs but shortly after the start they bounce all over the place, the springs get mixed up and the original vertex eventually split in many pieces.

Either there's something wrong with my repulsion force or I've missed something in the process.

About the repulsion force: I just applied a negative graviational force to each particle and divided this force by the distance separating a particle from another (the closer the stronger).

Repulsion force snippet

``````for i, e in enumerate(particules):
for j, f in enumerate(particules):
if e != f:
force = PVector.sub(e.location, f.location)
dsq = force.magSq()
strength = (e.g * e.mass * f.mass) / dsq
force *= -strength
f.applyForce(force)
``````

2 QUESTIONS:

• Does the repulsion force above seem correct to you ?
• Do you have an idea of what the problem could be ? (just looking at the GIF)

Full code:

``````from particle import Particle
from spring import Spring

def setup():
global particules, elastiques, n_particle
size(800, 600)

particules = []
elastiques = []
n_particle = 10

for e in range(n_particle):
angle = TWO_PI  / n_particle
x = radius * sin(angle * e) + map(noise(random(-20, 20)), 0, 1, -20, 20)
y = radius * cos(angle * e)
particules.append(Particle(width / 2 + x, height / 2 + y))

def draw():
global particules, elastiques
background(0)

for e in particules:
e.display()
e.update()

for e in range(n_particle):
n = 1
if e+n == n_particle:
n = - (n_particle - 1)
elastiques.append(Spring(particules[e+n].location.x, particules[e+n].location.y, 1))

if len(elastiques) - 1 == n_particle:
del elastiques

for j, e in enumerate(elastiques):
for i, p in enumerate(particules):
e.displayLine(p)
e.connect(p)

beginShape()
fill(255)
stroke(255)
for e in range(n_particle):
vertex(particules[e].location.x,particules[e].location.y)
endShape()

for i, e in enumerate(particules):
for j, f in enumerate(particules):
if e != f:
force = PVector.sub(e.location, f.location)
dsq = force.magSq()
strength = (e.g * e.mass * f.mass) / dsq
force *= -strength / dsq
f.applyForce(force)
e.applyForce(force)
``````

Particle class

``````class Particle(object):

def __init__(self, x, y):
self.location = PVector(x, y)
self.velocity = PVector()
self.acceleration = PVector()
self.mass = 4
self.g = 1

def applyForce(self, f):
f = f / self.mass
self.velocity += f

def update(self):
self.velocity += self.acceleration
self.location += self.velocity
self.acceleration *= 0

def display(self):
fill(255)
noStroke()
ellipse(self.location.x, self.location.y, 6, 6)
``````

Spring class

``````class Spring(object):

def __init__(self, x, y, longueur):
self.startpoint = PVector(x, y)
self.constante = .2
self.longueur = longueur
self.g = 1
self.mass = 4

def connect(self, p):
force = PVector.sub(p.location, self.startpoint)
distance = force.mag()
stretch = distance - self.longueur

force.normalize()
force *= -1 * self.constante * stretch
force.limit(.1)
p.applyForce(force)

def displayLine(self, p):
stroke(255)
strokeWeight(.2)
line(p.location.x, p.location.y, self.startpoint.x, self.startpoint.y)
``````
• Anyone ?

• Anyone ?

• Your gif shows points repeatedly falling through the center and out the other side. If there is repulsion force, it is Set nowhere near strong enough to overcome gravity and cause a bounce -- which is presumably what you want...?

• @jeremydouglass, thank you for your feedback. I do want the particles to bounce but simply not that way. For example, when a particle originally placed on the left goes too far to the right and crosses other particles (originally placed on the right side of the circle), the circular shape formed by the vertices then splits up and divides into portions. I do not want that behavior. I think now the problem lies in the way the particles are connected (fully interconnected network vs simple linear connection)

Now, did I managed to apply a repulsion force to every single particles ? I believe so and in this regard I would understand if my original question was marked as answered.

• I think I'm just having a hard time understanding what you are trying to accomplish. For example, in the animation you share, line segments don't cross because of strong repulsive forces. That is why the example looks like a blob.

You seem to want your points to cross due to very weak repulsive forces... but I don't understand what you think should happen visually when you allow crossing to occur. Is there a reference image of what you want it to look like when crossing happens? For example, do you always want to draw a convex hull around your collection of bouncing points, rather than maintaining inter-point springs?

• @jeremydouglass I'm sorry I couldn't make myself clear. I don't want points to cross at all. I would like to be able to make blobs behave exactly like in the GIF made by Zachary Lieberman.

As mentionned in my last comment, one of the problems was that I had connected particles the wrong way: each particle was connected to every other particles instead of just being connected successively (like a ring). It's now fixed (see link below).

https://media.giphy.com/media/1k2wspz8guv3PZ7dYq/giphy.gif

The last and only problem (let's hope) I'm facing now is concerning the repulsion force. In the GIF I made above the repulsion force is unchanging and triggered at a specific threshold.

Instead, It should be proportional to distance (the closer a particle is to another particle, the stronger is the repulsion) but i don't know how to implement such behavior with toxiclibs (hence the new question I posted yesterday).

• Got it. Glad you figured it out for the non-toxiclibs setup!

• :)