Skip to content

Commit

Permalink
ok
Browse files Browse the repository at this point in the history
  • Loading branch information
jcponce committed Jul 25, 2024
1 parent 29c2519 commit 3190c29
Show file tree
Hide file tree
Showing 5 changed files with 360 additions and 0 deletions.
17 changes: 17 additions & 0 deletions sketches/lenia-particle/b-w.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lenia Particle - B/W</title>

<link rel="stylesheet" type="text/css" href="style.css">

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.4/p5.min.js"></script>
</head>
<body>


<script src="sketch-b-w.js"></script>
</body>
</html>
17 changes: 17 additions & 0 deletions sketches/lenia-particle/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lenia Particle - B/W</title>

<link rel="stylesheet" type="text/css" href="style.css">

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.4/p5.min.js"></script>
</head>
<body>


<script src="sketch.js"></script>
</body>
</html>
157 changes: 157 additions & 0 deletions sketches/lenia-particle/sketch-b-w.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
Based upon this Tutorial by Alexander Mordvintsev:
Particle Lenia from scratch
https://observablehq.com/@znah/particle-lenia-from-scratch
The simulation shows Particle Lenia: the system of
particles that move to minimize local energy of their
interaction, leading to the formation of complex and
diverse structures.
https://arxiv.org/pdf/2305.16706
This version by Juan Carlos Ponce Campuzano
12/Jul/2024
https://www.patreon.com/jcponce
*/

let params = {
mu_k: 4.0, sigma_k: 1.0, w_k: 0.022,
mu_g: 0.6, sigma_g: 0.15, c_rep: 1.0,
dt: 0.1
};

let point_n = 200;
let points;
let fields;
let steps_per_frame; // Adjust this based on desired speed
let randomCol;

function setup() {
createCanvas(windowWidth, windowHeight);
points = init(new Float32Array(point_n * 2));
fields = {
R_val: new Float32Array(point_n),
U_val: new Float32Array(point_n),
R_grad: new Float32Array(point_n * 2),
U_grad: new Float32Array(point_n * 2)
};

colorMode(RGB, 200, 200, 200, 200);
fill(90)
stroke(255);
strokeWeight(0.05);

steps_per_frame = int(random(3, 12));

randomCol = random();

//console.log(randomCol);
}

function draw() {
for (let i = 0; i < steps_per_frame; ++i) step();
background(0, 30);
translate(width / 2, height / 2);
scale(width / 45.0);


for (let i = 0; i < point_n; ++i) {
let x = points[i * 2], y = points[i * 2 + 1];
let r = params.c_rep / (fields.R_val[i] * 5.0);

ellipse(x, y, r * 2, r * 2);
}
}

function init(points) {
for (let i = 0; i < point_n; ++i) {
points[i * 2] = (Math.random() - 0.5) * 12;
points[i * 2 + 1] = (Math.random() - 0.5) * 12;
}
return points;
}

function add_xy(a, i, x, y, c) {
a[i * 2] += x * c;
a[i * 2 + 1] += y * c;
}

function compute_fields() {
const { R_val, U_val, R_grad, U_grad } = fields;
const { c_rep, mu_k, sigma_k, w_k } = params;
R_val.fill(repulsion_f(0.0, c_rep)[0]);
U_val.fill(peak_f(0.0, mu_k, sigma_k, w_k)[0]);
R_grad.fill(0);
U_grad.fill(0);

for (let i = 0; i < point_n - 1; ++i) {
for (let j = i + 1; j < point_n; ++j) {
let rx = points[i * 2] - points[j * 2];
let ry = points[i * 2 + 1] - points[j * 2 + 1];
const r = Math.sqrt(rx * rx + ry * ry) + 1e-20;
rx /= r;
ry /= r;

if (r < 1.0) {
const [R, dR] = repulsion_f(r, c_rep);
add_xy(R_grad, i, rx, ry, dR);
add_xy(R_grad, j, rx, ry, -dR);
R_val[i] += R;
R_val[j] += R;
}
const [K, dK] = peak_f(r, mu_k, sigma_k, w_k);
add_xy(U_grad, i, rx, ry, dK);
add_xy(U_grad, j, rx, ry, -dK);
U_val[i] += K;
U_val[j] += K;
}
}
}

function repulsion_f(x, c_rep) {
const t = Math.max(1.0 - x, 0.0);
return [0.5 * c_rep * t * t, -c_rep * t];
}

function fast_exp(x) {
let t = 1.0 + x / 32.0;
t *= t;
t *= t;
t *= t;
t *= t;
t *= t;
return t;
}

function peak_f(x, mu, sigma, w = 1.0) {
const t = (x - mu) / sigma;
const y = w / fast_exp(t * t);
return [y, -2.0 * t * y / sigma];
}

function step() {
const { R_val, U_val, R_grad, U_grad } = fields;
const { mu_g, sigma_g, dt } = params;
compute_fields();
let total_E = 0.0;
for (let i = 0; i < point_n; ++i) {
const [G, dG] = peak_f(U_val[i], mu_g, sigma_g);
const vx = dG * U_grad[i * 2] - R_grad[i * 2];
const vy = dG * U_grad[i * 2 + 1] - R_grad[i * 2 + 1];
add_xy(points, i, vx, vy, dt);
total_E += R_val[i] - G;
}
return total_E / point_n;
}

function mousePressed() {
params.mu_k = random(1.0, 5.0);
params.sigma_k = random(0.1, 2.0);
params.w_k = random(0.01, 0.07);
params.mu_g = random(0.1, 1.0);
params.sigma_g = random(0.05, 0.3);
params.c_rep = random(0.1, 2.0);
// Debugg
//console.log(params);
}
163 changes: 163 additions & 0 deletions sketches/lenia-particle/sketch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
Based upon this Tutorial by Alexander Mordvintsev:
Particle Lenia from scratch
https://observablehq.com/@znah/particle-lenia-from-scratch
The simulation shows Particle Lenia: the system of
particles that move to minimize local energy of their
interaction, leading to the formation of complex and
diverse structures.
https://arxiv.org/pdf/2305.16706
This version by Juan Carlos Ponce Campuzano
12/Jul/2024
https://www.patreon.com/jcponce
*/

let params = {
mu_k: 4.0, sigma_k: 1.0, w_k: 0.022,
mu_g: 0.6, sigma_g: 0.15, c_rep: 1.0,
dt: 0.1
};

let point_n = 200;
let points;
let fields;
let steps_per_frame; // Adjust this based on desired speed
let randomCol;

function setup() {
createCanvas(windowWidth, windowHeight);
points = init(new Float32Array(point_n * 2));
fields = {
R_val: new Float32Array(point_n),
U_val: new Float32Array(point_n),
R_grad: new Float32Array(point_n * 2),
U_grad: new Float32Array(point_n * 2)
};

colorMode(RGB, 200, 200, 200, 200);
noStroke();

steps_per_frame = int(random(3, 12));

randomCol = random();

//console.log(randomCol);
}

function draw() {
for (let i = 0; i < steps_per_frame; ++i) step();
background(0, 30);
translate(width / 2, height / 2);
scale(width / 45.0);
strokeWeight(0.1);

for (let i = 0; i < point_n; ++i) {
let x = points[i * 2], y = points[i * 2 + 1];
let r = params.c_rep / (fields.R_val[i] * 5.0);

if(randomCol < 0.3){
fill((i)/point_n* 200, 70, 100);
} else if(0.3 <= randomCol && randomCol < 0.6) {
fill(90, 80, (i)/point_n* 200);
} else {
fill(20, (i)/point_n* 200, 180);
}

ellipse(x, y, r * 2, r * 2);
}
}

function init(points) {
for (let i = 0; i < point_n; ++i) {
points[i * 2] = (Math.random() - 0.5) * 12;
points[i * 2 + 1] = (Math.random() - 0.5) * 12;
}
return points;
}

function add_xy(a, i, x, y, c) {
a[i * 2] += x * c;
a[i * 2 + 1] += y * c;
}

function compute_fields() {
const { R_val, U_val, R_grad, U_grad } = fields;
const { c_rep, mu_k, sigma_k, w_k } = params;
R_val.fill(repulsion_f(0.0, c_rep)[0]);
U_val.fill(peak_f(0.0, mu_k, sigma_k, w_k)[0]);
R_grad.fill(0);
U_grad.fill(0);

for (let i = 0; i < point_n - 1; ++i) {
for (let j = i + 1; j < point_n; ++j) {
let rx = points[i * 2] - points[j * 2];
let ry = points[i * 2 + 1] - points[j * 2 + 1];
const r = Math.sqrt(rx * rx + ry * ry) + 1e-20;
rx /= r;
ry /= r;

if (r < 1.0) {
const [R, dR] = repulsion_f(r, c_rep);
add_xy(R_grad, i, rx, ry, dR);
add_xy(R_grad, j, rx, ry, -dR);
R_val[i] += R;
R_val[j] += R;
}
const [K, dK] = peak_f(r, mu_k, sigma_k, w_k);
add_xy(U_grad, i, rx, ry, dK);
add_xy(U_grad, j, rx, ry, -dK);
U_val[i] += K;
U_val[j] += K;
}
}
}

function repulsion_f(x, c_rep) {
const t = Math.max(1.0 - x, 0.0);
return [0.5 * c_rep * t * t, -c_rep * t];
}

function fast_exp(x) {
let t = 1.0 + x / 32.0;
t *= t;
t *= t;
t *= t;
t *= t;
t *= t;
return t;
}

function peak_f(x, mu, sigma, w = 1.0) {
const t = (x - mu) / sigma;
const y = w / fast_exp(t * t);
return [y, -2.0 * t * y / sigma];
}

function step() {
const { R_val, U_val, R_grad, U_grad } = fields;
const { mu_g, sigma_g, dt } = params;
compute_fields();
let total_E = 0.0;
for (let i = 0; i < point_n; ++i) {
const [G, dG] = peak_f(U_val[i], mu_g, sigma_g);
const vx = dG * U_grad[i * 2] - R_grad[i * 2];
const vy = dG * U_grad[i * 2 + 1] - R_grad[i * 2 + 1];
add_xy(points, i, vx, vy, dt);
total_E += R_val[i] - G;
}
return total_E / point_n;
}

function mousePressed() {
params.mu_k = random(1.0, 5.0);
params.sigma_k = random(0.1, 2.0);
params.w_k = random(0.01, 0.07);
params.mu_g = random(0.1, 1.0);
params.sigma_g = random(0.05, 0.3);
params.c_rep = random(0.1, 2.0);
// Debugg
//console.log(params);
}
6 changes: 6 additions & 0 deletions sketches/lenia-particle/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
html,
body {
margin: 0;
height: 100%;
overflow: hidden;
}

0 comments on commit 3190c29

Please sign in to comment.