Taking what I learned from the original version of the orbiting bodies sketch, I set out to multiply the number of particles by n, with each particle having its own properties of mass (which is doubling as diameter assuming all the particles have the same density), orbital radius, and resulting orbital velocity.

I tested out the logic by using ellipses as stand-ins for orbital trajectories. Once I nailed down the logic for how the mouseX and mouseY would affect the view, I moved on to developing how the particles would work. I also incorporated the translate function which saved me a bit of time. It’s a lot simpler to use translate than applying the math right into the functions.

Recalling from high school physics (by way of Google), V=√(G*M/r) with G standing in for the gravitational constant. This isn’t based on any real values, so I adjusted G until everything looked kind of smooth. For M and r, I entered random values, and V, I allowed to be the result of √(G*M/r). I established each of the variables as an array so that each of the particles could behave independently. Each particle has an orbital velocity that is exponentially proportional to the ratio of the particle’s mass to its distance from the center. This means bigger particles will travel faster and particles that are farther away will orbit more slowly.

I also added a feature that adds a particle when the left mouse button is clicked. Considering there are anywhere between 100 to 1,000 particles on screen, I made the new particles have a slightly red hue in order to differentiate themselves from the existing ones. One the number of particles reaches around 1,000, the sketch starts to drop frames, so I think 500 to 700 is the optimal number. Overall I’m pretty satisfied with the results, but the particles overlap each other in some unrealistic ways. I think that level of accuracy would require the use of 3D geometry.

let aY = []; //mouse y axis camera angle let m = []; //mass let s = []; //speed let r = []; //orbital radius let sh = []; //giving particles random colors let re = []; //leaving one value to distinguish new particles let n = 500; //initial number of particles in system let i; //counters let fC = 200; //our version of framecount, starting at 200 ensures random distribution function setup() { createCanvas(800, 800); /*filling out values. Orbital speed is the square root of mass times G over distance from center AKA radius.*/ for (i = 0; i < n; i += 1) { m[i] = random(5); r[i] = random(width * 0.3, width * 0.5); s[i] = sqrt(m[i] / r[i] ); sh[i] = random(100, 180); re[i] = sh[i]; } } function draw() { background(0, 50); translate(width / 2 - mouseX, 0); //camera pan based on mouseX location for (i = 0; i < n; i += 1) { aY = (r[i] / 2 - (mouseY / height) * r[i]); //aY is the resulting y radius of the ellipse based on the mouseY location strokeWeight(m[i] * (sin(s[i] * fC * PI / 2 + PI / 2) + 2) / 2); stroke(re[i], sh[i], sh[i], 125); fill(255); ellipse(r[i] * sin(s[i] * fC * PI / 2) + width / 2, aY * cos(s[i] * fC * PI / 2) + height / 2, m[i] * (sin(s[i] * fC * PI / 2 + PI / 2) + 2), m[i] * (sin(s[i] * fC * PI / 2 + PI / 2) + 2) ); } fC += 0.03; } function mousePressed() { if (mouseButton == LEFT) { n += 1; m[n - 1] = random(5); r[n - 1] = random(width * 0.3, width * 0.5); s[n - 1] = sqrt(m[n - 1] / r[n - 1] * 3); sh[n - 1] = random(0, 100); re[n - 1] = random(180, 255); } else { n -= 1; if (n < 0) { n = 0 } } }