function move_charges(charges) { for (let charge of charges) { charge.acceleration.setMag(0); } for (let i = 0; i < charges.length; i += 1) { for (let j = 0; j < i; j += 1) { const displacement = p5.Vector.sub( charges[i].position, charges[j].position, ); let acceleration_mag = 1 / displacement.mag() * 0.001; let ai; if (acceleration_mag === Infinity) { ai = p5.Vector.random3D(); } else { ai = displacement.copy().normalize(); } ai.mult(acceleration_mag); let aj = p5.Vector.mult(ai, -1); project_onto_plane(ai, charges[i].position); project_onto_plane(aj, charges[j].position); charges[i].acceleration.add(ai); charges[j].acceleration.add(aj); } } for (let charge of charges) { charge.velocity = charge.velocity.add(charge.acceleration); charge.position = charge.position.add(charge.velocity); charge.position.normalize(); } } function project_onto_unit_vector(v, unit_vector) { let size = p5.Vector.dot(v, unit_vector); return p5.Vector.mult(unit_vector, size); } /// Project `v` onto the plane normal to `unit_vector` /// Mutates `v` function project_onto_plane(v, unit_vector) { let v_proj = project_onto_unit_vector(v, unit_vector); v.sub(v_proj) }