Created
July 17, 2020 23:40
-
-
Save villares/ed22ac4418c25d7b16c38475239351cb to your computer and use it in GitHub Desktop.
Adapting Repeller from Khan Academy for p5js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // adapted from Khan Academy that adapts Dan Shiffman, natureofcode.com | |
| // https://pt.khanacademy.org/computing/computer-programming/programming-natural-simulations/programming-particle-systems/a/particle-systems-with-forces | |
| var gravity; | |
| var particleSystem; | |
| var repeller; | |
| function setup() { | |
| createCanvas(400, 400); | |
| gravity = createVector(0, 0.2); | |
| particleSystem = new ParticleSystem(createVector(width / 2, 50)); | |
| repeller = new Repeller(width / 2, 280); | |
| } | |
| var Repeller = function(x, y) { | |
| this.power = 398; | |
| this.position = createVector(x, y); | |
| }; | |
| Repeller.prototype.display = function() { | |
| stroke(255); | |
| strokeWeight(2); | |
| fill(127); | |
| ellipse(this.position.x, this.position.y, 32, 32); | |
| }; | |
| Repeller.prototype.calculateRepelForce = function(p) { | |
| // Calculate direction of force | |
| var dir = p5.Vector.sub(this.position, p.position); | |
| // Distance between objects | |
| var d = dir.mag(); | |
| // Normalize direction vector | |
| dir.normalize(); | |
| // Keep distance within a reasonable range | |
| d = constrain(d, 1, 100); | |
| // Repelling force is inversely proportional to distance | |
| var force = -1 * this.power / (d * d); | |
| // Get force vector --> magnitude * direction | |
| dir.mult(force); | |
| return dir; | |
| }; | |
| var Particle = function(position) { | |
| this.acceleration = createVector(0, 0); | |
| this.velocity = createVector(random(-1, 1) / 5, 0); | |
| this.position = position.copy(); | |
| this.timeToLive = 255.0; | |
| this.mass = random(5, 20); | |
| }; | |
| Particle.prototype.run = function() { | |
| this.update(); | |
| this.display(); | |
| }; | |
| Particle.prototype.applyForce = function(force) { | |
| var f = force.copy(); | |
| f.div(this.mass); | |
| this.acceleration.add(f); | |
| }; | |
| Particle.prototype.update = function() { | |
| this.velocity.add(this.acceleration); | |
| this.position.add(this.velocity); | |
| this.acceleration.mult(0); | |
| this.timeToLive -= 1; | |
| }; | |
| Particle.prototype.display = function() { | |
| stroke(0, 0, 0, this.timeToLive); | |
| strokeWeight(2); | |
| fill(255, 0, 0, this.timeToLive); | |
| ellipse(this.position.x, this.position.y, this.mass, this.mass); | |
| }; | |
| Particle.prototype.isDead = function() { | |
| if (this.timeToLive < 0.0 || this.position.y > 410) { | |
| return true; | |
| } else { | |
| return false; | |
| } | |
| }; | |
| var ParticleSystem = function(position) { | |
| this.origin = position.copy(); | |
| this.particles = []; | |
| }; | |
| ParticleSystem.prototype.addParticle = function() { | |
| this.particles.push(new Particle(this.origin)); | |
| }; | |
| ParticleSystem.prototype.applyForce = function(f) { | |
| for (var i = 0; i < this.particles.length; i++) { | |
| this.particles[i].applyForce(f); | |
| } | |
| }; | |
| ParticleSystem.prototype.applyGravity = function() { | |
| for (var i = 0; i < this.particles.length; i++) { | |
| var particleG = gravity.copy(); | |
| particleG.mult(this.particles[i].mass); | |
| this.particles[i].applyForce(particleG); | |
| } | |
| }; | |
| ParticleSystem.prototype.applyRepeller = function(r) { | |
| for (var i = 0; i < this.particles.length; i++) { | |
| var p = this.particles[i]; | |
| var force = r.calculateRepelForce(p); | |
| p.applyForce(force); | |
| } | |
| }; | |
| ParticleSystem.prototype.run = function() { | |
| for (var i = this.particles.length - 1; i >= 0; i--) { | |
| var p = this.particles[i]; | |
| p.run(); | |
| if (p.isDead()) { | |
| this.particles.splice(i, 1); | |
| } | |
| } | |
| }; | |
| draw = function() { | |
| background(214, 255, 171); | |
| particleSystem.applyGravity(); | |
| particleSystem.applyRepeller(repeller); | |
| repeller.display(); | |
| particleSystem.addParticle(); | |
| particleSystem.run(); | |
| fill(0); | |
| text(particleSystem.particles.length, 20, 380); | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment