import pygame as pg
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
import math
from copy import copy
import random
import matplotlib.pyplot as plt
dati = [
{"infetto":False,"velocita":10,"numero":200},
{"infetto":False,"velocita":0,"numero":10},
{"infetto":True,"velocita":10,"numero":1}
]
class Simulazione:
def __init__(s, w = 1200, h = 800, dati = []):
s.posizioni = []
s.ratio = w / h
s.w = w
s.h = h
pg.init()
schermo = (w,h)
pg.display.set_mode(schermo, DOUBLEBUF|OPENGL)
# in movimento
for d in dati:
for i in range(d["numero"]):
x = random.randint(-w/2+10,w/2-10)
y = random.randint(-h/2+10,h/2-10)
a = 2*math.pi*random.random()
s.posizioni.append(Punto(x,y,d["velocita"],a,infetto=d["infetto"]))
infezioni = []
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
quit()
glClearColor(1.0, 1.0, 1.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
tot_infetti = 0
for p in s.posizioni:
p.muovi()
s.disegnaPunto(p.x,p.y,raggio=p.raggio,colore=p.colore)
if p.infetto and not p.guarito: tot_infetti += 1
infezioni.append(tot_infetti)
s.controllaUrti()
pg.display.flip()
pg.time.wait(10)
if tot_infetti == 0:
pg.quit()
break
plt.plot(range(len(infezioni)),infezioni)
plt.title("curva contagi")
plt.xlabel("periodo")
plt.ylabel("contagi")
plt.show()
def controllaUrti(s):
for p in s.posizioni:
if copy(p) in s.posizioni:
pass
def disegnaPunto(s,x,y,lati=10,raggio=20,colore=(0.0, 0.0, 1.0)):
raggio = 2 * raggio / s.w
x = 2 * x / s.w
y = 2 * y / s.h
r,g,b = colore
glColor3f(r,g,b)
glBegin(GL_POLYGON)
for v in range(lati):
angolo = float(v) * 2.0 * math.pi / lati
glVertex2f(math.cos(angolo)*raggio + x,math.sin(angolo)*raggio*s.ratio + y)
glEnd()
class Punto:
def __init__(s,x,y,v=3,alfa=0,colore=(0.0, 0.0, 1.0),raggio=5,infetto=False):
s.x = x
s.y = y
s.v = v
s.alfa = alfa
s.id = id(s)
s.colore = colore
s.raggio = raggio
s.urtato = False
s.guarito = False
s.infetto = infetto
s.durata_infezione = 120 # cicli
def __eq__(s,o):
if math.sqrt((s.x - o.x)**2+(s.y - o.y)**2) < s.raggio * 2 and s.id != o.id:
salfa = s.alfa
oalfa = o.alfa
if (s.infetto and not s.guarito) or (o.infetto and not o.guarito):
s.infetto = o.infetto = True
if not s.urtato: s.urto(oalfa)
if not o.urtato: o.urto(salfa)
return True
else:
return False
def muovi(s):
s.urtato = False
if s.infetto: s.durata_infezione -= 1
if s.durata_infezione < 0:
s.guarito = True
s.colore=(0.0, 1.0, 0.0)
if s.infetto and not s.guarito: s.colore=(1.0, 0.0, 0.0)
dx = s.v * math.cos(s.alfa)
dy = s.v * math.sin(s.alfa)
if s.x+dx >= 600 or s.x+dx <= -600:
s.alfa = math.pi-s.alfa
dx = s.v * math.cos(s.alfa)
dy = s.v * math.sin(s.alfa)
if s.y+dy >= 400 or s.y+dy <= -400:
s.alfa = -s.alfa
dx = s.v * math.cos(s.alfa)
dy = s.v * math.sin(s.alfa)
s.x += dx
s.y += dy
if s.x >= 600 or s.x <= -600 or s.y >= 400 or s.y <= -400:
s.v = -s.v
def urto(s,theta):
s.alfa = s.alfa+theta
s.urtato = True
Simulazione(dati=dati)