import java.awt.*; public class BifurcateCanvas extends Canvas implements Runnable { private Bifurcate master; private double xMin, xMax; private double yMin, yMax; private int iter; private int preIter; private int width; private int height; private boolean newImage; private Thread thread = null; private Image offImage = null; private Graphics offGraph = null; private Color backColor = new Color(255,255,170); private Color forgColor = new Color(0,0,170); private Rectangle currentRect; private Dimension currentSize; public BifurcateCanvas(Bifurcate _master, Image _offImage, int _width, int _height, double _xMin, double _xMax, double _yMin, double _yMax, int _iter, int _preIter) { super(); master = _master; offImage = _offImage; setParams(_xMin,_xMax, _yMin, _yMax, _iter, _preIter); width = _width; height = _height; resize(width,height); offGraph = offImage.getGraphics(); start(); } public void start() { if (thread == null) { offGraph.setColor(backColor); offGraph.fillRect(0,0,width,height); offGraph.setColor(Color.black); offGraph.drawRect(0,0,width-1,height-1); offGraph.setColor(forgColor); thread = new Thread(this); thread.setPriority(2); thread.start(); } } public void stop() { if (thread != null) { thread.stop(); thread = null; } } public void setParams(double _xMin, double _xMax, double _yMin, double _yMax, int _iter, int _preIter) { xMin = _xMin; xMax = _xMax; yMin = _yMin; yMax = _yMax; iter = _iter; preIter = _preIter; } static double toWorld(int i, int iMax, double min, double max) { return (max - min) / iMax * ((double)i - iMax) + max; } static int toScreen(double x, int iMax, double min, double max) { return (int)Math.round( iMax / (max - min) * (x - max) + iMax); } public void run() { // for (int ix = 0; ix < width; ix++) for (int ix = width; ix >= 0; ix--) { double mu = toWorld(ix, width,xMin,xMax); double x = 0.5; for (int i = 0; i < preIter; i++) // x = mu * x * (1 - x); x = x*x + mu; for (int i = 0; i < iter; i++) { // x = mu * x * (1 - x); x = x*x + mu; int yCoord = toScreen(x, height, yMax, yMin); offGraph.fillRect(ix,yCoord,1,1); } repaint(); } stop(); } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { g.drawImage(offImage,0,0,null); if (currentRect != null) { Rectangle box = getDrawableRect(currentRect, new Dimension(width, height)); g.setColor(Color.green); g.drawRect(box.x, box.y, box.width - 1, box.height - 1); } } public boolean mouseDown(Event event, int x, int y) { if (x > width) x = width; if (y > height) y = height; currentRect = new Rectangle(x, y, 0, 0); repaint(); return false; } public boolean mouseDrag(Event event, int x, int y) { if (x > width) x = width; if (y > height) y = height; double x1 = toWorld(x, width, xMin, xMax); double x2 = toWorld(currentRect.x, width, xMin, xMax); double y1 = toWorld(y, height, yMax, yMin); double y2 = toWorld(currentRect.y, height, yMax, yMin); String msg = "(" + x2 + "," + y2 + ") - (" + x1 + "," + y1 + ")"; master.showMsg(msg); currentRect.resize(x - currentRect.x, y - currentRect.y); repaint(); return false; } public boolean mouseUp(Event event, int x, int y) { if (x > width) x = width; if (y > height) y = height; currentRect.resize(x - currentRect.x, y - currentRect.y); if ((Math.abs(x - currentRect.x) > 8) && (Math.abs(y - currentRect.y) > 8)) { double x1 = toWorld(x, width, xMin, xMax); double x2 = toWorld(currentRect.x, width, xMin, xMax); if (x1 > x2) { double tmp = x1; x1 = x2; x2 = tmp; } double y1 = toWorld(y, height, yMax, yMin); double y2 = toWorld(currentRect.y, height, yMax, yMin); if (y1 > y2) { double tmp = y1; y1 = y2; y2 = tmp; } stop(); setParams(x1,x2,y1,y2,iter,preIter); master.setControlParams(x1,x2,y1,y2,iter,preIter); start(); } currentRect = null; return false; } public boolean mouseMove(Event e, int x, int y) { if (x > width) x = width; if (y > height) y = height; double xx = toWorld(x, width, xMin, xMax); double yy = toWorld(y, height, yMax, yMin); String msg = "(" + String.valueOf(xx) + " , " + String.valueOf(yy) + ")"; master.showMsg(msg); return true; } Rectangle getDrawableRect(Rectangle originalRect, Dimension drawingArea) { int x = originalRect.x; int y = originalRect.y; int width = originalRect.width; int height = originalRect.height; if (width < 0) { width = 0 - width; x = x - width + 1; if (x < 0) { width += x; x = 0; } } if (height < 0) { height = 0 - height; y = y - height + 1; if (y < 0) { height += y; y = 0; } } if ((x + width) > drawingArea.width) { width = drawingArea.width - x; } if ((y + height) > drawingArea.height) { height = drawingArea.height - y; } return new Rectangle(x, y, width, height); } }