Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import pygame, sys,os
- from pygame.locals import *
- from random import random, uniform, randrange
- from math import sqrt, e, pi, cos, sin, atan
- #--------------------------------------------------------------------------
- Anagent class
- class anagent:
- def __init__(self, x, y):
- #position
- self.x = x
- self.y = y
- self.tx = x
- self.ty = y
- self.dx = 0
- self.dy = 0
- self.v = uniform(0.5, 2.5) #speed
- self.idle = False
- def setTarget(self,x,y):
- self.tx = x
- self.ty = y
- #--------------------------------------------------------------------------
- #Basic Setup
- pygame.init()
- w=400
- h=400
- window = pygame.display.set_mode((w, h))
- pygame.display.set_caption('Crowd Sim')
- screen = pygame.display.get_surface()
- layer1 = pygame.Surface((w,h))
- layer1.fill((0,0,0))
- layer1.set_colorkey((0,0,0))
- #POT_EXTEND = 30 #how much the potential extends forwards from a person
- #POT_DECAY = 0.01 #how fast the potential function decays per agent
- POT_EXTEND = 22
- POT_DECAY = 0.027
- POT_STRENGTH = 350 #how much the agents are affected by the potential field
- POT_DRAWFIELD = False #draw the potential field?
- iter = 0
- PPL = 20
- agent = []
- footman = (pygame.image.load("C:/footman_1.gif"),pygame.image.load("C:/footman_2.gif"),pygame.image.load("C:/footman_3.gif"))
- ttt = 0
- #--------------------------------------------------------------------------
- #Defs
- #handler for events
- def input(events):
- global POT_EXTEND
- global POT_DECAY
- global POT_STRENGTH
- global POT_DRAWFIELD
- global agent
- global layer1
- for event in events:
- if event.type == QUIT:
- sys.exit(0)
- elif event.type == KEYDOWN:
- if event.key == K_ESCAPE:
- sys.exit(0)
- elif event.key == K_i:
- POT_EXTEND += 1
- print "POT_EXTEND = " + `POT_EXTEND`
- elif event.key == K_u:
- POT_EXTEND -= 1
- print "POT_EXTEND = " + `POT_EXTEND`
- elif event.key == K_j:
- POT_DECAY -= 0.001
- print "POT_DECAY = " + `POT_DECAY`
- elif event.key == K_k:
- POT_DECAY += 0.001
- print "POT_DECAY = " + `POT_DECAY`
- elif event.key == K_m:
- POT_STRENGTH += 20
- print "POT_STRENGTH = " + `POT_STRENGTH`
- elif event.key == K_n:
- POT_STRENGTH -= 20
- print "POT_STRENGTH = " + `POT_STRENGTH`
- elif event.key == K_f:
- POT_DRAWFIELD = not POT_DRAWFIELD
- print "draw field toggled"
- elif event.key == K_r:
- agent = []
- resetAgents()
- layer1.fill((0,0,0))
- print "Agents reset"
- #return total danger due to all agents from position x,y
- def totalDangerAt(x, y):
- global agent
- danger = 0
- for a in agent:
- danger += dangerDue(x,y,a)
- return danger
- #return danger to an agent a from position x,y
- def dangerDue(x, y, a):
- global POT_EXTEND
- global POT_DECAY
- px2 = a.x + POT_EXTEND*a.dx
- py2 = a.y + POT_EXTEND*a.dy
- d1 = sqrt((a.x - x)**2 + (a.y - y)**2)
- d2 = sqrt((px2 - x)**2 + (py2 - y)**2)
- danger = e**(-POT_DECAY*(d1 + d2))
- return danger
- #return the gradient of danger at position x,y due to agent a
- def gradDangerDue(x,y,a):
- global POT_EXTEND
- global POT_DECAY
- px2 = a.x + POT_EXTEND*a.dx
- py2 = a.y + POT_EXTEND*a.dy
- d1 = sqrt((a.x - x)**2 + (a.y - y)**2)
- d2 = sqrt((px2 - x)**2 + (py2 - y)**2)
- danger = e**(-POT_DECAY*(d1 + d2))
- multiplierx = -POT_DECAY*(x - a.x)/(2*d1) - POT_DECAY*(x - px2)/(2*d2)
- multipliery = -POT_DECAY*(y - a.y)/(2*d1) - POT_DECAY*(y - py2)/(2*d2)
- return (danger*multiplierx, danger*multipliery)
- #return the total gradient of danger at position x,y due to all agents
- def gradDangerAt(x, y):
- global agent
- totx = 0
- toty = 0
- for a in agent:
- if not (a.x == x and a.y == y):
- res = gradDangerDue(x, y, a)
- totx += res[0]
- toty += res[1]
- return (totx, toty)
- #generate agents
- def resetAgents():
- global agent, PPL, w, h
- for i in range (0, PPL):
- if i < PPL/2: #left and right walkers
- newagent = anagent(w/10 + uniform(-100,100),random()*h/2 + h/4)
- newagent.setTarget(w +10,newagent.y)
- #newagent.setTarget(w/2,h/2)
- else:
- newagent = anagent(w - w/10 + uniform(-100,100),random()*h/2 + h/4)
- newagent.setTarget(-10,newagent.y)
- #newagent.setTarget(w/2,h/2)
- newagent.idle = False
- agent.append(newagent)
- #at corners
- def resetAgents2():
- global agent, PPL, w, h
- n = PPL/4
- for i in range(n):
- newagent = anagent(uniform(0, 100),uniform(0, 100))
- newagent.setTarget(w,h)
- newagent.idle = False
- agent.append(newagent)
- for i in range(n):
- newagent = anagent(uniform(w-100, w),uniform(0, 100))
- newagent.setTarget(0,h)
- newagent.idle = False
- agent.append(newagent)
- for i in range(n):
- newagent = anagent(uniform(0, 100),uniform(h-100, h))
- newagent.setTarget(w,0)
- newagent.idle = False
- agent.append(newagent)
- for i in range(n):
- newagent = anagent(uniform(w-100,w),uniform(h-100, h))
- newagent.setTarget(0,0)
- newagent.idle = False
- agent.append(newagent)
- #in circle
- def resetAgents3():
- global agent, PPL, w, h
- r = min(w, h)*0.9/2
- incr = 2*pi/PPL
- for i in range(PPL):
- newagent = anagent(w/2 + r*cos(incr*i), h/2 + r*sin(incr*i))
- newagent.setTarget(w/2 + r*cos(incr*i + pi), h/2 + r*sin(incr*i + pi))
- agent.append(newagent)
- #from all over the place to middle
- def resetAgents4():
- global agent, PPL, w, h
- for i in range(PPL):
- newagent = anagent(uniform(-w, 2*w), uniform(-h, 2*h))
- newagent.setTarget(w/2, h/2)
- agent.append(newagent)
- #--------------------------------------------------------------------------
- resetAgents3()
- #MAIN LOOP
- while True:
- input(pygame.event.get())
- pygame.time.delay(30)
- screen.fill((0,0,50))
- if POT_DRAWFIELD:
- #calculate the danger field
- for x in range(0,w,10):
- for y in range(0,h,10):
- danger = 2*POT_STRENGTH*totalDangerAt(x,y)
- #print danger
- dng = 0
- if danger > 255:
- dng = danger - 255
- danger = 255
- if dng > 255:
- dng = 255
- pygame.draw.circle(screen, (danger,dng,0), (x,y), 7)
- #update agents
- for a in agent:
- dx = 0
- dy = 0
- if not a.idle:
- d = sqrt((a.tx - a.x)**2 + (a.ty - a.y)**2)
- if d > a.v:
- dx = a.v*(a.tx - a.x)/d
- dy = a.v*(a.ty - a.y)/d
- else:
- #a.idle = True
- a.setTarget(random()*w, random()*h)
- #if random() < 0.5:
- # a.x = -30
- # a.y = random()*h/2 + h/4
- # a.setTarget(w +10,a.y)
- #else:
- # a.x = w + 30
- # a.y = random()*h/2 + h/4
- # a.setTarget(-10,a.y)
- #now calculate force due to poptential at this point.
- #we do this by summing up all the gradients at this point
- #of all functions that each agent generates.
- gradx,grady = gradDangerAt(a.x,a.y)
- gradx = -gradx*POT_STRENGTH
- grady = -grady*POT_STRENGTH
- #print gradx,grady
- dx += gradx
- dy += grady
- #pygame.draw.circle(screen, (0, 255, 0) , (a.x + a.dx, a.y + a.dy), 10, 5)
- #pygame.draw.circle(screen, (255, 255, 255) , (a.tx, a.ty), 5, 1)
- pygame.draw.line(screen, (255,255,0), (a.x,a.y), (a.tx, a.ty))
- #pygame.draw.line(screen, (0,0,255), (a.x,a.y), (a.x+30*gradx, a.y+30*grady))
- #normalize velocity to agents speed
- lengthv = sqrt(dx*dx + dy*dy)
- dx = a.v*dx/lengthv
- dy = a.v*dy/lengthv
- pygame.draw.line(layer1, (50,50,0), (a.x,a.y), (a.x + a.dx, a.y + a.dy))
- a.x += dx
- a.y += dy
- a.dx = dx
- a.dy = dy
- #draw agent and his direction of motion
- #pygame.draw.circle(screen, (255, 255, 0) , (a.x, a.y), 17, 1)
- #ang = atan(a.dy/a.dx)
- #if a.dx < 0:
- # ang += pi
- #nf =pygame.transform.rotate(footman[int(ttt)],90 - ang*180/pi)
- #ttt+=0.025
- #if ttt > 3:
- # ttt = 0
- #screen.blit(nf, (a.x - nf.get_rect().width/2, a.y - nf.get_rect().height/2))
- pygame.draw.circle(screen, (0, 255, 255) , (a.x, a.y), 10, 1)
- pygame.draw.line(screen, (255,255,255), (a.x,a.y), (a.x+6*a.dx, a.y+6*a.dy))
- #pygame.draw.line(screen, (255,255,255), (px,py), pygame.mouse.get_pos())
- #pygame.draw.circle(screen, (0, 255, 0) , (px, py), 10)
- #screen.blit(layer1, (0,0))
- pygame.display.flip()
- #pygame.image.save(screen, "C:\pics\p" + `iter` + ".bmp")
- #iter += 1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement