Remember: As you work on these steps with guidance from your teaching assistant, you should look toward your neighbor to see if they need help (or ask if you need help). You can collaborate in lab during these activities!
In this lab, you will
Here is a link to the p5.js template we are using to create the program.
Modify the particle system example done in class (Lecture 20) so that particles have a variety of colors and sizes.
var gravity = 0.3; // downward acceleration var spring = 0.7; // how much velocity is retained after bounce var drag = 0.0001; // drag causes particles to slow down var np = 100; // how many particles function particleStep() { this.age++; this.x += this.dx; this.y += this.dy; if (this.x > width) { // bounce off right wall this.x = width - (this.x - width); this.dx = -this.dx * spring; } else if (this.x < 0) { // bounce off left wall this.x = -this.x; this.dx = -this.dx * spring; } if (this.y > height) { // bounce off bottom this.y = height - (this.y - height); this.dy = -this.dy * spring; } else if (this.y < 0) { // bounce off top this.y = -this.y; this.dy = -this.dy * spring; } this.dy = this.dy + gravity; // force of gravity // drag is proportional to velocity squared // which is the sum of the squares of dx and dy var vs = Math.pow(this.dx, 2) + Math.pow(this.dy, 2); // d is the ratio of old velocty to new velocity var d = vs * drag; // d goes up with velocity squared but can never be // so high that the velocity reverses, so limit d to 1 d = min(d, 1); // scale dx and dy to include drag effect this.dx *= (1 - d); this.dy *= (1 - d); } function particleDraw() { point(this.x, this.y); } // create a "Particle" object with position and velocity function makeParticle(px, py, pdx, pdy) { p = {x: px, y: py, dx: pdx, dy: pdy, age: 0, stepFunction: particleStep, drawFunction: particleDraw } return p; } var particles = []; function setup() { createCanvas(400, 400); for (var i = 0; i < np; i++) { // make a particle var p = makeParticle(200, 200, random(-50, 50), random(-50, 50)); // push the particle onto particles array particles.push(p); } frameRate(10); } // draw all particles in the particles array // function draw() { background(230); stroke(0); strokeWeight(10); if (mouseIsPressed) { var newp = makeParticle(mouseX, mouseY, random(-10, 10), random(-10, 0)); particles.push(newp); } // newParticles will hold all the particles that we want to // retain for the next call to draw() -- we will retain particles // if the age is < 200 (frames). Initially, newParticle is empty // because we have not found any "young" particles yet. newParticles = []; for (var i = 0; i < particles.length; i++) { // for each particle var p = particles[i]; p.stepFunction(); p.drawFunction(); // since we are "looking" at every particle in order to // draw it, let's use the opportunity to see if particle[i] // is younger than 200 frames. If so, we'll push it onto the // end of newParticles. if (p.age < 200) { newParticles.push(p); } } // now, newParticles has EVERY particle with an age < 200 frames. // these are the particles we want to draw next time, so assign // particles to this new array. The old value of particles, i.e. // the entire array, is simply "lost" -- Javascript will reclaim // and reuse the memory since that array is no longer needed. particles = newParticles; }
Here is one frame of a possible solution:
Copy the program from the previous problem into a new project. In this exercise, you will decrease the size of the particle as it gets older. After the particle ages every 40 steps, shrink the size of the particle by 20%. Think: where in the code would you make this update?
Test your program to make sure it works correctly. (You may want to reduce the number of particles so you can see what’s happening more easily.)
Let (rpx, rpy) represent a location that repels particles. The value rpc represents a fixed, constant factor that you should adjust to get the right “look”: if rpc is too small, particles will not be noticeably affected by the force. If rpc is extremely large, particles will all be immediately pushed away, possibly “running” to the corners to “get away.”
This challenge is inspired by “Example 4.7: ParticleSystem with repeller” from Chapter 4 of Daniel Shiffman, The Nature of Code.
Review the implementation of the particles and springs arrays in the Try This exercise of Lecture 21. (Sample code is given in the Lecture 21 zip file on Canvas.) Be sure you understand how the code that initializes the two arrays leads to the initial particle/spring configuration on the canvas.