/** * Sigmoid Function Generator * @author Robert John Morton Email * @version 15 December 1997 */ import java.awt.*; import javax.swing.*; import java.awt.image.BufferedImage; public class sigmoid extends JPanel implements Runnable{ private boolean finished=false, // indicates when the curve has been completed firstpass=true; // first pass flag private double k=.025, // non-linearity constant x=0, // input value y=k/4, // output 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, // width of graph (pixels) Y=200, // height of graph (pixels) ph=0, // horizontal pixel positions of previous pass pv=0; // vertical pixel positions of previous pass private long δt=50, // total Time Frame for T update cycle t; // time at which next new cycle is due to begin private Color bg = new Color(0,0,0), // background colour tr = new Color(0,255,128); // trace colour private Font font=new Font("Dialog",Font.PLAIN,12); // annotations font 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 sigmoid() { setBackground(bg); // set applet's background colour // 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 i.setColor(bg); // set background colour of off-screen image i.fillRect(0,0,X,Y); // paint background of off-screen image 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 int Xy = V - 5, // x-coord of axis letters Yx = H + 5; // y-co-ord of axis letters i.setFont(font); // set up the annotation font 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 } public 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 v = V - (int)(s * y); // convert vertical plot to pixels if(firstpass){ ph = h; pv = v; firstpass = false; } i.drawLine(ph,pv,h,v); // do next plot on off-screen image ph = h; // save horizontal pixel positions ready for next pass pv = v; // save verticalpixel positions ready for next pass y += k * y * (1 - y); // advance the output difference equation x += dx; // advance the input value } } 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 the PC too slow for the trace 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 }