1

Ok I have a particle system going in Android.

Right now I use 500 or so particles and they randomly move around the screen. I set it so that on touch (actually motion right now). that all the particles would approach your finger. Problem being is that they're approaching at a static angle (not taking into the angle they are from the touch point).

Anyone have the algorithm to determine how to evenly approach a point? My attempt to get the angle in randians.. then convert etc.. got really messy. This simple approach showed that I move at the right pace.. but it's a simple 45 angle approach. (keep in mind on android there are no negative x,y coordinates.. and top left is 0,0.. bottom right is (max,max). the functions takes the ontouch (x,y) coordinates. b.x, b.y are the particle coordiantes.

public void moveParticles(float x, float y) {
    for (Particle b : Particles)
        {
         if (x <= b.x)
             b.x = b.x -1;
         else b.x = b.x +1;

          if (y <= b.y)
            b.y = b.y -1;
          else b.y = b.y +1;
         }          
}
DJPlayer
  • 3,244
  • 2
  • 33
  • 40
  • By evenly do you mean a better transition instead of straight to the point of touch? Like a circular motion towards the center? – Jack Sep 29 '11 at 01:47
  • If you look at how the code it will approach the point of touch @ a 45 degree angle after it hits either the x axis or y axis of the point of origin.. it will go to the origin. Really what should happen is each particle should approach the point or origin in a straight line fashion. – DJPlayer Sep 29 '11 at 02:05

2 Answers2

2

Naive code that assumes touch is in the centre of the screen:

public void moveParticles(float x, float y) {
    for (Particle b : Particles) {
      b.x += ((b.x-x)/(x/2))*speedmodifier;
      b.y += ((b.y-y)/(y/2))*speedmodifier;
    }
}

Code with normalised speeds each side of the touch axis:

public void moveParticles(float x, float y) {
    for (Particle b : Particles) {
      height_difference = screenheight-x;
      width_difference = screenwidth-y;
      height_ratio = (b.x < x) ? screen_height-height_difference : height_diffrence;
      width_ratio = (b.y < y) ? screenwidth-width_difference : width_difference;

      b.x += ((b.x-x)/height_ratio)*speedmodifier;
      b.y += ((b.y-y)/width_ratio)*speedmodifier;
    }
}

Steps to make this code: You need to get the ratio of the screen above and below the x and y axis, so as to normalise the speed of the particles from 0 to 1 no matter where the touch is:

height_difference = screenheight-x;
width_difference = screenwidth-y;
height_ratio = (b.x < x) ? screen_height-height_difference : height_diffrence;
width_ratio = (b.y < y) ? screenwidth-width_difference : width_difference;

Once we have that normalisation information we can use it to normalise the particle speeds:

b.x += ((b.x-x)/height_ratio)*speedmodifier;
b.y += ((b.y-y)/width_ratio)*speedmodifier;
Serdalis
  • 10,296
  • 2
  • 38
  • 58
  • omg!! that was so freaking easy I'm just plain embarrassed. I get angles, converting radians, using sin and cos etc.. oh btw.. change your your code to b.x-=.....; and b.y-=......" thanks. As I hang my head in shame.. – DJPlayer Sep 29 '11 at 02:35
  • It is quite easy for a centered touch, however i've now added code for a touch that may not be centered, see the code below the first function. Glad it helps! – Serdalis Sep 29 '11 at 02:41
  • I implemented a good portion of that.. I noticed that on my tablet screen (so I have alot of real estate to play on). When you touch, the shrinking area almost resembles the shape of a box. What I did was set the speed modifier equivalent to a calculation based on distance from the touchpoint to particle. So objects further away would come faster vs. a static speed. Makes the convergence look more spherical rather than "boxy". Might toss in a very controlled number just to keep it from looking to geometric. – DJPlayer Sep 29 '11 at 03:17
  • @DJPlayer great work that sounds accurate since this function is linear, if you want to make it exponential you do exactly as you have done. – Serdalis Sep 29 '11 at 04:04
1

Take the particle's displacement as a vector with convergence point as origin:

x = particle.x - finger.x
y = particle.y - finger.y

Get unit vector:

norm = sqrt(pow(x, 2.0) + pow(y, 2.0))
x = x / norm
y = y / norm

Displace particle by unit vector * -1 * speed factor:

particle.x -= x * speed
particle.y -= y * speed

Does that work? I just wrote this out, didn't try it or nothin'.

mdunsmuir
  • 41
  • 2