owned this note
owned this note
Published
Linked with GitHub
## Noite de Processing - 28 de fevereiro de 2023
# Particle Life
## Versão 0
```processing=
// John na Noite de Processing
int N = 800;
int especies_N = 4;
float color_step = 256.0 / especies_N;
int right, left, top, bottom;
float[][] leis;
Ball[] balls;
void setup(){
size( 800, 650 );//displayWidth
right = width +10;
left = -10;
top = -10;
bottom = height +10;
colorMode(HSB);
balls = new Ball[N];
for(int i = 0; i < N; i++ ) balls[i] = new Ball();
leis = new float[especies_N][especies_N];
for(int j = 0; j < especies_N; j++ ){
for(int i = 0; i < especies_N; i++ ){
leis[i][j] = random(-3, 3);
print( leis[i][j] + ", " );
}
println(".");
}
noSmooth();
}
void draw(){
background(0);
noStroke();
for(int i = 0; i < N; i++ ){
balls[i].tick();
balls[i].display();
for(int j = i; j < N; j++ ){
PVector forca = PVector.sub(balls[i].pos, balls[j].pos);
float dsq = forca.magSq();
if( dsq < 10000 ){
boolean collision = false;
PVector fA = forca.get();
float mag = map( dsq, 10000, 0, 0, 0.001 );
if( dsq < 10 ){
float coll = map( dsq, 10, 0, 0, 1 );
fA.setMag( coll );
collision = true;
}
else{
fA.setMag( leis[ balls[i].especie ][ balls[j].especie ] * mag );
}
balls[i].vel.add( fA );
PVector fB;
if( collision ){
fB = fA.get().mult(-1);
}
else{
fB = forca.get().mult(-1);
fB.setMag( leis[ balls[j].especie ][ balls[i].especie ] * mag );
}
balls[j].vel.add( fB );
}
}
}
}
class Ball{
PVector pos, vel;
int especie;
Ball(){
pos = new PVector(random(width), random(height));
vel = new PVector(random(-1,1),random(-1,1));
especie = int(random(especies_N));
}
void tick(){
pos.add( vel );
vel.mult(0.98);//inercia
if( pos.x > right ) pos.x = left;
if( pos.x < left ) pos.x = right;
if( pos.y > bottom ) pos.y = top;
if( pos.y < top ) pos.y = bottom;
}
void display(){
fill( color(especie*color_step, 255, 255) );
ellipse(pos.x, pos.y, 6, 6);
}
}
```
## Versão 1 (outro esquema de loop)
```processing=
//V2
int N = 800;
int especies_N = 4;
float color_step = 256.0 / especies_N;
int right, left, top, bottom;
float[][] leis;
Ball[] balls;
void setup(){
size( 800, 650 );//displayWidth
right = width +10;
left = -10;
top = -10;
bottom = height +10;
colorMode(HSB);
balls = new Ball[N];
for(int i = 0; i < N; i++ ) balls[i] = new Ball();
leis = new float[especies_N][especies_N];
for(int j = 0; j < especies_N; j++ ){
for(int i = 0; i < especies_N; i++ ){
leis[i][j] = random(-3, 3);
print( leis[i][j] + ", " );
}
println(".");
}
noSmooth();
}
void draw(){
background(0);
noStroke();
for(int i = 0; i < N; i++ ){
balls[i].tick();
balls[i].display();
for(int j = 0; j < N; j++ ){
PVector forca = PVector.sub(balls[i].pos, balls[j].pos);
float dsq = forca.magSq();
if( dsq < 10000 ){
float mag = map( dsq, 10000, 0, 0, 0.001 );
if( dsq < 10 ){
mag = map( dsq, 10, 0, 0, 1 );
forca.setMag( mag );
}
else{
forca.setMag( leis[ balls[i].especie ][ balls[j].especie ] * mag );
}
balls[i].vel.add( forca );
}
}
}
//println(frameRate);
}
class Ball{
PVector pos, vel;
int especie;
Ball(){
pos = new PVector(random(width), random(height));
vel = new PVector(random(-1,1),random(-1,1));
especie = int(random(especies_N));
}
void tick(){
pos.add( vel );
vel.mult(0.98);//inercia
if( pos.x > right ) pos.x = left;
if( pos.x < left ) pos.x = right;
if( pos.y > bottom ) pos.y = top;
if( pos.y < top ) pos.y = bottom;
}
void display(){
fill( color(especie*color_step, 255, 255) );
ellipse(pos.x, pos.y, 6, 6);
}
}
```
## Versão JavaScript do prof. Claudio Esperança
https://observablehq.com/@esperanc/particle-life
## Uma versão Python (horrivelmente lerda)
```python=
# usando py5 (py5coding.org) module mode agora
import py5
N = 100
especies_n = 4
color_step = 256.0 / especies_n
leis = [[0] * especies_n for _ in range(especies_n)]
balls = []
def setup():
global right, left, top, bottom
py5.size(800, 650) # displayWidth
py5.no_smooth()
right = py5.width + 10
left = -10
top = -10
bottom = py5.height + 10
py5.color_mode(py5.HSB)
balls[:] = [Ball() for _ in range(N)]
for j in range(especies_n):
for i in range(especies_n):
leis[i][j] = py5.random(-3, 3)
print(leis)
def draw():
py5.background(0)
py5.no_stroke()
for ball_i in balls:
ball_i.tick()
ball_i.display()
for ball_j in balls:
forca = ball_i.pos - ball_j.pos
dsq = forca.mag_sq
if ball_i is not ball_j and dsq < 10000:
if(dsq < 10):
m = py5.remap(dsq, 10, 0, 0, 1)
if m < 0:
forca *= -1
m = -m
forca.mag = m
else:
m = py5.remap(dsq, 10000, 0, 0, 0.001)
lm = leis[ball_i.especie][ball_j.especie] * m
if lm < 0:
forca *= -1
lm = -lm
forca.mag = lm
ball_i.vel += forca
py5.window_title(f'{py5.get_frame_rate():.1f}')
class Ball:
def __init__(self):
self.pos = py5.Py5Vector(py5.random(py5.width), py5.random(py5.height))
self.vel = py5.Py5Vector(py5.random(-1, 1), py5.random(-1, 1))
self.especie = int(py5.random(especies_n))
def tick(self):
self.pos += self.vel
self.vel *= 0.98
if self.pos.x > right:
self.pos.x = left
if self.pos.x < left:
self.pos.x = right
if self.pos.y > bottom:
self.pos.y = top
if self.pos.y < top:
self.pos.y = bottom
def display(self):
py5.fill(self.especie * color_step, 255, 255)
py5.ellipse(self.pos.x, self.pos.y, 6, 6)
py5.run_sketch()
```