/** * Sigmoid Function Generator using the exponential formula * @author Robert J Morton * @version 28 August 2019 adapted from difference equation version of 15 December 1997 This program was written to determine the ideal value of 'k' for the formula used in the Height Command Channel of the Waypoint Encounter class wpenc.java of the Automatic Global Navigator program movmap.java. */ import java.awt.*; import javax.swing.*; import java.awt.image.BufferedImage; public class sigexp extends JPanel implements Runnable { private boolean finished = false, // indicates when the curve has been completed TypeFlag = false; // set for unipolar presentation private double k = 4.5, // non-linearity constant x = -1, // input value y = -1, // output value δx = .005; // x-increment private int 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 = H + 15, // horizontal co-ordinate of axis letters Yx = V - 10, // vertical co-ordinate of axis letters X = 200, // width (in pixels) of the applet window Y = 200; // height (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 sigexp() { // 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(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 } //set up the graphics (re)draw from the off-screen image I public void paint(Graphics g) { g.drawImage(I,14,15,null); } 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 = (int)(s * y), // convert vertical plot to pixels a = H + h, // simplify pixel co-ordinates b = H - h, c = V - v, d = V + v; y = 2 / (1 + Math.exp(-k * x)) - 1; i.drawLine(a,c,a,c); // do next plot in upper right quadrant x += δx; // advance the input value // System.out.println(""+y); } } public void run() { // run the T thread while(T != null) { // loop while thread is alive // If not yet finished, do the next plot. newplot(); if(!finished) repaint(); // Time left in the current time-frame. long s = t - System.currentTimeMillis(); if(s < 5) s = 5; // in case PC too slow for plotting speed /* 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 }