/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////*\ This class is an extention of Canvas. Runs its own thread. paint methods cannot be called directly by browser (good) \*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////*/ import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; import java.text.DecimalFormat; //! @brief This class shows the trajectory over as many periods as one likes. /// 1, 2, 4, 8, power-of-two number of periods only! class Trajectory extends Canvas implements Runnable { private Thread myThread; private AFMSimulator afmSim; private BufferedImage image; private BufferedImage surface_image; private Color backgroundColor; private Color textColor; private int surface_periods = 4; private int ind; private final int W = 500, H = 300; private final double INTERVAL = (double) W / AFMConstants.SAMPLES; private final int X_AXIS = H/2 + 100; private int delay = 100; private int zoom = 1000; /* temporary image file */ public Trajectory() { setSize(W, H); afmSim = new AFMSimulator(); afmSim.setParams(AFMApplet.params[0], AFMApplet.params[1], AFMApplet.params[2], AFMApplet.params[3], AFMApplet.params[4], AFMApplet.params[5], AFMApplet.params[6], AFMApplet.params[7], AFMApplet.params[8]); afmSim.resetSim(); image = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB); surface_image = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB); backgroundColor = AFMConstants.BG_color; textColor= AFMConstants.text_color; Graphics back = surface_image.getGraphics(); back.setColor(backgroundColor); back.fillRect(0, 0, W, H); back.setColor(textColor); back.drawString("( x( t ), y( t ) )", 400, 20); ind = 0; AFMApplet.drawSurface(surface_image, afmSim, surface_periods, AFMConstants.surface_color); image.setData(surface_image.getData(new Rectangle(0,0,W,H))); addMouseListener(new MouseCoordListener()); addMouseMotionListener(new MouseCoordListener()); } public Trajectory(int _delay) { this(); delay = _delay; } public void start() { if (myThread != null) stop(); myThread = new Thread(this); myThread.start(); image.setData(surface_image.getData(new Rectangle(0,0,W,H))); }//end start public void reset() { image = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB); Graphics back = image.getGraphics(); back.setColor(backgroundColor); back.fillRect(0, 0, W, H); back.setColor(textColor); back.drawString("( x( t ), y( t ) )", 400, 20); ind = 0; afmSim.setParams(AFMApplet.params[0], AFMApplet.params[1], AFMApplet.params[2], AFMApplet.params[3], AFMApplet.params[4], AFMApplet.params[5], AFMApplet.params[6], AFMApplet.params[7], AFMApplet.params[8]); afmSim.resetSim(); image.setData(surface_image.getData(new Rectangle(0,0,W,H))); } public void resume() { start(); } public void run() { while (myThread != null) { repaint(); try { Thread.sleep(delay); } catch (InterruptedException e) { this.stop(); } } }//end run public void stop() { myThread = null; } public void cleanup() { myThread = null; afmSim = null; image = null; backgroundColor = null; textColor = null; } public AFMSimulator getState() { return afmSim; } public void clear() { image.setData(surface_image.getData(new Rectangle(0,0,W,H))); } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { Graphics back = image.getGraphics(); back.setColor(textColor); back.drawString("( x( t ), y( t ) )", 400, 20); back.setColor(AFMConstants.info_color); back.drawString("Time = " + ind, 20, 290); for (int j = 0; j < AFMConstants.SAMPLES; j += 5*surface_periods) { back.setColor(new Color(0xFF00 + j * 0xFF)); // gives nice colors. On every iteration, // the same indices have the same color int xCoord = (int) (W / 2 + AFMMath.mod(ind, surface_periods) * W / surface_periods + AFMMath.mod(afmSim.getAFM().getX(j), Surface.L) * (double) W / (Surface.L) / surface_periods); if (xCoord >= W) xCoord -= W; /***Changed this... experimenting with Force. Change back to getY(j)***/ int yCoord = AFMApplet.SURFACE_HEIGHT - (int) Math.round(afmSim.getAFM().getY(j) * 500 / surface_periods); back.drawOval(xCoord, yCoord, 1, 1); // used to be x-2, y-2. why? } g.drawImage(image, 0, 0, this); back.setColor(backgroundColor); back.drawString("Time = " + ind, 20, 290); afmSim.getMore(); ind++; if(AFMMath.mod(ind, surface_periods)==0 && !AFMApplet._accumulate2) { image.setData(surface_image.getData(new Rectangle(0,0,W,H))); } }//end paint private class MouseCoordListener implements MouseMotionListener, MouseListener { private String lastInfo = ""; public void mouseDragged(MouseEvent e) { //To change body of implemented methods use File | Settings | File Templates. } public void mouseMoved(MouseEvent event) { Graphics back = image.getGraphics(); double x = event.getPoint().getX(); double y = event.getPoint().getY(); double x_realValue = (double) (x - W / 2) * Surface.L / W; // x_center holds *actual* x center value (in the system, not on the display) if(x_realValue > 1) x_realValue -= 1; double y_realValue = (double) (X_AXIS - y) / zoom; back.setColor(backgroundColor); back.drawString(lastInfo, 20, 270); DecimalFormat dec = new DecimalFormat("0.###"); dec.setMaximumFractionDigits((int)Math.round(AFMMath.log2(zoom/100)) + 4); back.setColor(AFMConstants.info_color); lastInfo = "(" + dec.format(x_realValue) + ", " + dec.format(y_realValue) + ")"; back.drawString(lastInfo, 20, 270); /***ADD CODE HERE***/ } public void mouseClicked(MouseEvent event) { if(AFMApplet.zoomTool.isSelected()) { if (event.getButton() != MouseEvent.BUTTON1) surface_periods *= 2; else surface_periods /= 2; if(surface_periods<1) surface_periods = 1; Graphics back = surface_image.getGraphics(); back.setColor(backgroundColor); back.fillRect(0,0,W,H); AFMApplet.drawSurface(surface_image, afmSim, surface_periods, AFMConstants.surface_color); clear(); repaint(); } } public void mouseEntered(MouseEvent e) { //To change body of implemented methods use File | Settings | File Templates. } public void mouseExited(MouseEvent e) { //To change body of implemented methods use File | Settings | File Templates. } public void mousePressed(MouseEvent e) { //To change body of implemented methods use File | Settings | File Templates. } public void mouseReleased(MouseEvent e) { //To change body of implemented methods use File | Settings | File Templates. } } }//end Trajectory