in reply to 3 Dimensional repelling particle simulation

To get a pair of nodes to have an equilibrium distance that they gradually work towards I use springs, not charges. The magnitude of the force on each node is proportional to the (signed) difference between the natural length of the spring and the distance between the two nodes, and the force is directed parallel to the separation vector between them (repulsive if they're too close together and attractive if they're too far apart). Put friction in if you want an equilibrium to be reached. I like making Platonic polyhedra out of elastic and bouncing them around.

Put two like charges in deep space and the distance between them will become very large.

Update: Since it's a non-Perl question anyway, here's the C++ subroutines for the important bit.

// double position[12][3] and double velocity[12][3] are global // arrays of 3D vectors // int edge[0] and int edge[1] are the indices in position[][3] and // velocity[][3] of the two nodes making up this edge, or link // double friction is about 0.9999 // double natural is about 1 void icosahedron::cord(const int *edge) { double s[3], rr; rr=0; for (int i=0; i<3; i++) { s[i]=position[edge[1]][i]-position[edge[0]][i]; rr+=s[i]*s[i]; } if (rr>0) { double strain=spring*(natural/sqrt(rr)-1); for (int i=0; i<3; i++) { rr=strain*s[i]; velocity[edge[0]][i]-=rr; velocity[edge[1]][i]+=rr; } } } //------------------------------------------------- void icosahedron::move() { double *pos,*vel; for (pos=*position, vel=*velocity; pos-*position<36; pos++, vel++) *pos+=*vel; for (vel=*velocity; vel-*velocity<36; vel+=3) *vel*=friction; }
I hope this is helpful.
Update: removed reference to 'fun'. Finite-element analysis is not fun.