import java.awt.*; import java.awt.image.*; public class plot extends Canvas { int h[] = null; int v[] = null; int zv = -1; Rectangle r = null; double xmin = 0, xmax = 10, ymin = -1, ymax = 1; double xguess = 0, yguess = 0, xguess2 = 0; int niters = 0; applet2 app; double dxdh = 0; double dydx = 0; double dydv = 0; Image buf = null; public plot(applet2 a) { super(); app = a; setBackground(Color.white); } public void paint(Graphics g2) { set_rect(); if (buf == null) buf = createImage(size().width, size().height); Graphics g = buf.getGraphics(); g.setColor(Color.white); g.fillRect(0, 0, size().width, size().height); g.setColor(Color.blue); g.drawLine(r.x, r.y, r.x, r.y + r.height); g.drawLine(r.x, r.y, r.x - 5, r.y); g.drawLine(r.x, r.y + r.height, r.x - 5, r.y + r.height); String s = format_num(ymax); g.drawString(s, r.x - 7 - g.getFontMetrics().stringWidth(s), r.y + 4); s = format_num(ymin); g.drawString(s, r.x - 7 - g.getFontMetrics().stringWidth(s), r.y + r.height + 4); g.drawLine(r.x, r.y + r.height, r.x + r.width, r.y + r.height); g.drawLine(r.x, r.y + r.height, r.x, r.y + r.height + 5); g.drawLine(r.x + r.width, r.y + r.height, r.x + r.width, r.y + r.height + 5); s = format_num(xmin); g.drawString(s, r.x - g.getFontMetrics().stringWidth(s) / 2, r.y + r.height + 17); s = format_num(xmax); g.drawString(s, r.x + r.width - g.getFontMetrics().stringWidth(s) / 2, r.y + r.height + 17); if (zv >= r.y && zv <= r.y + r.height) { g.drawLine(r.x, zv, r.x + r.width, zv); if (zv >= r.y + 10 && zv <= r.y + r.height - 10) { g.drawLine(r.x - 5, zv, r.x, zv); s = format_num(0); g.drawString(s, r.x - 7 - g.getFontMetrics().stringWidth(s), zv + 4); } } g.drawLine(r.x, r.y, r.x + r.width, r.y); g.drawLine(r.x + r.width, r.y, r.x + r.width, r.y + r.height); if (h != null && v != null) { g.setColor(Color.blue); if (zv >= r.y && zv <= r.y + r.height) g.drawLine(r.x, zv, r.x + r.width, zv); g.setColor(Color.red); for (int i = 0; i < h.length - 1; i ++) { //g.drawLine(h[i], v[i], h[i + 1], v[i + 1]); drawThickLine(g, h[i], v[i], h[i + 1], v[i + 1]); } int hguess2 = (int) (r.x + (xguess2 - xmin) * dxdh); if (hguess2 > r.x && hguess2 < r.x + r.width) { g.setColor(Color.magenta); g.drawLine(hguess2, r.y, hguess2, r.y + r.height); } int hguess = (int) (r.x + (xguess - xmin) * dxdh); if (hguess > r.x && hguess < r.x + r.width) { g.setColor(Color.green); int vguess = (int) (r.y + r.height - (yguess - ymin) * dydv); g.drawLine(hguess, r.y, hguess, r.y + r.height); int h1 = r.x; double y1 = yguess - dydx * (xguess - xmin); int v1 = (int) (r.y + r.height - (y1 - ymin) * dydv); int h2 = r.x + r.width; double y2 = yguess + dydx * (xmax - xguess); int v2 = (int) (r.y + r.height - (y2 - ymin) * dydv); g.drawLine(h1, v1, h2, v2); } if (app.state == 2) xguess = xguess2; g.setColor(Color.black); g.drawString("xn-value: ", r.x + r.width + 10, r.y + 30); g.setColor(Color.green); g.drawString(format_num(xguess, 6), r.x + r.width + 10 + 120, r.y + 30); if (app.state == 2) niters ++; g.setColor(Color.black); g.drawString("n-value: ", r.x + r.width + 10, r.y + 15); g.drawString(String.valueOf(niters), r.x + r.width + 10 + 120, r.y + 15); g.drawString("yn-value: ", r.x + r.width + 10, r.y + 45); g.drawString(format_num(yguess, 6), r.x + r.width + 10 + 120, r.y + 45); g.drawString("Slope at xn: ", r.x + r.width + 10, r.y + 60); g.drawString(format_num(dydx, 6), r.x + r.width + 10 + 120, r.y + 60); if (app.state != 2) { g.drawString("x(n+1)-value: ", r.x + r.width + 10, r.y + 75); g.setColor(Color.magenta); g.drawString(format_num(xguess2, 6), r.x + r.width + 10 + 120, r.y + 75); } g.setColor(Color.black); if (app.state == 1) g.drawString("- Running -", r.x + r.width + 10, r.y + 90); else if (app.state == 2) g.drawString("- Done -", r.x + r.width + 10, r.y + 75); } g2.drawImage(buf, 0, 0, this); } public void update(Graphics g) { paint(g); } void drawThickLine(Graphics g, int x0, int y0, int x1, int y1) { g.drawLine(x0, y0, x1, y1); g.drawLine(x0 + 1, y0, x1 + 1, y1); g.drawLine(x0, y0 + 1, x1, y1 + 1); g.drawLine(x0 + 1, y0 + 1, x1 + 1, y1 + 1); } public void reset(double x[], double y[], double xg) { set_rect(); h = new int[x.length]; xmin = x[0]; xmax = x[0]; for (int i = 0; i < x.length; i ++) if (x[i] > xmax) xmax = x[i]; else if (x[i] < xmin) xmin = x[i]; dxdh = (r.width - 1) / (xmax - xmin); for (int i = 0; i < x.length; i ++) h[i] = (int) (r.x + (x[i] - xmin) * dxdh); v = new int[x.length]; ymin = y[0]; ymax = y[0]; for (int i = 0; i < x.length; i ++) if (y[i] > ymax) ymax = y[i]; else if (y[i] < ymin) ymin = y[i]; if (ymin == ymax) { ymin -= 1; ymax += 1; } dydv = (r.height - 1) / (ymax - ymin); for (int i = 0; i < x.length; i ++) v[i] = (int) (r.y + r.height - 1 - (y[i] - ymin) * dydv); zv = (int) (r.y + r.height - (0 - ymin) * dydv); niters = 0; xguess = xg; yguess = app.p.eval(xguess); dydx = get_deriv(xguess); if (dydx != 0) xguess2 = xguess - yguess / dydx; else xguess2 = xguess; repaint(); } public void step() { niters ++; xguess = xguess2; yguess = app.p.eval(xguess); dydx = get_deriv(xguess); if (dydx != 0) xguess2 = xguess - yguess / dydx; else xguess2 = xguess; repaint(); } double get_deriv(double x) { double dx = (xmax - xmin) / 1000.0; if (dx > 0.001) dx = 0.001; double x1 = x - dx; double x2 = x + dx; double y1 = app.p.eval(x1); double y2 = app.p.eval(x2); return (y2 - y1) / (2 * dx); } void set_rect() { r = new Rectangle(80, 10, size().width / 2 - 10, size().height - 30); } String truncate_num(double x, int maxc) { String s = String.valueOf(x); String s2 = ""; int dec = 0; int count = 0; for (int i = 0; i < s.length(); i ++) { char c = s.charAt(i); if (c == '.') dec = 1; else if (Character.isDigit(c)) { if (dec == 1) { if (count >= maxc) continue; count ++; } } else dec = 0; if (!(c == '.' && maxc == 0)) s2 += c; } return s2; } String format_num(double x) { return format_num(x, 3); } String format_num(double x, int maxc) { double y = x; if (Double.isInfinite(y)) return new String("INF"); if (Double.isNaN(y)) return new String("NaN"); if (y == 0.0) return new String("0"); // no trailing zeros if (maxc < 0) maxc = 0; //double factor = Math.pow(10.0, (double) maxc); long factor = 1; for (int i = 0; i < maxc; i ++) factor *= 10; y = Math.rint(y * factor) / factor; return truncate_num(y, maxc); } public Dimension minimumSize() { Dimension d = getParent().size(); return new Dimension(d.width, (int) (d.height * 0.6)); } public Dimension preferredSize() { Dimension d = getParent().size(); return new Dimension(d.width, (int) (d.height * 0.6)); } }