/** * Tuned Circuit Attenuation Function Generator * @author Robert John Morton UK-YE572246C * @version 29 October 2007 Traces a graph of a tuned circuit's attenuation of a signal over the range 1000000 to 11000000 Rz (radians per second). Vertical scale is logarithmic and ranges from zero attenuation at the top to the value for the minimum displayed frequency. Resonant frequency of tuned circuit is 6000000 Rz. */ import java.awt.*; import javax.swing.*; import java.awt.image.BufferedImage; public class tuning extends JPanel implements Runnable { private boolean FP=true, // indicates first pass of program finished=false; // indicates when curve has been completed private int X=200, x=0, px=0, // width of graph (pixels), current, prev Y=200, y=0, py=0; // height of graph (pixels) private double W = 6000000, // resonant frequency Rz ~= 954930 Hz B = 5000000, // semi-bandspread of graph (in Rz) Q = 4, // SQUARE of Q of tuned circuit (Q=1/R) M = W - B, P = M / W - W / M, // minimum frequency, minimum reactance R=(B+B+B)/X, // Rz per pixel for horizontal graph axis // vertical scale: dB per pixel K = 20 * Math.log(Math.sqrt(Q * (P * P + 1 / Q))) / Y; private Font // lettering font for applet font=new Font("Dialog",Font.PLAIN,12); private Color tr = new Color(0,255,128), // trace colour bg = new Color(0,0,0); // background colour private BufferedImage I = null; // reference for a Bounce Graph image object private Graphics2D i; // graphics reference for off-screen image private long δt = 50; // total Time Frame for plot update cycle private long t; // time at which next cycle is due to begin private volatile Thread T; // declare a thread reference variable tuning() { setBackground(bg); // set applet's background colour // Create image object on which to draw graph axes I = new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB); i = I.createGraphics(); // get its graphics context i.setColor(bg); // set background colour of off-screen img i.fillRect(0,0,X,Y); // fill with transparent background colour i.setColor(Color.white); // set colour for drawing the graph axes i.drawLine(0,Y-1,X,Y-1); // draw x axis i.drawLine(0,0,0,Y); // draw y axis i.setFont(font); // set up the annotation font i.drawString("kHz",X-30,Y-5); i.drawString("dB",5,10); // print the axis annotations i.setColor(tr); // set colour to paint the trace on image t = System.currentTimeMillis() + δt; //set end of first time frame T = new Thread(this); // create the run thread T.start(); // start the run thread } public void newplot(){ // PLOT THE TUNING CURVE if(x > X || y > Y) // if plot has reached edge of graph finished=true; // set the 'finished' flag else{ // while not finished T graph i.setColor(tr); // set trace colour double p = (R*x + M)/W, q = p - 1/p, // reactance of the tuned circuit Z = Q*(q*q + 1/Q); // square of circuit's impedance @ w // attenuation in y-pixels y = (int)(20 * Math.log(Math.sqrt(Z)) / K); if(FP) { // if this is the first pass of the method px = x; py = y; FP = false; } i.drawLine(px,py,x,y); // do next plot on off-screen image px = x; // advance to next pixel right py = y; x++; } } public void paint(Graphics g){ // set up the graphics g.drawImage(I,14,15,null); // (re)draw from off-screen image I } 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; } } /* Start the program thread by creating the thread object and starting it running. Returns a call to run(). */ public void start() { T = new Thread(this); T.start(); } public void stop() {T = null;} // kill the program thread }