@@ -259,14 +259,14 @@ void Particle_Gravity_update(PSparticle *part, bool wrapX, bool bounceX, bool bo
259259 part->ttl --;
260260
261261 // check if particle is out of bounds or died
262- if ((part->y < -PS_P_RADIUS) || (part->y >= PS_MAX_Y << 1 ))
262+ if ((part->y < -PS_P_RADIUS) || (part->y >= PS_MAX_Y << 2 ))
263263 { // if it moves more than 1 pixel below y=0, it will not come back. also remove particles that too far above
264264 part->ttl = 0 ;
265265 return ; // particle died, we are done
266266 }
267267 if (wrapX == false )
268268 {
269- if ((part->x < -PS_MAX_X) || (part->x >= PS_MAX_X << 1 ))
269+ if ((part->x < -PS_MAX_X) || (part->x >= PS_MAX_X << 2 ))
270270 { // left and right: keep it alive as long as its not too far out (if adding more effects like wind, it may come back)
271271 part->ttl = 0 ;
272272 return ; // particle died, we are done
@@ -733,7 +733,7 @@ void detectCollisions(PSparticle* particles, uint32_t numparticles, uint8_t hard
733733 {
734734 // go though all 'higher number' particles and see if any of those are in close proximity
735735 // if they are, make them collide
736- if (particles[i].ttl > 0 && particles[i].collide ) // if particle is alive and does collide
736+ if (particles[i].ttl > 0 && particles[i].collide && particles[i]. outofbounds == 0 ) // if particle is alive and does collide and is not out of view
737737 {
738738 int32_t dx, dy; // distance to other particles
739739 for (j = i + 1 ; j < numparticles; j++)
@@ -771,15 +771,15 @@ void handleCollision(PSparticle *particle1, PSparticle *particle2, const uint8_t
771771 {
772772 // Adjust positions based on relative velocity direction
773773
774- if (relativeVx <= 0 ) { // if true, particle2 is on the right side
774+ if (relativeVx < 0 ) { // if true, particle2 is on the right side
775775 particle1->x --;
776776 particle2->x ++;
777777 } else {
778778 particle1->x ++;
779779 particle2->x --;
780780 }
781781
782- if (relativeVy <= 0 ) {
782+ if (relativeVy < 0 ) {
783783 particle1->y --;
784784 particle2->y ++;
785785 } else {
@@ -805,7 +805,7 @@ void handleCollision(PSparticle *particle1, PSparticle *particle2, const uint8_t
805805 particle2->vx -= ximpulse;
806806 particle2->vy -= yimpulse;
807807
808- if (hardness < 50 ) // if particles are soft, they become 'sticky' i.e. no slow movements
808+ if (hardness < 50 ) // if particles are soft, they become 'sticky' i.e. slow movements are stopped
809809 {
810810 particle1->vx = (particle1->vx < 2 && particle1->vx > -2 ) ? 0 : particle1->vx ;
811811 particle1->vy = (particle1->vy < 2 && particle1->vy > -2 ) ? 0 : particle1->vy ;
@@ -814,38 +814,45 @@ void handleCollision(PSparticle *particle1, PSparticle *particle2, const uint8_t
814814 particle2->vy = (particle2->vy < 2 && particle2->vy > -2 ) ? 0 : particle2->vy ;
815815 }
816816
817- }
818-
817+ }
819818 // particles have volume, push particles apart if they are too close by moving each particle by a fixed amount away from the other particle
820819 // if pushing is made dependent on hardness, things start to oscillate much more, better to just add a fixed, small increment (tried lots of configurations, this one works best)
821820 // one problem remaining is, particles get squished if (external) force applied is higher than the pushback but this may also be desirable if particles are soft. also some oscillations cannot be avoided without addigng a counter
822- if (distanceSquared < 2 * PS_P_HARDRADIUS * PS_P_HARDRADIUS)
821+ if (distanceSquared < ( int32_t ) 2 * PS_P_HARDRADIUS * PS_P_HARDRADIUS)
823822 {
824- uint8_t rndchoice = random8 (2 );
825- const uint32_t HARDDIAMETER = 2 *PS_P_HARDRADIUS;
823+ uint8_t choice = random8 (2 );// randomly choose one particle to push, avoids oscillations
824+ const int32_t HARDDIAMETER = (int32_t )2 *PS_P_HARDRADIUS;
825+
826826
827827 if (dx < HARDDIAMETER && dx > -HARDDIAMETER)
828828 { // distance is too small, push them apart
829- int32_t push = 3 ;
830- if (dx < 0 ) // dx is negative
831- push =-push; // negative push direction
832829
833- if (rndchoice) // randomly chose one of the particles to push, avoids oscillations
830+ int32_t push;
831+ if (dx <= 0 )
832+ push = -1 ;// -(PS_P_HARDRADIUS + dx); // inverted push direction
833+ else
834+ push = 1 ;// PS_P_HARDRADIUS - dx;
835+
836+ if (choice) // chose one of the particles to push, avoids oscillations
834837 particle1->x -= push;
835838 else
836- particle2->x += push; // only push one particle to avoid oscillations
839+ particle2->x += push;
837840 }
838-
841+ // Serial.print(" dy");
842+ // Serial.println(dy);
839843 if (dy < HARDDIAMETER && dy > -HARDDIAMETER)
840- { // distance is too small (or negative)
841- int32_t push = 3 ;
842- if (dy < 0 ) // dy is negative
843- push = -push;// negative push direction
844+ {
845+
846+ int32_t push;
847+ if (dy <= 0 )
848+ push = -1 ; // -(PS_P_HARDRADIUS + dy); // inverted push direction
849+ else
850+ push = 1 ; // PS_P_HARDRADIUS - dy;
844851
845- if (rndchoice ) // randomly chose one of the particles to push, avoids oscillations
852+ if (choice ) // chose one of the particles to push, avoids oscillations
846853 particle1->y -= push;
847854 else
848- particle2->y += push; // only push one particle to avoid oscillations
855+ particle2->y += push;
849856 }
850857 // note: pushing may push particles out of frame, if bounce is active, it will move it back as position will be limited to within frame
851858 }
0 commit comments