Skip to content
Snippets Groups Projects
Commit 463b1859 authored by phwitte's avatar phwitte
Browse files

prey, food und bunt

parent 25aa0f70
No related branches found
No related tags found
No related merge requests found
from graphics import *
import time
import random
import math
class Agent:
def __init__(self, point, window ):
self.color = color_rgb(0,0,0)
self.point = point
self.window = window
self.Velocity_x = 1
self.Velocity_y = 1
self.tempV = [0,0]
self.line = Line(self.point, Point(self.point.getX() + self.Velocity_x, self.point.getY()+self.Velocity_y))
#evolvable
self.speed = 4
self.zor_r = 10#fix
self.zoo_r = 20
self.zoa_r = 200
self.attCircle = Circle(self.point, self.zoa_r)
self.blind_angle = 80
self.turn_angle = 50
self.food_pref = 5
self.anti_pred = 0
self.foodlevel = 0
self.noise = 2
def drawLine(self):
self.line.undraw()
self.line = Line(self.point, Point(self.point.getX() + self.Velocity_x, self.point.getY()+self.Velocity_y))
self.line.setArrow("last")
self.line.setFill(self.color)
self.line.draw(self.window)
"""
self.attCircle.undraw()
self.attCircle = Circle(self.point, self.zoa_r)
self.attCircle.setOutline("black")
self.attCircle.draw(self.window)
"""
class Food:
def __init__(self, Point):
self.point = Point
# help functions
# Distance function betwen points xi, yi and xii,yii
def distance(xi,xii,yi,yii):
sq1 = (xi-xii)*(xi-xii)
sq2 = (yi-yii)*(yi-yii)
return math.sqrt(sq1 + sq2)
def absvec(a, b):
m = math.sqrt(a*a + b*b)
if m == 0: m = 0.001
return m
def calc_angle(x1, y1, x2, y2):
skalar = x1*x2 + y1*y2
abs1 = absvec(x1, y1)
abs2 = absvec(x2, y2)
erg = skalar/(abs1* abs2)
if erg > 1:
#print erg
erg=1
elif erg < -1:
#print erg
erg=-1
return math.degrees(math.acos(erg))
#-----couzin movement--------------------
# returns three lists, one for each zone,
# contaning all other agent in the zone.
# ignores al egents ind the angle behind the current agent defined by blind.
def neigbour_in_zones(a, aas, zor_r, zoo_r, zoa_r, blind):
zor = []
zoo = []
zoa = []
for agent in aas:
disVecX = agent.point.getX() - a.point.getX()
disVecY = agent.point.getY() - a.point.getY()
alpha = calc_angle(a.Velocity_x,a.Velocity_y, disVecX, disVecY)
if (a == agent):
True
elif alpha < 180 - blind and alpha > 180 + blind:
True
else:
dis = absvec(agent.point.getX() - a.point.getX() , agent.point.getY() - a.point.getY() )
if dis <= zor_r:
zor.append(agent)
elif dis <= zoo_r:
zoo.append(agent)
elif dis <= zoa_r:
zoa.append(agent)
#print len(zoo)+len(zor)+len(zoa)
return [zor, zoo, zoa]
#update Velocity a la couzin
def updateV_couzin(a, matrix):
dx=0
dy=0
#zor
if matrix[0] != []:
for agent in matrix[0]:
disX = agent.point.getX() - a.point.getX()
disY = agent.point.getY() - a.point.getY()
rX = disX/absvec(disX, disY)
rY = disY/absvec(disX, disY)
dx += rX / absvec(rX, rY)
dy += rY / absvec(rX, rY)
dx = -dx
dy = -dy
# zoo ; zoa leer
elif matrix[1] != [] and matrix[2] == []:
for agent in matrix[1]:
dx += agent.Velocity_x / absvec(agent.Velocity_x, agent.Velocity_y)
dy += agent.Velocity_y / absvec(agent.Velocity_x, agent.Velocity_y)
dx += a.Velocity_x / absvec(a.Velocity_x, a.Velocity_y)
dy += a.Velocity_y / absvec(a.Velocity_x, a.Velocity_y)
# zoo leer ; zoa
elif matrix[1] == [] and matrix[2] != []:
for agent in matrix[2]:
disX = agent.point.getX() - a.point.getX()
disY = agent.point.getY() - a.point.getY()
rX = disX/absvec(disX, disY)
rY = disY/absvec(disX, disY)
dx += rX / absvec(rX, rY)
dy += rY / absvec(rX, rY)
# zoo ; zoa
elif matrix[1] != [] and matrix[2] != []:
for agent in matrix[1]:
dx += agent.Velocity_x / absvec(agent.Velocity_x, agent.Velocity_y)
dy += agent.Velocity_y / absvec(agent.Velocity_x, agent.Velocity_y)
dx += a.Velocity_x / absvec(a.Velocity_x, a.Velocity_y)
dy += a.Velocity_y / absvec(a.Velocity_x, a.Velocity_y)
for agent in matrix[2]:
disX = agent.point.getX() - a.point.getX()
disY = agent.point.getY() - a.point.getY()
rX = disX/absvec(disX, disY)
rY = disY/absvec(disX, disY)
dx += rX / absvec(rX, rY)
dy += rY / absvec(rX, rY)
dx = 0.5*dx
dy = 0.5*dy
# all zones empty
else:
dx = a.Velocity_x
dy = a.Velocity_y
# randomness factor / error
dx += random.uniform(-a.noise/2, a.noise/2)
dy += random.uniform(-a.noise/2, a.noise/2)
return [dx, dy]
def check_food(agent, foods):
dX=0
dY=0
if foods == []:
return [dX,dY]
nf = nearest_neighbour(agent, foods)
dis = distance(agent.point.getX(), nf.point.getX(), agent.point.getY(), nf.point.getY())
if dis<=agent.zor_r:
nf.point.undraw()
foods.remove(nf)
agent.foodlevel += 1
elif dis<=agent.zoa_r:
disX = nf.point.getX() - agent.point.getX()
disY = nf.point.getY() - agent.point.getY()
rX = disX/absvec(disX, disY)
rY = disY/absvec(disX, disY)
dX = rX / absvec(rX, rY)
dY = rY / absvec(rX, rY)
return [dX, dY]
def updateV_final(agent, matrix,foods):
vc = updateV_couzin(agent, matrix)
vf = check_food(agent, foods)
vvX = vc[0] + agent.food_pref* vf[0]
vvY = vc[1] + agent.food_pref* vf[1]
return [vvX, vvY]
def nearest_neighbour(a,aas):
minDis = float('inf')
nn = None
for b in aas:
if (a == b):
True
elif (nn == None):
nn = b
else:
dis = distance(a.point.getX(),b.point.getX(), a.point.getY(), b.point.getY())
if(dis < minDis):
minDis = dis
nn = b
return nn
# check for window boundaries
def checkBoundary(agent, winWidth, winHeight):
point = agent.point
point.move(agent.Velocity_x,agent.Velocity_y)
x = point.getX()
y = point.getY()
if x > 0 and y < winHeight and x < winWidth and y > 0:
agent.point = point
elif x <= 0 or x >= winWidth:
agent.Velocity_x = agent.Velocity_x * (-1)
agent.point.move(agent.Velocity_x,agent.Velocity_y)
elif y <= 0 or y >= winHeight:
agent.Velocity_y = agent.Velocity_y * (-1)
agent.point.move(agent.Velocity_x,agent.Velocity_y)
return agent
def update_couzin(agents,foods,winWidth, winHeight, window):
# Velocity update
for agent in agents:
neigh_matrix = neigbour_in_zones(agent, agents, agent.zor_r, agent.zoo_r, agent.zoa_r, agent.blind_angle,)
agent.tempV = updateV_final(agent, neigh_matrix, foods)
#print "blind: " + str(agent.blind_angle)
#print "turn: " + str(agent.turn_angle)
#print "zoa: " + str(agent.zoa_r)
# move, draw
for agent in agents:
# alpha = calc_angle(agent[1], agent[2],agent.tempV[0],agent[4][1])
# test if in ragne of agent.turn_angle, if not rotate angle by maxTurn in
# direction of new direction
radTurn = math.radians(agent.turn_angle)
negRadTurn = math.radians(360-agent.turn_angle)
angle_old = math.atan2(agent.Velocity_y, agent.Velocity_x)
angle_new = math.atan2(agent.tempV[1], agent.tempV[0])
alpha = math.degrees(angle_old - angle_new)
if abs(alpha) > 180:
if alpha < 0:
alpha += 360
else:
alpha -= 360
if abs(alpha)<agent.turn_angle:
agent.Velocity_x = agent.tempV[0]
agent.Velocity_y = agent.tempV[1]
elif alpha < 0:
agent.Velocity_x = agent.Velocity_x * math.cos(radTurn) - agent.Velocity_y * math.sin(radTurn)
agent.Velocity_y = agent.Velocity_x * math.sin(radTurn) + agent.Velocity_y * math.cos(radTurn)
else:
agent.Velocity_x = agent.Velocity_x * math.cos(negRadTurn) - agent.Velocity_y * math.sin(negRadTurn)
agent.Velocity_y = agent.Velocity_x * math.sin(negRadTurn) + agent.Velocity_y * math.cos(negRadTurn)
# normalise diection vector to 1, and multiply by constant speed
agent.Velocity_x = agent.Velocity_x/absvec(agent.Velocity_x, agent.Velocity_y) * agent.speed
agent.Velocity_y = agent.Velocity_y/absvec(agent.Velocity_x, agent.Velocity_y) * agent.speed
agent = checkBoundary(agent, winWidth, winHeight)
# draw arrow
agent.drawLine()
return agents
def simulate():
winWidth = 500
winHeight = 500
window = GraphWin("Window", winWidth, winHeight)
maxTime = 10000
agentNum = 80
foodCluster = 10
clusterSize = 8
clusterradius = 20
isFood = True
t = 0.1
rr = 5
As = 5000 * (rr**2)
Am = 50 *(rr**2) * t
# zones for couzin, vicsek
# radii of zones
# swarm: 10, 20, 200
# torus: 5, 60, 200
# dynamic parallel group: 5, 100, 200
# highly parallel group: 5, 180, 200
agents = []
foods = []
for i in range (agentNum):
#p = Point(random.uniform(0,winWidth), random.uniform(0,winHeight))
agent = Agent(Point(random.uniform(0,winWidth), random.uniform(0,winHeight)) , window)
agent.Velocity_x = random.uniform(-1, 1)
agent.Velocity_y = random.uniform(-1, 1)
agent.zor_r = rr
agent.zoa_r = random.uniform( math.sqrt(As/(2*math.pi)), 2*math.sqrt(As/(2*math.pi)) )
agent.zoo_r = random.uniform(rr, agent.zoa_r)
agent.speed = random.uniform(1, 2)
agent.blind_angle = (360 - math.degrees(As/(agent.zoa_r**2)) ) / 2
agent.turn_angle = math.degrees(Am/(2*(agent.speed**2)))
agent.food_pref = random.uniform(0,1)
agent.anti_pred = random.uniform(0,1)
agent.noise = random.uniform(0,1)
r = random.randrange(256)
g = random.randrange(256)
b = random.randrange(256)
agent.color = color_rgb(r,g,b)
agents.append(agent)
print "turn: "+str(agent.turn_angle)
print "blind: "+str(agent.blind_angle)
for i in range(maxTime):
#print i
if i == maxTime * 0.01 and isFood:
for j in range (foodCluster):
x = random.uniform(clusterradius, winWidth-clusterradius)
y = random.uniform(clusterradius, winHeight- clusterradius)
for k in range (clusterSize):
xk = random.uniform(x - clusterradius, x + clusterradius)
yk = random.uniform(y - clusterradius, y + clusterradius)
f = Food(Point(xk, yk))
f.point.setFill("blue")
f.point.draw(window)
foods.append(f)
agents = update_couzin(agents, foods,winWidth, winHeight, window)
time.sleep(0.01*t)
window.getMouse()
window.close()
simulate()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment