Alexandre B A Villares 2019-12-11 19:22:48 -02:00
rodzic aac2130b62
commit 73446c8d33
5 zmienionych plików z 380 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,195 @@
# -*- coding: utf-8 -*-
# The Boid class
from estrela import *
from cores import *
class Boid(object):
def __init__(self, x, y):
self.acceleration = PVector(0, 0)
self.angle = random(TWO_PI)
self.velocity = PVector(cos(self.angle), sin(self.angle))
self.location = PVector(x, y)
self.r = 2.0
self.maxspeed = 2
self.maxforce = 0.03
def run(self, boids, i, amp):
self.flock(boids)
self.update()
self.borders()
self.render(i, amp)
def applyForce(self, force):
# We could add mass here if we want A = F / M
self.acceleration.add(force)
# We accumulate acceleration each time based on three rules.
def flock(self, boids):
sep = self.separate(boids) # Separation
ali = self.align(boids) # Alignment
coh = self.cohesion(boids) # Cohesion
# Arbitrarily weight these forces.
sep.mult(1.5)
ali.mult(1.0)
coh.mult(1.0)
# Add the force vectors to acceleration.
self.applyForce(sep)
self.applyForce(ali)
self.applyForce(coh)
# Method to update location.
def update(self):
# Update velocity.
self.velocity.add(self.acceleration)
# Limit speed.
self.velocity.limit(self.maxspeed)
self.location.add(self.velocity)
# Reset accelertion to 0 each cycle.
self.acceleration.mult(0)
# A method that calculates and applies a steering force towards a target.
# STEER = DESIRED MINUS VELOCITY
def seek(self, target):
# A vector pointing from the location to the target.
desired = PVector.sub(target, self.location)
# Scale to maximum speed.
desired.normalize()
desired.mult(self.maxspeed)
# Above two lines of code below could be condensed with PVector setMag() method.
# Not using this method until Processing.js catches up.
# desired.setMag(maxspeed)
# Steering = Desired minus Velocity
steer = PVector.sub(desired, self.velocity)
steer.limit(self.maxforce) # Limit to maximum steering force.
return steer
def render(self, ins, amp):
# Draw a triangle rotated in the direction of velocity.
theta = self.velocity.heading2D() + radians(90)
# heading2D() above is now heading() but leaving old syntax until
# Processing.js catches up.
noFill()
stroke(255)
strokeWeight(.1)
self.x, self.y = self.location.x, self.location.y
raio1, raio2 = amp, 25
# self.tamanho = amp
colorMode(RGB)
cor_final = 255
stroke(cor_final, 150)
strokeJoin(ROUND)
if ins in (0, 1, 2, 3, 4, 5):
fill(0, 10) # preto bem fraquinho
apply_override()
estrela(self.x, self.y, 7, raio1 * .6, raio2 * .6)
if ins in (6, 7, 8, 9, 10, 11):
pushMatrix()
translate(self.x, self.y)
stroke(cor_final, min(255, 255))
apply_override()
estrela(0, 0, 4, raio1, raio2)
rotate(QUARTER_PI)
s = 4 if ins == 5 else 5
# cor2 = paleta(s, cor)
# stroke(cor2, min(255, amp))
apply_override()
estrela(0, 0, 4, raio1 * .8, raio2 * .8)
popMatrix()
if ins in (12, 13, 14, 15, 16, 17):
stroke(0)
pushMatrix()
translate(self.x, self.y)
rotate(radians(frameCount))
# stroke(cor_final, 230 - min(230, amp))
# s = 4 if ins == 5 else 5
# stroke(paleta(s, cor))
apply_override()
estrela(0, 0, 10, raio1, 50)
popMatrix()
# Wraparound
def borders(self):
if self.location.x < -self.r:
self.location.x = width + self.r
if self.location.y < -self.r:
self.location.y = height + self.r
if self.location.x > width + self.r:
self.location.x = -self.r
if self.location.y > height + self.r:
self.location.y = -self.r
# Separation
# Method checks for nearby boids and steers away.
def separate(self, boids):
desiredseparation = 50.0
steer = PVector(0, 0, 0)
count = 0
# For every boid in the system, check if it's too close.
for other in boids:
d = PVector.dist(self.location, other.location)
# If the distance is greater than 0 and less than an arbitrary
# amount (0 when you are yourself).
if 0 < d < desiredseparation:
# Calculate vector pointing away from neighbor.
diff = PVector.sub(self.location, other.location)
diff.normalize()
diff.div(d) # Weight by distance.
steer.add(diff)
count += 1 # Keep track of how many
# Average -- divide by how many
if count == 0:
return PVector(0, 0)
if count > 0:
steer.div(float(count))
# As long as the vector is greater than 0
if steer.mag() > 0:
# First two lines of code below could be condensed with PVector setMag() method.
# Implement Reynolds: Steering = Desired - Velocity
steer.normalize()
steer.mult(self.maxspeed)
steer.sub(self.velocity)
steer.limit(self.maxforce)
return steer
# Alignment
# For every nearby boid in the system, calculate the average velocity.
def align(self, boids):
neighbordist = 50
sum = PVector(0, 0)
count = 0
for other in boids:
d = PVector.dist(self.location, other.location)
if 0 < d < neighbordist:
sum.add(other.velocity)
count += 1
if count == 0:
return PVector(0, 0)
sum.div(float(count))
# First two lines of code below could be condensed with PVector setMag() method.
# Implement Reynolds: Steering = Desired - Velocity
sum.normalize()
sum.mult(self.maxspeed)
steer = PVector.sub(sum, self.velocity)
steer.limit(self.maxforce)
return steer
# Cohesion
# For the average location (i.e. center) of all nearby boids, calculate
# steering vector towards that location.
def cohesion(self, boids):
neighbordist = 50
# Start with empty vector to accumulate all locations.
sum = PVector(0, 0)
count = 0
for other in boids:
d = PVector.dist(self.location, other.location)
if 0 < d < neighbordist:
sum.add(other.location) # Add location.
count += 1
if count > 0:
sum.div(count)
return self.seek(sum) # Steer towards the location.
else:
return PVector(0, 0)

Wyświetl plik

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
# Paleta B - grupo 1
coresB = ((0, 255, 77), (109, 0, 255), (255, 0, 255),
(0, 255, 255), (255, 0, 71), (253, 255, 0))
# Paleta A - grupo 2
coresA = ((255, 82, 0), (255, 247, 0), (0, 238, 255),
(79, 0, 255), (0, 255, 249), (255, 255, 255))
# Paleta C - grupo 3
coresC = ((224, 0, 255), (255, 245, 0), (0, 255, 241),
(255, 0, 95), (255, 250, 0), (255, 255, 255))
def paleta(ins, valor):
opcoes = (coresB[:3],
coresB[3:],
coresA[:3],
coresA[3:],
coresC[:3],
coresC[3:],
)
if ins > 5:
ins = 5
a, b, c = opcoes[ins]
return triangulo(color(*a), color(*b), color(*c), int(valor))
def triangulo(a, b, c, v):
if 0 <= v < 60 or v == 360:
return a
if 60 <= v < 120:
t = map(v, 60, 120, 0, 1)
return lerpColor(a, b, t)
if 120 <= v < 180:
return b
if 180 <= v < 240:
t = map(v, 180, 240, 0, 1)
return lerpColor(b, c, t)
if 240 <= v < 300:
return c
if 300 <= v < 360:
t = map(v, 300, 360, 0, 1)
return lerpColor(c, a, t)

Wyświetl plik

@ -0,0 +1,99 @@
22# -*- coding: utf-8 -*-
from cores import *
class Estrela():
""" Classe Estrela, cor sorteada, tamanho sorteado por default """
full_screen = False
ins_override = -1
def __init__(self, x, y, tam=100):
self.x, self.y = x, y
self.tamanho = tam
self.vy = -0.5
def desenha(self, ins, cor, amp):
""" Desenha polígono em torno das coordenadas do objeto """
raio1, raio2 = amp, amp / 4
self.tamanho = amp
colorMode(RGB)
cor_final = paleta(ins, cor)
stroke(cor_final)
strokeJoin(ROUND)
if Estrela.full_screen:
translate(width / 2, height / 2)
rotate(HALF_PI)
translate(-width / 2, -height / 2)
if ins in (0, 1):
fill(0, 10) # preto bem fraquinho
apply_override()
estrela(self.x, self.y, 7, raio1 * .6, raio2 * .6)
if ins in (2, 3):
pushMatrix()
translate(self.x, self.y)
apply_override()
estrela(0, 0, 4, raio1, raio2)
rotate(QUARTER_PI)
s = 4 if ins == 5 else 5
cor2 = paleta(s, cor)
stroke(cor2, min(255, amp))
apply_override()
estrela(0, 0, 4, raio1 * .8, raio2 * .8)
popMatrix()
if ins in (4, 5):
pushMatrix()
translate(self.x, self.y)
rotate(radians(frameCount))
apply_override()
if amp > 10:
estrela(0, 0, 10, raio1, 50)
else:
estrela(0, 0, 10, raio1, 5)
popMatrix()
if Estrela.full_screen:
translate(width / 2, height / 2)
rotate(-HALF_PI)
translate(-width / 2, -height / 2)
def anda(self, tom=None):
""" atualiza a posição do objeto e devolve do lado oposto se sair """
# if Estrela.full_screen:
# w, h = height, width
# else:
w, h = width, height
if tom is not None:
self.x = map(tom, -24, 24, self.tamanho * 2, w - self.tamanho * 2)
# self.x += self.vx
self.vy = -.35 * 40 / (tom + 40)
self.y += self.vy
tam = self.tamanho
if self.x > w + tam:
self.x = -tam
if self.y > h + tam:
self.y = -tam
if self.x < -tam:
self.x = w + tam
if self.y < -tam:
self.y = h + tam
def apply_override():
if Estrela.ins_override == 6:
stroke(255)
noFill()
strokeWeight(1)
def estrela(cx, cy, pontas, raio1, raio2):
pontos = pontas * 2
parte = 360. / pontos
beginShape() # comece a forma!
for p in range(pontos): # para cada p
angulo = radians(p * parte) # calcula angulo
if p % 2 == 0: # se for par
raio = raio1
else: # senão, se for impar
raio = raio2
x = cx + raio * sin(angulo)
y = cy + raio * cos(angulo)
vertex(x, y) # vertex é um ponto
endShape(CLOSE) # termina forma

Wyświetl plik

@ -0,0 +1,13 @@
# The Flock (a list of Boid objects)
class Flock(object):
def __init__(self):
self.boids = [] # Initialize a list for all the boids.
def run(self, amp):
for i, b in enumerate(self.boids):
# Pass the entire list of boids to each boid individually.
b.run(self.boids, i, amp)
def addBoid(self, b):
self.boids.append(b)

Wyświetl plik

@ -0,0 +1,30 @@
add_library('sound') # aviso de que vai usar o microfone
from estrela import Estrela
from boid import Boid
from flock import Flock
def setup():
global dados, instrumentos, oscP5, novos_dados, estrelas
global input, loudness
global flock
flock = Flock()
size(800, 600)
# fullScreen() # testar se 1 vai para segundo monitor
background(0)
# Burocracia para receber o som e analisar o volume
source = AudioIn(this, 0)
source.start()
loudness = Amplitude(this)
loudness.input(source)
for i in range(18):
flock.addBoid(Boid(width / 2, height / 2))
def draw():
fill(0, 10)
noStroke()
rect(0, 0, width, height)
volume = loudness.analyze()
tamanho = int(map(volume, 0, 0.5, 30, 350))
# amp = 200 * noise(frameCount * .02)
flock.run(tamanho)