Home‎ > ‎Python‎ > ‎

Particle Simulation

Here is how to do a basic particle simulation in Python using PyGame.

This is a movie of a basic 2d particle simulation emulating particles that are attracted to each other, while simultaneously avoiding getting too close.

Running on a Mac with Python 2.5? Install pygame and pyobjc from http://rene.f0o.com/~rene/stuff/macosx/. OS X 10.4 versions also work in OS X 10.5.


# Particle Simulator

import sys, os, pygame, random, math
from pygame.locals import *

if sys.platform == 'win32': #for compatibility on some hardware platforms
    os.environ['SDL_VIDEODRIVER'] = 'windib'
   
xmax = 1000    #width of window
ymax = 600     #height of window
psize = 3      #particle size

class Particle:
   def __init__(self, x = 0, y = 0, dx = 0, dy = 0, col = (255,255,255)):
       self.x = x    #absolute x,y in pixel coordinates
       self.y = y
       self.rx = x   #absolute x,y in real coordinates
       self.ry = y
       self.dx = dx   #force-like vectors
       self.dy = dy
       self.col = col

   def mass(self, points):
       dx = 0.0
       dy = 0.0
       for p in points:         #where is everybody else?
           dx1 = p.rx - self.rx
           dy1 = p.ry - self.ry
          
           d = math.sqrt(pow(dx1, 2) + pow(dy1, 2))   #distance from me to p

           if d > 15:
               w = math.exp(-0.015*(d-15))
               dx += w * dx1/d
               dy += w * dy1/d
           else:
               dx -= 7 * dx1
               dy -= 7 * dy1

       #induce simple drag and energy
       self.dx = 0.98 * self.dx + 0.03 * dx
       self.dy = 0.98 * self.dy + 0.03 * dy
       
   def move(self):
       if self.x <= 0:
           if self.dx < 0: self.dx = -self.dx
       elif self.x >= xmax:
           if self.dx > 0: self.dx = -self.dx
       if self.y <= 0:
           if self.dy < 0: self.dy = -self.dy
       elif self.y >= ymax:
           if self.dy > 0: self.dy = -self.dy
              
       self.rx += self.dx
       self.ry += self.dy
       self.x = int(self.rx + 0.5)
       self.y = int(self.ry + 0.5)
      
def main():
   # Initialize PyGame
   pygame.init()
   pygame.display.set_caption('Particle Sim')
   screen = pygame.display.set_mode((xmax,ymax))
   #want fullscreen? pygame.display.set_mode((xmax,ymax), pygame.FULLSCREEN)
   white = (255, 255, 255)
   black = (0,0,0)

   particles = []
   for i in range(100):
       if i % 2 > 0: col = black
       else: col = black
       particles.append( Particle(random.randint(1, xmax-1), random.randint(1, ymax-1), 0, 0, col) )

   exitflag = False
   while not exitflag:
      
       # Handle events
       for event in pygame.event.get():
           if event.type == QUIT:
               exitflag = True
           elif event.type == KEYDOWN:
               if event.key == K_ESCAPE:
                   exitflag = True
       screen.fill(white)
       for p in particles:
           p.mass(particles)
       for p in particles:
           p.move()
           pygame.draw.circle(screen, p.col, (p.x, p.y), psize)
          
       pygame.display.flip()

   # Close the Pygame window
   pygame.quit()

#Run the system

if __name__ == "__main__":
    main()
ċ
Niels Stender,
May 23, 2008, 11:24 AM
Comments