Code (Java, Processing) for video "Video_70_Spin-Off#2" @Vimeo.
Walter Gorgosilits (Dextro.org), 2016.
For research only. No commercial or military use. ;-)


//initiating parameters and lists (only once, at the beginning):
float aa = 1920;//image width
float bb = 1200;//image height
int num = 100000;//number of particles
float[] xli = new float[num];//list for x-position
float[] yli = new float[num];//list for y-position
float[] xcli = new float[num];//list for remembering last x-position
float[] ycli = new float[num];//list for remembering last y-position
float[] wli = new float[num];//list for angle of movement
float[] sli = new float[num];//list for speed
float ww, xx, yy, dd, ff, xxc, yyc, ss, xi, yi, dx, dy, fff, ddd;//other variables needed
int[] colli = new int[num];//list for storing color
void setup() {//setting up stage and lists (only once, at the beginning)
size(1920, 1200);
background(128);
frameRate(125);
smooth();
//place particles randomly yet separated by color, attribute random speeds and directions to them:
for (int n = 0; n < num; n++) {
wli[n] = random(360);
if (random(100) < 50) {
xli[n] = random(aa/2);
colli[n] = 1;
} else {
xli[n] = random(aa/2) +aa/2;
colli[n] = -1;
}
yli[n] = random(bb*3)-bb;
xcli[n] = xli[n];
ycli[n] = yli[n];
sli[n] = 0.1;
}
fff = 1000;//factor for the attraction/repulsion
}
void draw() {//doing the calculations (iterating continuously, and without changing the code at any time)
//fading out partially the previous images (by 4%)
noStroke();
fill(128, 10);
rect(0, 0, aa, bb);
noFill();
fff = max(1, fff*0.9);//factor for the attraction/repulsion, fading in slowly
//apply to all particles:
for (int n = 0; n < num; n++) {
//read out of lists the previous values for position, speed and direction
xx = xli[n];
yy = yli[n];
xxc = xcli[n];
yyc = ycli[n];
ww = wli[n];
ss = sli[n];
//apply movement resulting from last iteration:
xx = xx +cos(ww*PI/180)*ss;
yy = yy +sin(ww*PI/180)*ss;
//check distance to all other particles, and, if close enough, repulse and/or attract them:
for (int i = 0; i < num; i++) {
if (i != n) {
xi = xli[i];
yi = yli[i];
//measuring distance (unnecessarily complicated but robust code, independent from Processing's syntax)
dx = (xx -xi);
dy = (yy -yi);
dd = sqrt(dx*dx +dy*dy);
//keeping a minimum distance...
//...by repulsing if closer than 10... 		(A)
if (dd <= 10) {
ddd = max(1, dd);
ff = 1/(ddd*ddd);
xx = xx +(xx -xi)*ff;
yy = yy +(yy -yi)*ff;
} else {//...and attracting if closer than 20	(B)
if (dd < 20) {
ddd = max(1, dd);
ddd = max(200000, ddd*ddd*ddd);
xx = xx -(xx -xi)/ddd;
yy = yy -(yy -yi)/ddd;
}
}
//dealing with the other color:			(C, which consists only of the following three lines and is solely responsible for all movement after the first five seconds or so)
if ((colli[n] != colli[i]) && (dd < abs(n-num/2)/10) && (dd < 200)) {
xx = xx -(xx -xi)/ddd/100/fff;
yy = yy -(yy -yi)/ddd/100/fff;
}   
}
}
//sum up all vectors: (again, unnecessarily complicated but robust code, independent from Processing's syntax)
dx = (xxc -xx);
dy = (yyc -yy);
ss = sqrt(dx*dx +dy*dy);
if (dx == 0) {dx = 0.001;}
if (dy == 0) {dy = 0.001;}
if ((dx > 0) && (dy > 0)) {ww = atan(dy/dx)*(180/PI) +180;}
if ((dx < 0) && (dy > 0)) {ww = atan(dy/dx)*(180/PI) +360;}
if ((dx < 0) && (dy < 0)) {ww = atan(dy/dx)*(180/PI);}
if ((dx > 0) && (dy < 0)) {ww = atan(dy/dx)*(180/PI) +180;} 
//reset anyone who ventured out of format:
if ((xx > aa +10) || (xx < -10) || (yy < -10) || (yy > bb +10)) {
if (colli[n] == 1) {
xx = random(aa/2);
} else {
xx = random(aa/2) +aa/2;
}
yy = random(bb);
}
//store new values in lists
xli[n] = xx;
yli[n] = yy;
wli[n] = ww;
sli[n] = ss*0.9;
xcli[n] = xli[n];
ycli[n] = yli[n];
//draw...
stroke(max(0, colli[n])*255, 128);
strokeWeight(1);
point(xx, yy);//...a point at the current position...
strokeWeight(0.5);
line(xx, yy, xxc, yyc);//...and a line between the current and the previous position
}
//save image, later to be combined to form the video:
saveFrame();
}