NoC (W03): A Phenomenon with Forces
Floating Ping-pong Balls
p5js Link: Ping-pong-balls (p5js.org)
Idea: From the Deepest Memory
I was pretty stuck when dealing with the requirement. The force analysis during the physics class (also on the exam paper) is the only thing that I can come up with the forces. When I was immersed in the memory of high school, I memorized an interesting experiment that my physics teacher did for us in her first physic class with us which is using the hairdryer to make the ping-pong ball float. Although that was 7 years ago, although her experiment finally failed, although this is mainly presenting Bernoulli’s law, I think it’s suitable for practicing the forces on p5js. As for the ping-pong ball, it is subjected to gravity, the force of the wind, and the friction of the air (why I’m analyzing the forces here again!).
https://www.bilibili.com/video/BV1zE411P7mT/
Coding 01: Hair Drier? Aero Engine!
Above all, we must need a hair drier to blow the balls. Especially that kind of can change the speed. If you have seen my first NoC project (if you haven’t you are welcome to browse it first :), you must know my answer: why don’t we use the aero engine? That would be super cool!
So I use the aero engine code in my first project as the hair drier(more suitable for the giants lol). However, the engine is a perfect circle while the visual effect that I want to achieve is having an ellipse since the perspective relations. I use the scale() function to make the aero engine an ellipse:
push();
fill(100);
noStroke();
rect(0, 540, 600, 600);
scale(1, 0.2);
translate(0, 2400);
Engine();
pop();
Control();
Since most of the engine drawing codes are from my w01 project, I copied them into a function that can make the code easier to read. When setting the y-axis scale to 0.2, the overall shape becomes a pleasing ellipse. Although it is not a precise perspective relation, it seems acceptable.
Of course, since the aero engine is inhaling the air, so I make reversed its direction which can make it theoretically acceptable.
Coding 02: Ping-Pong-Ping-Pong
Then comes adding the balls. After coding the basic ES6 model objects and the basic frame of forces, the most important part is the forces. In this project, 4 forces need to apply.
class Ball { constructor(x, y, spd) { this.pos = createVector(x, y); this.vel = createVector(spd[0], spd[1]); this.acc = createVector(0, 0); this.gravity = createVector(0, 0.5); this.wind = createVector(0,0) this.scale = random(0.8, 1.2); this.mass = random(0.8, 1.2) this.windForce = 0 } update() { this.vel.add(this.acc); this.pos.add(this.vel); this.acc.mult(0); } display() { push(); noStroke(); fill(255); translate(this.pos.x, this.pos.y); scale(this.scale * this.mass); pingpong(); pop(); }
The first one is gravity. Gravity is quite simple since all the things that I need to do is add a certain number to the acceleration index:
this.gravity = createVector(0, 0.5); //gravity this.acc.add(this.gravity);
After applying gravity, then is the air friction. According to my physics common knowledge, air friction is related to the speed of an object. So I put the air friction multiply the speed and becomes the final acceleration:
//friction this.friction = createVector(this.vel.x * -0.005, this.vel.y * -0.005); this.acc.add(this.friction);
Here comes the most complicated force which is the force from the wind. It should be related to the distance from the engine and its turning speed of it:
//windForce this.wind = createVector(0, (-RPM * 0.3/(height - this.pos.y))/this.mass ** 2) this.acc.add(this.wind)
Here I use RPM/(height – this.pos.y) to make the force has a negative correlation with the distance.
And you can see that I’ve added the this.mass here. Actually, I’ve made the ball has a random mass and scale. In this case, a bigger ball will have a higher mass and will become harder for the wind to blow up. From the height, we can see the heavier ball will have a lower height than the light one.
The last force is the bouncing force. When the ball hit the ground, it will bounce up. Since we can simplify the process by only changing its speed, it becomes not that complex:
checkStatus() { if (this.pos.y > height - 100 + (this.scale - 1) * 200 && this.vel.y >= 0) { if (this.vel.y <= 0.5 && RPM <= 130) { this.acc.y = 0; this.vel.y = 0; } else { this.vel.y *= -0.95; } } }
After all, here is the final effect:
Reflection: May the Forces be with You
With the help of the forces, we can easily simulate the movement of a certain object. Along with the addition of the forces, we can simplify the complex movement into a simple one. However, there are still some restrictions of the force simulation, as we can still hard to simulate the shape of a string. Hope I can have a more comprehensive capability of stimulating these objects.