We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello forum, Always thank you for yall's comments. I think I become to feel more comfortable to write some codes and at the same time want to try something more complicated.
I'm thinking of making a code which is sensitive to density of particles and able to bounce off once the collisions happen. However, I was stuck in the code which is for making my particles bounce off from the surface of squares and have no idea about how to make my particles slow down once the density of particles nearby gets higher.
Below is the code I made for illustrating particle movement from the bottom and squares dispersed through out the screen.
How can I make the particle recognize the surface of the squares in the screen, and make the speed of particles slows down once the number of particles within 100*100 pixels gets more than 50?
I think rather than putting the numbers for my squares, I think it would be better to set the variables for each squares to make a collision equation. No matter how many sample codes I looked through from github, I didn't find any code examples for this situation.
=Sketch=
Particle [] parts = new Particle [500];
float x;
float y;
float r;
float sx1 =30, sx2=120, sx3=210, sx4=300;
float sy1 =30, sy2 =120, sy3=210, sy4=300;
void setup(){
size(600,400);
for(int i =0; i<parts.length;i++) {
float x = random(0,width);
float y = 0;
parts[i] = new Particle();
}
}
void draw(){
background(200);
for (int i =0;i<parts.length;i++) {
parts[i].display();
parts[i].movement();
parts[i].finish();
}
fill(100,50);
rect(sx1,sy1,60,60);
rect(sx2,sy2,60,60);
rect(sx3,sy3,60,60);
rect(sx4,sy4,60,60);
rect(sx2,sy1,60,60);
rect(sx2,sy1,60,60);
rect(sx3,sy1,60,60);
rect(sx4,sy1,60,60);
}
=Particle Class=
class Particle {
float x;
float y;
float r;
float distance;
float speed;
//float sx1 =30, sx2=120, sx3=210, sx4=300;
//float sy1 =30, sy2 =120, sy3=210, sy4=300;
Particle () {
x= random(0,width);
y= height;
r= 10;
speed = random(0.1,0.5);
}
void display() {
stroke(0);
fill(255,0,0,80);
ellipse(x,y,r,r);
}
void movement() {
x=x+random(-0.5,0.5);
y=y-speed;
}
void finish() {
if (y>=height) {
speed = 0;
}
}
}
Answers
There you have two different problems. You need to approach the first one bey starting with one particle. For this, you can check the collision algorithms available either in the forum or in other common resources. For example: https://processing.org/examples/bounce.html or https://processing.org/examples/circlecollision.html or https://forum.processing.org/two/discussion/23052/collision-detection#latest
For the second problem, you can use the concept of collision detection that you developed in your first step but using a modified version. In the first step you need to work with collision detection between a square and a circle. In the second problem, you do it between circle-circle elements. You use the distance calculation to count how many particles are close by. To do this, you need to go through each particle and check the distance to all other particles. You count the number of particles within your selected distance, let's say a radius of 100. Using this number and the distance, you calculate the density and then adjust the speed.
There is a question that needs to be address first: Is not clear in your example if overlapping particles is acceptable or if you want to check for overlapping conditions before placing a particle in your universe.
Kf
@kfajer
Thank you so much. I will look into the link in the forum. Actually, I already went through all the links you attached, but I wasn't sure whether it's the right thing for me. Thank you so much.
@kfrajer's advice on using collision detection for detecting density is good -- and it is a simple way to start, using the same logic for both.
Once you have that working, you can also optimize the processing of detecting density using zones.
If you use collision detection, every particle checks every other particle -- so 1,000 particles is ~1,000,000 checks (per frame).
Instead you could try creating a grid of screen zones (spatial bins) at whatever spatial resolution you want (e.g. 4x4 zones, 16x16, etc.). Loop through the list of particles and check each particle against the zone list, assign it the zone it currently occupies (rect collision detection) and increment a zone counter (e.g. +1 = 14 particles in this zone). When you move a particle, set its speed based on the counter of its current zone.
1,000 particles requires up to 16,000 checks -- breaking the switch statement when you hit a match probably means more like ~8,000 checks if your particles are evenly distributed, plus a lookup of the final count is 9,000 checks -- better than 1,000,000.
You can further optimize this by always first checking a particle's previous zone, then checking the rest of the list only if it doesn't match. Depending on speed and zone resolution, if most particles are in the same zone that they were in during the previous frame then that might get you down to 1,000 particles requiring only ~1,200 checks plus a lookup is 2,200 checks.
One other thing I should mention -- if the zones are perfectly regular subdivisions of the screen, you can simple compute zone directly.
e.g.:
A 400x400 screen divided into 4x4 zones of 100x100 pixels each -- with density / population counters for each zone stored in the 2d array
int[][] zones = new int[4][4]
;So we can just increment by adding 1 to the value of the array member
zones[x%zonewidth][y%zoneheight]
-- a particle at (250,350) is in zones[2][3] ... without having to loop through each zone and test for a collision.