This applet was created from the algorithm described in the article "Blobs" in Hugi 21

 

import java.awt.*;
import javax.swing.*;
import java.applet.*;
import java.util.*;
import java.awt.image.*;

public class blobs extends Applet implements Runnable{

static Random rand = new Random();
Thread aThread=null;
private Image TargetImage=null;
private int TargetPixel[];
private MemoryImageSource mis;
int x,y;
private long msStart, msNow, msDiff, lFrames=0;
float[][] screen;
int[][][] blob;
int h,w;
int blobs;
private ColorModel cm=ColorModel.getRGBdefault();

public void start(){
	if (aThread == null){
		aThread = new Thread(this);
		aThread.start();
	}
}


	
public void run(){
		while(true){
			repaint();
			try{
				aThread.sleep(50);
			}
			catch (InterruptedException e){

			}
		}
}

public void paint(Graphics g){	
	  	
}

public void update(Graphics g) {
	float distance=0;	
	int index=0;	
	int colour=0;	
	for (int i=0; i<h*w; i++){
		TargetPixel[i]=0xff000000;
	}
	
	for (int i=0;i<blob.length;i++){
		if (blob[i][0][0]>w){ blob[i][0][1]=-blob[i][0][1]; }
		else if (blob[i][0][0]<0){ blob[i][0][1]=-blob[i][0][1]; }
		if (blob[i][1][0]>h){ blob[i][1][1]=-blob[i][1][1]; }
		else if (blob[i][1][0]<0){ blob[i][1][1]=-blob[i][1][1]; }
		blob[i][0][0]+=blob[i][0][1];
		blob[i][1][0]+=blob[i][1][1];
	}
	for (int i=0;i<w;i++){
		for (int j=0;j<h;j++){
			screen[i][j]=0;
			index++;
			for (int k=0;k<blob.length;k++){
				distance=(float)((blob[k][0][0]-i)*(blob[k][0][0]-i)+
                               (blob[k][1][0]-j)*(blob[k][1][0]-j));
				screen[i][j]+=(1/distance);
				if (screen[i][j]>0.001){
					colour=(int)(screen[i][j]*0xfffff%0xffff);
					TargetPixel[index] =   0xff000000+colour;
				}
			}			
		}
	}
  	lFrames++;			
	mis.newPixels();	
	g.drawImage(TargetImage,0,0,this);
        msNow = System.currentTimeMillis();
        msDiff = msNow - msStart;
        showStatus( "FPS: " + (lFrames  * 1000 / msDiff));	
}

public void init() {     
	w=size().width;
	h=size().height;
	TargetPixel=new int[w*h];
	mis=new MemoryImageSource(w,h,cm,TargetPixel,0,w);
	mis.setAnimated(true);
	mis.setFullBufferUpdates(true);		
	TargetImage=createImage(mis);		
	blobs=6;
	screen=new float[w][h];
	blob=new int[blobs][blobs][blobs];
	for (int i=0;i<blobs;i++){
		blob[i][0][0]=Math.abs(rand.nextInt())%w;;
		blob[i][1][0]=Math.abs(rand.nextInt())%h;;
		blob[i][0][1]=-5+Math.abs(rand.nextInt())%10;
		blob[i][1][1]=-5+Math.abs(rand.nextInt())%10;
	}	
	msStart = System.currentTimeMillis();		
}     
}