/** * Sigmoid Function Generator * @author Robert J Morton * @version 15 December 1997 */ import java.awt.*; import javax.swing.*; import java.awt.image.BufferedImage; public class sigfun extends JPanel implements Runnable { private boolean finished = false, // indicates when the curve has been completed TypeFlag = false; // set for unipolar presentation private double k = .025, // non-linearity constant y = k / 4, // output value x = 0, // input value dx = k / 10; // T (or look-up table) increment private int s = 200, // pixels per unit real (scaling factor) H = 0, // horizontal window co-ordinate of graphical origin V = s - 1, // vertical window co-ordinate of graphical origin X = 200, // x-extent (in pixels) of the applet window Y = 200; // y-extent (in pixels) of the applet window private long t, // time at which the next new cycle is due to begin δt = 50; // total Time Frame for T update cycle private Font font = new Font("Dialog",Font.PLAIN,12); // for annotations private Color tr = new Color(0,255,128); // trace colour private BufferedImage I = null; // reference for a Graph image object private Graphics2D i; // graphics reference for off-screen image private volatile Thread T; // thread reference variable sigfun(boolean b) { TypeFlag = b; // false = monopolar; true = bipolar trace int Xy = V - 5, // x-coord of axis letters Yx = H + 5; // y-coord of axis letters // Create image object on which to draw graph axes I = new BufferedImage(X,Y,BufferedImage.TYPE_INT_RGB); i = I.createGraphics(); // get its graphics context if(TypeFlag){ // if doing a bipolar trace, k = 0.011; // non-linearity constant x = 0; // input value y = 0; // output value dx = .0025; // T (or look-up table) increment s = 100; // pixels per unit real (scaling factor) H = 100; // horizontal window co-ordinate of graphical origin V = 100; // vertical window co-ordinate of graphical origin Xy = V + 15; // x-coord of axis letters Yx = H - 10; // y-coord of axis letters } i.setColor(Color.black); // background colour for off-screen image i.fillRect(0,0,X,Y); // paint background of off-screen image i.setFont(font); // set up the annotation font i.setColor(Color.white); // set colour for drawing the graph axes i.drawLine(0,V,X,V); // draw x axis i.drawLine(H,0,H,Y); // draw y axis i.drawString("X",X - 10,Xy); i.drawString("Y",Yx,10); // print the X and Y axis letters i.setColor(tr); // set colour to paint the trace on image // Set end time for first update time frame t = System.currentTimeMillis() + δt; T = new Thread(this); // create the run thread T.start(); // start the run thread } public void paint(Graphics g) { // set up the graphics g.drawImage(I,14,15,null); // (re)draw from the off-screen image I } void newplot() { // PLOT THE SIGMOID GRAPH if(x > 1 || y > 1) // if plot has reached edge of graph finished = true; // set the 'finished' flag else { // if not yet finished T graph int h = (int)(s * x); // convert horizontal plot to pixels int v = (int)(s * y); // convert vertical plot to pixels int a = h, // simplify pixel co-ordinates b, c = V - v, d; if(TypeFlag) { a = H - h; // simplify pixel co-ordinates b = H + h; c = V + v; d = V - v; i.drawLine(b,d,b,d); // do next plot in lower left quadrant y += k * (1 - y); // advance the output difference equation } else y += k * y * (1 - y); // advance the output difference equation x += dx; // advance the input value i.drawLine(a,c,a,c); // do next plot in upper right quadrant } } public void run(){ // run the T thread while(T != null){ // loop while thread is alive newplot(); if(!finished) // If not yet finished, repaint(); // do the next plot. // Time left in the current time-frame. long s = t - System.currentTimeMillis(); if(s < 5) // in case PC too slow for plotting speed s = 5; /* Sleep for the remainder of the time-frame, while allowing external events to interrupt the thread. */ try {T.sleep(s);} catch (InterruptedException e) {} // Set the finishing pass of the next time frame. t = System.currentTimeMillis() + δt; } } public void stop() {T = null;} // kill the program thread }