hunar4321 / life_code
- воскресенье, 28 августа 2022 г. в 00:34:54
A simple program to simulate attraction/reuplsion forces between many particles
A simple program to simulate primitive Artificial Life using simple rules of attraction/repulsion among atom like particles, producing complex self-organzing life like patterns as a result. The code is less than a page (excluding GUI elements). Video tutorial and Walkthrough is available below.
You don't need to be exact with the parameters to reproduce these patterns. The best way to get interesting patterns: First try random parameter explorations, once you find an intersting pattern, try fine-tuning it gradually. To avoid being stuck at a local maximum, you can make some occasional big parameter jumps. This way interesting & different patterns keep poping up.
Download this repo. unzip the file then go to /particle_life/bin/ folder and click on particle_life.exe
Source code available in both C++ and JavaScript ( watch this YouTube video for a walkthrough tutorial: https://youtu.be/0Kx4Y9TVMGg )
If you like to contribute to the C++ program. The core algorithm is the first 100 lines of code at: "/particle_life/src/ofApp.cpp". Everything else are GUI components & rendering controls which are provided by the openFrameworks library. openFrameworks is a nice, opensource, and easy to use image rendering library. To start, download this repository first, then download openFrameworks library here (https://openframeworks.cc/). Use openFramework's projectGenerator and import /particle_life/ folder to the project. Alternatively, generate a new openFramework project and add ofxGui. Once the project files are generated replace the /src/ folder with the one provided here. You can now compile the C++ code on your machine.
<canvas id="life" width="500" height="500"></canvas>
<script>
//Hunar Ahmad @ brainxyz
m=document.getElementById("life").getContext('2d')
draw=(x,y,c,s)=>{m.fillStyle=c; m.fillRect(x, y, s, s)}
atoms=[]
atom=(x,y,c)=>{return{"x":x, "y":y, "vx":0, "vy":0, "color":c}}
random=()=>{return Math.random()*400+50}
create=(number, color)=>{
group=[]
for(let i=0; i < number; i++){
group.push(atom(random(), random(), color))
atoms.push(group[i])
}
return group
}
rule=(atoms1, atoms2, g)=>{
for(let i=0; i < atoms1.length; i++){
fx = 0
fy = 0
for(let j=0; j < atoms2.length; j++){
a = atoms1[i]
b = atoms2[j]
dx = a.x-b.x
dy = a.y-b.y
d = Math.sqrt(dx*dx + dy*dy)
if(d > 0 && d < 80){
F = g * 1/d
fx += (F * dx)
fy += (F * dy)
}
}
a.vx = (a.vx + fx)*0.5
a.vy = (a.vy + fy)*0.5
a.x += a.vx
a.y += a.vy
if(a.x <= 0 || a.x >= 500){ a.vx *=-1 }
if(a.y <= 0 || a.y >= 500){ a.vy *=-1 }
}
}
yellow = create(200, "yellow")
red = create(200, "red")
green = create(200, "green")
update=()=>{
rule(green, green, -0.32)
rule(green, red, -0.17)
rule(green, yellow, 0.34)
rule(red, red, -0.10)
rule(red, green, -0.34)
rule(yellow, yellow, 0.15)
rule(yellow, green, -0.20)
m.clearRect(0, 0, 500, 500)
draw(0, 0, "black", 500)
for(i=0; i<atoms.length; i++){
draw(atoms[i].x, atoms[i].y, atoms[i].color, 5)
}
requestAnimationFrame(update)
}
update();
</script>
Related topics: Particle Life Simulation, Primordial Soup - Evolution, Conway's game of life, Cellular automata, Self organzing patterns,
This project was inspired by: Jeffery Ventrella's Clusters http://www.ventrella.com/Clusters/ I don't have access to Ventrella's code but I guess the main difference of this project with the other particle life projects is that I didn't implement collision detection and this made simulating thousands of particles possible in real-time. Also, I added GUI controls to change the parameters in real-time this allows easy fine-tuning & exploration, hence, I was able to find some never-seen-before patterns emerge form some extremely simple models of relations. The code here is probably an order of magnitude simpler than any other Artificial Life codes out there because I started this code solely as an educational material for non-programmers and general audience to prove the point that complexity can arise from simplicity.