Concept
For this assignment, I have created a particle simulator, in which small particles move away from the cursor and return to their initial positions. As the particles are in motion, their color will change. Recently, I have read several papers regarding electromagnetic forces and quantum fields. This project is inspired by the electromagnetic interactions between charged particles. I pictured small localized particles on a field, on which the particles are repelled by an external force (the cursor). The particles will then return to their initial position because they are most stable on those points. The color red means the particles are stable; the color blue means the particles are unstable.
Code
I began writing codes for declaring a class for small particles. Each particle will store 5 different pieces of information about their X and Y coordinates of their initial positions, X and Y coordinates of their current positions, and the color that will be used to set the stroke color.
class spacePoints { //Declare class constructor(posX, posY) { this.posX0 = posX; //Original X coordinate of the point this.posY0 = posY; //Original Y coordinate of the point this.posX = posX; //Current X coordinate this.posY = posY; //Current Y coordinate this.color = 255; //Color of the point when drawn }
The most challenging codes to write in this project was a class method, which updates the position of the particles depending on the cursor position. Using dist(), I measured distance between a particle and the cursor. If the distance is smaller than the defined threshold, the particle must be repelled. To do this, a vector that is always directed away from the cursor was declared. Then, the magnitude of the vector was modified to make its magnitude increase as the cursor gets closer to a particle. Since the particle is in motion, and thus, unstable, the particle’s color property is also modified.
If there is no cursor near a particle, a particle is moved back to its initial position. Another vector that points towards a particle’s initial position was created. Based on this vector, a particle’s position is updated.
movePoint() { let cursorDist = dist(this.posX, this.posY, mouseX, mouseY); if (cursorDist < 100) { let dVec = createVector(this.posX - mouseX, this.posY-mouseY); dVec = dVec.setMag(100 / dVec.mag()); this.posX += constrain(dVec.x, -20, 20); this.posY += constrain(dVec.y, -20, 20); this.color = 0; } else { if (abs(this.posX - this.posX0) > 1 || abs(this.posY != this.posY0) > 1) { let dVec = createVector(this.posX0 - this.posX, this.posY0 - this.posY); dVec.setMag(1); this.posX += dVec.x; this.posY += dVec.y; }else this.color=255; } }
In the end, I wrote a short method that draws a particle based on the canvas. One noticeable thing is that the stroke color will change depending on a particle’s color property.
drawPoint() { //Draw a spacePoint noFill(); stroke(this.color,125,125); strokeWeight(3); circle(this.posX, this.posY, 8); }
Click listener is also used, so the user can freely add particles on specific points they click on.
function mouseClicked() { //When mouse is clicked append(pArr, new spacePoints(mouseX+random(-5,5), mouseY+random(5,-5))); //Generate new spacePoint at where the mouse is clicked. Store it in pArr[] pNum++; //Increase number of current number of spacePoints by 1 }
The draw function is rather very simple because all calculations are done by the functions and objects.
function draw() { background(0); for (let i = 0; i < pNum; i++) { pArr[i].movePoint(); //Update positions of spacePoints in pArr pArr[i].drawPoint(); //Draw spacePoints in pArr on the canvas } }
Reflection / Future Improvements
I am very happy about my project’s complex mathematical logic behind the simple appearance. I initially added lines that show the current direction and velocity of the particle’s motion, but I had to remove the lines to keep my project look simple. This is the first project that I did not use translate() to handle coordinate calculations, which I found surprisingly easy without shifting my origin to the canvas center.
If I have another opportunity to work on this project, I would like to change and improve upon these:
- Optimization. Though code seems to run smoothly regardless of the number of particles, there are rare moments the code takes time to start. I believe this problem occurred because I used vectors for angle calculations. Instead of calculating angles via vectors, the program may run faster if mathematical expressions are used.
- Collision Detection. The project will look more interesting if each particle interacted with the other. If each particle has collision detection features, the particle simulator will be more realistic. However, because collision detection require more computing power, the codes must be optimized before adding this feature.
Awesome! Would be cool if the particles had some motion of their own (e.g. drifting on the screen) as well as being influenced by the mouse. The colour change for the particles influenced by the mouse is nice.