Skip to content

Commit

Permalink
primordial
Browse files Browse the repository at this point in the history
  • Loading branch information
lenincompres committed May 24, 2024
1 parent c541b89 commit d4590af
Show file tree
Hide file tree
Showing 21 changed files with 139,266 additions and 0 deletions.
Binary file modified .DS_Store
Binary file not shown.
Binary file added noc/.DS_Store
Binary file not shown.
70 changes: 70 additions & 0 deletions noc/primordial/Grid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
export class Grid {
constructor(resolution) {
if (resolution > width || resolution > height) console.error('The resolution is too high.');
this.resolution = resolution;
this.arr = new Array(this.colN);
for (let i = 0; i < this.colN; i++) {
this.arr[i] = (new Array(this.rowN)).fill([]);
}
this.clear();
}

get colN() {
return floor(width / this.resolution);
}

get rowN() {
return floor(height / this.resolution);
}

clear() {
this.arr.forEach(cols => cols.forEach(rows => rows = []));
}

iterate(func = (m, i, j) => null) {
for (let i = 0; i < this.colN; i++) {
for (let j = 0; j < this.rowN; j++) {
func(this.arr[i][j], i, j);
}
}
}

get(i, j) {
if (i < 0 || i >= this.colN) return [];
if (j < 0 || j >= this.rowN) return [];
return this.arr[i][j];
}

assign(movers) {
movers.forEach(mover => {
let col = floor(mover.x / this.resolution);
let row = floor(mover.y / this.resolution);
col = constrain(col, 0, this.colN - 1);
row = constrain(row, 0, this.rowN - 1);
this.arr[col][row].push(mover);
});
}

setNeighbors() {
this.iterate((movers, i, j) => {
let neighbors = [...movers];
neighbors.push(...this.get(i - 1, j));
neighbors.push(...this.get(i, j - 1));
neighbors.push(...this.get(i - 1, j - 1));
neighbors.push(...this.get(i + 1, j));
neighbors.push(...this.get(i, j + 1));
neighbors.push(...this.get(i + 1, j + 1));
neighbors.push(...this.get(i - 1, j + 1));
neighbors.push(...this.get(i + 1, j - 1));
movers.forEach(b => b.neighbors = neighbors);
});
}

reset(movers) {
this.clear();
this.assign(movers);
this.setNeighbors();
}
}

export default Grid;
118 changes: 118 additions & 0 deletions noc/primordial/Mass.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
class Mass {
constructor(m = 1000, x, y, world = {}) {
this.mass = m;
this.hue = random(100);

this.x = x !== undefined ? x : random(width);
this.y = y !== undefined ? y : random(height);
this.velocity = createVector().rotate(random(TWO_PI));
this.force = createVector();
this.angSpeed = 0;

this.world = world;
if (!world.friction) world.friction = 0.04;
if (!world.frameRate) world.frameRate = frameRate();
if (!world.masses) world.masses = [];
this.world.masses.push(this);

this.actions = [];
this.updates = [];
this.addTrait("show", "move");
}

get radius() {
return sqrt(this.mass / PI);
}

get diam() {
return 2 * this.radius;
}

get color() {
this.hue = (this.hue + 100) % 100; // wraps around
let c = color(this.hue, this.s ? this.s : 100, this.l ? this.l : 60);
return c;
}

get position() {
return createVector(this.x, this.y);
}

set position(pos) {
this.x = pos.x;
this.y = pos.y;
}

run() {
if (this.mass <= 0) return;
this.actions.forEach(action => action(this));
return this;
}

update() {
if (this.mass <= 0) return;
this.updates.forEach(uptade => uptade(this));
if (this.mass > 0) return this;
this.world.masses = this.world.masses.filter(m => m !== this);
}

addTrait(...traits) {
traits.forEach(trait => {
if (!Mass.TRAITS[trait]) return;
if (!this.traits) this.traits = [];
if (!this.traits.includes(trait)) {
this.traits.push(trait);
this.traits.sort((a, b) => (b.sort ? b.sort : 0) - (a.sort ? a.sort : 0)).reverse();
trait = Mass.TRAITS[trait];
if (trait.setup) trait.setup(this);
let args = trait.args ? trait.args : trait.arg ? [trait.arg] : [];
if (trait.update) this.updates.push(() => trait.update(this, ...args));
if (trait.action) this.actions.push(() => trait.action(this, ...args));
}
});
}

static TRAITS = {
show: {
action: me => {
push();
stroke(me.color);
strokeWeight(me.diam);
noFill();
translate(me.x, me.y);
point(0, 0);
pop();
}
},
move: {
update: me => {
let distance = me.force.copy().mult(1 / me.mass); // d = f/m
let a = me.velocity.heading();
me.velocity.add(distance).limit(me.diam);
me.position = me.position.add(me.velocity);
me.velocity.mult(1 - me.world.friction);
me.force.mult(0);
a -= me.velocity.heading();
let burn = sqrt(me.mass * distance.mag() * me.world.friction);
burn += sqrt(PI * abs(a) * me.mass * me.world.friction);
burn = max(0.3 * burn, 4 / me.world.frameRate);
me.mass -= burn;
}
},
/*
moveWithoutVelocity: {
update: me => {
let distance = me.force.copy().mult(me.radius / (PI * me.mass)).limit(this.diam); // d = f/m
me.position = me.position.add(distance);
me.force.mult(0.94);
if(me.force.mag() < 1) me.force.mult(0);
let burn = 1 + sqrt(me.mass * distance.mag() * me.world.friction);
me.mass -= burn;
if (me.mass > 0) return me;
me.world.masses = me.world.masses.filter(m => m !== me);
}
},*/
}
}

export default Mass;
73 changes: 73 additions & 0 deletions noc/primordial/dna.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
class DNA {

constructor(subject, rna = {}, bases = {}) {
subject.dna = this;
this.subject = subject;
this.rna = rna;
this.bases = bases;
this.read();
Object.entries(rna).forEach(([key, val]) => this.set(key, val));
}

read() {
Object.entries(this.subject).forEach(([key, val]) => {
if (["x", "y"].includes(key)) return;
if (typeof this.subject[key] === "number") this.set(key, val);
});
}

write() {
this.keys.forEach(key => {
if (["x", "y"].includes(key)) return;
if (typeof this.subject[key] === "number") this.subject[key] = this.get(key);
});
}

get keys() {
return Object.keys(this.rna);
}

set(key, val) {
if (val === undefined) val = random();
if (this.bases[key]) {
this.rna[key] = val < 1 ? val : val / this.bases[key];
this.write();
return;
}
let base = 1;
while (base < val) base *= 10;
this.bases[key] = base;
this.rna[key] = val / base;
this.write();
}

get(key) {
return this.rna[key] * this.bases[key];
}

copy(subject, mutationRate) {
this.read();
let copy = new DNA(subject, this.rna, this.bases);
if(mutationRate) copy.mutate(mutationRate);
return copy;
}

mutate(mutationRate = 0.1) {
Object.entries(this.rna).forEach(([key, val]) => {
if (random() < mutationRate) {
if (random() < mutationRate) {
this.set(key);
} else {
this.set(key, randomGaussian(val, mutationRate));
}
} else {
this.set(key, val);
}
});
this.write();
return this;
}

}

export default DNA;
11 changes: 11 additions & 0 deletions noc/primordial/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<script src="p5.js"></script>
<script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<script src="sketch.js" type="module"></script>
</body>
</html>
Loading

0 comments on commit d4590af

Please sign in to comment.