• API
• FAQ
• Tools
• Trends
• Archive
SHARE
TWEET

# Crowd simulation in Python

a guest Jul 25th, 2010 841 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. import pygame, sys,os
2. from pygame.locals import *
3. from random import random, uniform, randrange
4. from math import sqrt, e, pi, cos, sin, atan
5. #--------------------------------------------------------------------------
6. Anagent class
7. class anagent:
8.     def __init__(self, x, y):
9.
10.         #position
11.         self.x = x
12.         self.y = y
13.
14.         self.tx = x
15.         self.ty = y
16.
17.         self.dx = 0
18.         self.dy = 0
19.         self.v = uniform(0.5, 2.5) #speed
20.         self.idle = False
21.
22.     def setTarget(self,x,y):
23.         self.tx = x
24.         self.ty = y
25.
26. #--------------------------------------------------------------------------
27. #Basic Setup
28. pygame.init()
29. w=400
30. h=400
31. window = pygame.display.set_mode((w, h))
32. pygame.display.set_caption('Crowd Sim')
33. screen = pygame.display.get_surface()
34. layer1 = pygame.Surface((w,h))
35. layer1.fill((0,0,0))
36. layer1.set_colorkey((0,0,0))
37.
38. #POT_EXTEND = 30         #how much the potential extends forwards from a person
39. #POT_DECAY = 0.01        #how fast the potential function decays per agent
40. POT_EXTEND = 22
41. POT_DECAY = 0.027
42. POT_STRENGTH = 350         #how much the agents are affected by the potential field
43.
44. POT_DRAWFIELD = False    #draw the potential field?
45.
46. iter = 0
47.
48. PPL = 20
49. agent = []
51. ttt = 0
52. #--------------------------------------------------------------------------
53. #Defs
54.
55. #handler for events
56. def input(events):
57.     global POT_EXTEND
58.     global POT_DECAY
59.     global POT_STRENGTH
60.     global POT_DRAWFIELD
61.     global agent
62.     global layer1
63.     for event in events:
64.         if event.type == QUIT:
65.             sys.exit(0)
66.         elif event.type == KEYDOWN:
67.             if event.key == K_ESCAPE:
68.                 sys.exit(0)
69.             elif event.key == K_i:
70.                 POT_EXTEND += 1
71.                 print "POT_EXTEND = " + `POT_EXTEND`
72.             elif event.key == K_u:
73.                 POT_EXTEND -= 1
74.                 print "POT_EXTEND = " + `POT_EXTEND`
75.             elif event.key == K_j:
76.                 POT_DECAY -= 0.001
77.                 print "POT_DECAY = " + `POT_DECAY`
78.             elif event.key == K_k:
79.                 POT_DECAY += 0.001
80.                 print "POT_DECAY = " + `POT_DECAY`
81.             elif event.key == K_m:
82.                 POT_STRENGTH += 20
83.                 print "POT_STRENGTH = " + `POT_STRENGTH`
84.             elif event.key == K_n:
85.                 POT_STRENGTH -= 20
86.                 print "POT_STRENGTH = " + `POT_STRENGTH`
87.             elif event.key == K_f:
88.                 POT_DRAWFIELD = not POT_DRAWFIELD
89.                 print "draw field toggled"
90.             elif event.key == K_r:
91.                 agent = []
92.                 resetAgents()
93.                 layer1.fill((0,0,0))
94.                 print "Agents reset"
96. def totalDangerAt(x, y):
97.     global agent
98.     danger = 0
99.     for a in agent:
100.        danger += dangerDue(x,y,a)
101.     return danger
102.
103. #return danger to an agent a from position x,y
104. def dangerDue(x, y, a):
105.     global POT_EXTEND
106.     global POT_DECAY
107.     px2 = a.x + POT_EXTEND*a.dx
108.     py2 = a.y + POT_EXTEND*a.dy
109.     d1 = sqrt((a.x - x)**2 + (a.y - y)**2)
110.     d2 = sqrt((px2 - x)**2 + (py2 - y)**2)
111.     danger = e**(-POT_DECAY*(d1 + d2))
112.     return danger
113.
114.
115. #return the gradient of danger at position x,y due to agent a
117.     global POT_EXTEND
118.     global POT_DECAY
119.     px2 = a.x + POT_EXTEND*a.dx
120.     py2 = a.y + POT_EXTEND*a.dy
121.     d1 = sqrt((a.x - x)**2 + (a.y - y)**2)
122.     d2 = sqrt((px2 - x)**2 + (py2 - y)**2)
123.     danger = e**(-POT_DECAY*(d1 + d2))
124.
125.     multiplierx = -POT_DECAY*(x - a.x)/(2*d1) - POT_DECAY*(x - px2)/(2*d2)
126.     multipliery = -POT_DECAY*(y - a.y)/(2*d1) - POT_DECAY*(y - py2)/(2*d2)
127.
128.     return (danger*multiplierx, danger*multipliery)
129.
130. #return the total gradient of danger at position x,y due to all agents
132.     global agent
133.     totx = 0
134.     toty = 0
135.     for a in agent:
136.         if not (a.x == x and a.y == y):
137.             res = gradDangerDue(x, y, a)
138.             totx += res[0]
139.             toty += res[1]
140.     return (totx, toty)
141.
142. #generate agents
143. def resetAgents():
144.     global agent, PPL, w, h
145.     for i in range (0, PPL):
146.         if i < PPL/2: #left and right walkers
147.             newagent = anagent(w/10 + uniform(-100,100),random()*h/2 + h/4)
148.             newagent.setTarget(w +10,newagent.y)
149.             #newagent.setTarget(w/2,h/2)
150.         else:
151.             newagent = anagent(w - w/10 + uniform(-100,100),random()*h/2 + h/4)
152.             newagent.setTarget(-10,newagent.y)
153.             #newagent.setTarget(w/2,h/2)
154.
155.         newagent.idle = False
156.
157.         agent.append(newagent)
158.
159. #at corners
160. def resetAgents2():
161.     global agent, PPL, w, h
162.     n = PPL/4
163.     for i in range(n):
164.         newagent = anagent(uniform(0, 100),uniform(0, 100))
165.         newagent.setTarget(w,h)
166.         newagent.idle = False
167.         agent.append(newagent)
168.     for i in range(n):
169.         newagent = anagent(uniform(w-100, w),uniform(0, 100))
170.         newagent.setTarget(0,h)
171.         newagent.idle = False
172.         agent.append(newagent)
173.     for i in range(n):
174.         newagent = anagent(uniform(0, 100),uniform(h-100, h))
175.         newagent.setTarget(w,0)
176.         newagent.idle = False
177.         agent.append(newagent)
178.     for i in range(n):
179.         newagent = anagent(uniform(w-100,w),uniform(h-100, h))
180.         newagent.setTarget(0,0)
181.         newagent.idle = False
182.         agent.append(newagent)
183.
184. #in circle
185. def resetAgents3():
186.     global agent, PPL, w, h
187.     r = min(w, h)*0.9/2
188.     incr = 2*pi/PPL
189.     for i in range(PPL):
190.         newagent = anagent(w/2 + r*cos(incr*i), h/2 + r*sin(incr*i))
191.         newagent.setTarget(w/2 + r*cos(incr*i + pi), h/2 + r*sin(incr*i + pi))
192.         agent.append(newagent)
193.
194. #from all over the place to middle
195. def resetAgents4():
196.     global agent, PPL, w, h
197.     for i in range(PPL):
198.         newagent = anagent(uniform(-w, 2*w), uniform(-h, 2*h))
199.         newagent.setTarget(w/2, h/2)
200.         agent.append(newagent)
201.
202. #--------------------------------------------------------------------------
203. resetAgents3()
204. #MAIN LOOP
205. while True:
206.    input(pygame.event.get())
207.    pygame.time.delay(30)
208.
209.    screen.fill((0,0,50))
210.
211.    if POT_DRAWFIELD:
212.        #calculate the danger field
213.        for x in range(0,w,10):
214.            for y in range(0,h,10):
215.
216.                danger = 2*POT_STRENGTH*totalDangerAt(x,y)
217.
218.                #print danger
219.                dng = 0
220.                if danger > 255:
221.                    dng = danger - 255
222.                    danger = 255
223.
224.                if dng > 255:
225.                    dng = 255
226.
227.                pygame.draw.circle(screen, (danger,dng,0), (x,y), 7)
228.
229.    #update agents
230.    for a in agent:
231.        dx = 0
232.        dy = 0
233.
234.        if not a.idle:
235.            d = sqrt((a.tx - a.x)**2 + (a.ty - a.y)**2)
236.
237.            if d > a.v:
238.                dx = a.v*(a.tx - a.x)/d
239.                dy = a.v*(a.ty - a.y)/d
240.            else:
241.                #a.idle = True
242.                a.setTarget(random()*w, random()*h)
243.
244.                #if random() < 0.5:
245.                #    a.x = -30
246.                #    a.y = random()*h/2 + h/4
247.                #    a.setTarget(w +10,a.y)
248.                #else:
249.                #    a.x = w + 30
250.                #    a.y = random()*h/2 + h/4
251.                #    a.setTarget(-10,a.y)
252.
253.        #now calculate force due to poptential at this point.
254.        #we do this by summing up all the gradients at this point
255.        #of all functions that each agent generates.
262.        #pygame.draw.circle(screen, (0, 255, 0) , (a.x + a.dx, a.y + a.dy), 10, 5)
263.        #pygame.draw.circle(screen, (255, 255, 255) , (a.tx, a.ty), 5, 1)
264.
265.        pygame.draw.line(screen, (255,255,0), (a.x,a.y), (a.tx, a.ty))
267.
268.        #normalize velocity to agents speed
269.        lengthv = sqrt(dx*dx + dy*dy)
270.        dx = a.v*dx/lengthv
271.        dy = a.v*dy/lengthv
272.
273.        pygame.draw.line(layer1, (50,50,0), (a.x,a.y), (a.x + a.dx, a.y + a.dy))
274.        a.x += dx
275.        a.y += dy
276.        a.dx = dx
277.        a.dy = dy
278.
279.        #draw agent and his direction of motion
280.        #pygame.draw.circle(screen, (255, 255, 0) , (a.x, a.y), 17, 1)
281.        #ang = atan(a.dy/a.dx)
282.        #if a.dx < 0:
283.        #    ang += pi
284.
285.        #nf =pygame.transform.rotate(footman[int(ttt)],90 - ang*180/pi)
286.        #ttt+=0.025
287.        #if ttt > 3:
288.        #    ttt = 0
289.        #screen.blit(nf, (a.x - nf.get_rect().width/2, a.y - nf.get_rect().height/2))
290.
291.        pygame.draw.circle(screen, (0, 255, 255) , (a.x, a.y), 10, 1)
292.        pygame.draw.line(screen, (255,255,255), (a.x,a.y), (a.x+6*a.dx, a.y+6*a.dy))
293.
294.
295.    #pygame.draw.line(screen, (255,255,255), (px,py), pygame.mouse.get_pos())
296.    #pygame.draw.circle(screen, (0, 255, 0) , (px, py), 10)
297.    #screen.blit(layer1, (0,0))
298.
299.    pygame.display.flip()
300.    #pygame.image.save(screen, "C:\pics\p" + `iter` + ".bmp")
301.    #iter += 1
RAW Paste Data
Top