We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Charged Particles
Pages: 1 2 3 
Charged Particles (Read 5610 times)
Charged Particles
Dec 9th, 2009, 12:35pm
 
Hi..I've written a little program that places some charged (negative and positive) particles in a box, and then lets their attractions and repulsions determine their behaviour. I really wanted repulsion to take over regardless of the charges if the particles got too close - but for some weird reason when I put this code in none of the particles will draw. See:

http://www.openprocessing.org/visuals/?visualID=6456

I have commented out the offending bit of code. I'm also losing particles out of the edges of the screen, despite my best efforts to stop them.

Any suggestions welcome, thanks.
Re: Charged Particles
Reply #1 - Dec 9th, 2009, 3:13pm
 
How come your repulsive forces have negative signs? I thought they should have positive signs.
Re: Charged Particles
Reply #2 - Dec 9th, 2009, 3:18pm
 
Yes, you're right. I would have noticed that in the behaviour if it ran with that code in there....which it won't, which I find puzzling.
Re: Charged Particles
Reply #3 - Dec 9th, 2009, 3:31pm
 
Because you commit a cardinal sin: division by zero is very bad indeed!

Code:
 else  //repulsive force if particles get too close. Uncomment this and it breaks program. Why?? 
       {
         if(ijdist>0){
        xaccel+=  -1*(force/(ijdist*ijdist)) * cos(theta);  
         yaccel+=  -1*(force/(ijdist*ijdist)) * sin(theta);  
         }
       }


I'd also be a little more ruthless with your constraints.  It may be that your particles have enough velocity that they simply hang beyond the edge of the screen at which point they'll get stuck in a loop of having it multiplied by -1 each frame (but perhaps never long enough to get back on screen).  If a particle strays beyond your bounds you place it back within the bounds and then change its velocity:

Code:

if (posX > width) {
 posX = width;
 vx *= -1;
}
Re: Charged Particles
Reply #4 - Dec 9th, 2009, 4:51pm
 
Great, thanks. Your comments let me fix the issues. I still left the "repulsion at close range for all particles" bit out as it made the behaviour less interesting. You can uncomment it yourself now, if you're curious to see the difference.
Re: Charged Particles
Reply #5 - Dec 9th, 2009, 7:33pm
 
You can use something like f_constant/(r^4) for a repulsion force this way, it doesn't affect attraction far away but it strongly repulses when particles get too close. Give it a try or google Leonard-Jones potential and see that for effective long-range attraction and short-range repulsion what you would need. Are you learning physics or just trying out the electrostatic formula?
Re: Charged Particles
Reply #6 - Dec 10th, 2009, 7:06am
 
I'm just playing around with stuff. I used to be a scientist, but I gave it up and moved into fine arts practice about 9 years ago. So I did all this chemistry/ physics/ maths at university, which I still remember well - and then later on I did a Fine Arts degree... and maybe I'm just starting to bring my science and arts backgrounds together with this coding art. For some reason a lot of the science I learned in the past seems to be surfacing in my mind and I feel like playing around with it.

It's great to create an accurate model and then start playing around with it, changing the laws of physics to create some interesting behaviour.

I'll try out that 1/r^4 idea.... I had the repulsion at 1/r^2, but it was too strong and resulting in a sort of jerky bouncing that I didn't like.
Re: Charged Particles
Reply #7 - Dec 10th, 2009, 7:48am
 
Here is one more idea you can toy with: to keep the particles on your screen, instead of letting them bouncing off the border, which you had some slight trouble and lose some particle, you may employ a periodic boundary condition where, if the particle travels too much to the left, it appears to have wrapped around and come in from the right. Physicists use this in a lot of places. You would just add screen width your calculated x-position if x appears negative after update, same for y.
Re: Charged Particles
Reply #8 - Dec 10th, 2009, 12:09pm
 
I thought of that. It effectively creates a toroidal surface. As the particles are sort of forming into chains and following each other around, then I wouldn't want that to be broken by the one of the particles wrapping around to the other side. So the distances would have to be calculated on that toroidal surface (which makes my head hurt).
Re: Charged Particles
Reply #9 - Dec 10th, 2009, 12:51pm
 
I looked up the  Leonard-Jones potential , and I do remember that now from the physical chemistry courses I did (a while ago). If you just used this equation (without charges), and combined it with a random, brownian motion type of movement, you could simulate the van der Waals attractions of, say, a bunch of argon atoms, perturbed by thermal random movement. Clusters would form, but would break apart because of the random vibrations.

Anyway, I added the 1/r^4 repulsions and the wrapping you suggested, and updated the sketch on OpenProcessing:

http://www.openprocessing.org/visuals/?visualID=6456
Re: Charged Particles
Reply #10 - Dec 10th, 2009, 2:17pm
 
Now interactive - click and drag particles to move them. Click in empty space to create new particles.
Re: Charged Particles
Reply #11 - Dec 11th, 2009, 8:19am
 
Cool! It is only getting more interesting each day! Here is another suggestion: for dragging, if you can record the dragged position of the last frame, or even better, 10 frames ago, you can use the difference in the current position and the position 10 frames ago as the velocity of the particle when it is released by the mouse:
vx=(x_released-x_10_frames_ago_still_dragged)/10 or divide by number of frames between the positions.
^_^
Re: Charged Particles
Reply #12 - Dec 13th, 2009, 11:00am
 
Good suggestion....can't seem to get it to work. Here's my code, if you have any suggestions.....(particle class the same as before) - see OpenProcessing link above.

Code:
float force=100; //attraction/repulsion force
particle[] particles;
int numparticles=2;
float dragfactor=0.50; //stop speeds from accumumulating too much
int selectedindex=-1; // index of the currently selected particle -1=none
float[] lastxpos;
float[] lastypos;

void setup()
{
 size(800,800);
 background(0);
 stroke(255);
 strokeWeight(1);
 noFill();
 smooth();
 lastxpos= new float[25]; //to store positions for release velocity
 lastypos = new float[25];
 //frameRate(30);
 particles = new particle[numparticles];
 for(int i=0; i<numparticles; i++)
 {
   if (i%2==0) particles[i] = new particle(random(width/10, 9*width/10), random(height/10, 9*height/10), 1, 0, 0);
   else particles[i]= new particle(random(width/10, 9*width/10), random(height/10, 9*height/10), -1, 0, 0);
 }
 if(mousePressed) //to store positions for release velocity
 {
   for(int i=0; i<lastxpos.length; i++)
   {
lastxpos[i]=lastxpos[i-1];
lastypos[i]=lastypos[i-1];
   }
   lastxpos[0]= particles[selectedindex].xpos;
   lastypos[0]= particles[selectedindex].ypos;
 }
}


void draw()
{
 background(0);
 for(int i=0; i<numparticles; i++)
 {
 
   float xaccel=0, yaccel=0;
   for(int j=0; j<numparticles; j++)
   {
float ijdist = dist(particles[i].xpos, particles[i].ypos, particles[j].xpos, particles[j].ypos);
float theta = atan2(particles[i].ypos-particles[j].ypos, particles[i].xpos-particles[j].xpos);
 

 
 if(ijdist>20) //attractive or repulsive forces depending on charges
 {
   xaccel+=  particles[i].charge * particles[j].charge * (force/(ijdist*ijdist)) * cos(theta);
   yaccel+=  particles[i].charge * particles[j].charge * (force/(ijdist*ijdist)) * sin(theta);
 }
 
 else if(ijdist>0.1)
 {
   xaccel+=  (force/(pow(ijdist,4))) * cos(theta);
   yaccel+=  (force/(pow(ijdist,4))) * sin(theta);
 }
 
 
 particles[i].xspeed+=xaccel;
 particles[i].yspeed+=yaccel;
  }
  particles[i].move();
  particles[i].render();
 }

}

void mousePressed()
{
  for(int i=0; i<numparticles; i++)
  {
    if (dist(mouseX, mouseY, particles[i].xpos, particles[i].ypos)<8)
    {
selectedindex=i;
break;
    }
  }
 
  if (selectedindex==-1)
  {
    float randno= (int)random(0, 2);
    if (randno==0)
    {
particles = (particle[])append(particles, new particle(mouseX, mouseY, 1, 0, 0));
    }
    else particles= (particle[])append(particles, new particle(mouseX, mouseY, -1, 0, 0));
    numparticles++;
  }
  else
  {
    for(int i=0; i<lastxpos.length; i++)
    {
lastxpos[i]=particles[selectedindex].xpos;
lastypos[i]=particles[selectedindex].ypos;
//when mouse pressed set all values of arrays to current position
    }
  }
}

void mouseDragged()
{
  if(selectedindex!=-1)
  {
    particles[selectedindex].xpos=mouseX;
    particles[selectedindex].ypos=mouseY;
  }  
}

void mouseReleased()
{
 if(selectedindex!=-1)
 {
   particles[selectedindex].xspeed=(lastxpos[0]-lastxpos[24])/25;
   particles[selectedindex].yspeed=(lastypos[0]-lastypos[24])/25;
 }
 selectedindex=-1;
}
Re: Charged Particles
Reply #13 - Dec 13th, 2009, 3:40pm
 
this example is old code and could probably be improved somewhat, but there's a crude implementation (see mouse handling in main tab) of dragging and 'throwing' based on code from 'Actionscript animation' (a great reference for this kind of thing!).
Re: Charged Particles
Reply #14 - Dec 13th, 2009, 9:45pm
 
Yes....that works fine. Thanks.

I was initially trying to use pmouseX and pmouseY - but didn't work for some reason. Then I got even more complicated with storing arrays of past positions, but that didn't work either.
Pages: 1 2 3