// DO NOT REPRODUCE WITHOUT PERMISSION - HMC JULY 2000 /* This applet illustrates the behaviour of a simple self-organizing map in organizing three-dimensional data. The data consist of randomly-generated triples of values of r, theta and phi, where the range of r is 0-355, theta is 0-8 and phi 0-3. These data are then used to calculate values for the Cartesian coordinates x, y and z. At each node in the map, a triplet of weights is stored. When the applet draws to the screen, a blob is placed at the coordinates of the node, drawn in a colour determined by (x, y, z), the weights developed at each node HMC July 2000. */ import java.applet.*; import java.awt.*; import java.util.Random; public class coloursom extends Applet implements Runnable { double som_weights[][][] = new double[30][30][3]; double a,xa,ya,za,mult1,mult2,adjustment,diff,bestdiff,scale,rubble; double r,theta,phi,complexity; int i,j,k,l,w,h,besti,bestj,cycle,mapsize,mapsize1,nodex,nodey; boolean paused, show_weights; boolean please_stop=false; Random rs = new Random(); Choice choice; Button pausebutton,resetbutton; Font font; Image offscreen; int imagewidth, imageheight; Thread animator = null; public void init() { // Make the font and widgets font = new Font("Helvetica", Font.BOLD, 16); resetbutton=new Button(" Reset "); this.add(resetbutton); choice = new Choice(); choice.add("Adjust parameters....."); choice.add("Mapsize: 10 x 10"); choice.add("Mapsize: 20 x 20"); choice.add("Mapsize: 30 x 30"); choice.add("Data complexity: 1"); choice.add("Data complexity: 1.5"); choice.add("Data complexity: 3"); choice.add("Data complexity: 5"); complexity=1.0; this.add(choice); pausebutton = new Button(" Start "); pausebutton.setForeground(Color.red); this.add(pausebutton); // Initialize miscellaneous values paused=true; show_weights=false; rubble=1000.0; mapsize=30; restart(); } public void restart() { // Initialize the node weights with random values between 1 and mapsize cycle=0; mapsize1=mapsize-1; scale=400.0/mapsize; for (i=0; i50 && e.x < 350 && e.y>50 && e.y<350) { // Find which node the mouse has been clicked on nodex=(int)(((e.x-50)/300.0)*mapsize); nodey=(int)(((e.y-50)/300.0)*mapsize); } show_weights=true; return true; } } } super.handleEvent(e); return true; } public void paint(Graphics g) { Dimension size = this.size(); w=size.width; h=size.height; g.setColor(Color.white); g.fillRect(0, 0, w, h); g.setColor(Color.blue); g.fillRect(48,48,304,304); g.setColor(new Color(140,117,128)); g.fillRect(49,49,303,302); g.setFont(font); g.drawString("Cycle " + cycle, 40,375); if (show_weights) { double wx,wy,wz; wx=((int)(som_weights[nodex][nodey][0]*10))/10.0; wy=((int)(som_weights[nodex][nodey][1]*10))/10.0; wz=((int)(som_weights[nodex][nodey][2]*10))/10.0; g.drawString("Node (" + nodex + "," + nodey + "): " + wx + " " + wy + " " + wz, 150, 375); } cycle++; // Cycle through all nodes, drawing them in the appropriate colour int jmul=300/mapsize; int c1,c2,c3; for (i=0; i=0 && i=0 && jbesti-2 && ibestj-2 && j