diff --git a/org/obrienscience/fractal/AnimApplet2.java b/src/main/java/org/obrienscience/fractal/AnimApplet2.java old mode 100755 new mode 100644 similarity index 97% rename from org/obrienscience/fractal/AnimApplet2.java rename to src/main/java/org/obrienscience/fractal/AnimApplet2.java index a44593f..4139e88 --- a/org/obrienscience/fractal/AnimApplet2.java +++ b/src/main/java/org/obrienscience/fractal/AnimApplet2.java @@ -1,255 +1,255 @@ -package org.obrienscience.fractal; - -import java.applet.Applet; -import java.awt.AWTEvent; -import java.awt.Color; -import java.awt.Frame; -import java.awt.Graphics; -import java.awt.Image; -import java.awt.MenuItem; -import java.awt.PopupMenu; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; - -public abstract class AnimApplet2 extends Applet implements MouseListener, MouseMotionListener, ActionListener { - private static final long serialVersionUID = -5412190348711102401L; - public static final String MAX_HEIGHT = "1024"; - public static final String MAX_WIDTH = "1024"; - /** we are running as an applet unless we enter main() */ - private static boolean isApplet = true; - - // vars used to blink objects - protected boolean bvOddFrame = true; - protected int ivFrameCount = 0; - protected int ivFrameFlipCount = 10; - protected int ivFrames = 0; - protected int xPos, yPos = 0; - protected String eventString; - protected int counter = 0; - - //protected static int izMaxWidth, izMaxHeight, izSleepTime = 1; // milliseconds to sleep - protected static int izMaxWidth, izMaxHeight = 1; // milliseconds to sleep - // private custom objects - - // The next two objects are for double-buffering - protected Graphics gContext; // off-screen graphics context - protected Image buffer; // buffer in which to draw image - - // popup menu - protected String svPopupNames[] = { "Erase", "Reset", "Randomize" }; - protected MenuItem thePopupMenuItems[]; - protected PopupMenu aPopupMenu; - - private int originXPixel; - private int originYPixel; - private int radiusX; - private int radiusY; - private int extentX; - private int extentY; - - // load the images when the applet begins executing - @Override - public void init() { - //this.genericInit(); - // applet listen for mouse events, ok - addMouseListener(this); - addMouseMotionListener(this); - if (isApplet) { - String maxHeight = getParameter("maxHeight"); - if(null == maxHeight || maxHeight.length() < 1) { - maxHeight = MAX_HEIGHT; - } - String maxWidth = getParameter("maxWidth"); - if(null == maxWidth || maxWidth.length() < 1) { - maxWidth = MAX_WIDTH; - } - izMaxHeight = Integer.parseInt(maxHeight); - izMaxWidth = Integer.parseInt(maxWidth); - } - - // create popup menu - aPopupMenu = new PopupMenu("Popup"); - thePopupMenuItems = new MenuItem[svPopupNames.length]; - - for (int i = 0; i < svPopupNames.length; i++) { - thePopupMenuItems[i] = new MenuItem(svPopupNames[i]); - aPopupMenu.add(thePopupMenuItems[i]); - thePopupMenuItems[i].addActionListener(this); - } - - // add popup menu to this canvas - add(aPopupMenu); - enableEvents(AWTEvent.MOUSE_EVENT_MASK); - - // create graphics subsystem - buffer = createImage(izMaxWidth, izMaxHeight); // create image buffer - gContext = buffer.getGraphics(); // get graphics context - - // set background of buffer to black - gContext.setColor(Color.black); - gContext.fillRect(0, 0, izMaxWidth, izMaxHeight + 30); - } - - private void setValues(String event, int x, int y) { - eventString = event; - xPos = x; - yPos = y; // repaint(); - } - - @Override - public void mouseClicked(MouseEvent e) { - setValues("Clicked", e.getX(), e.getY()); - } - - @Override - public void mousePressed(MouseEvent e) { - setValues("Pressed", e.getX(), e.getY()); - } - - @Override - public void mouseReleased(MouseEvent e) { - setValues("Released", e.getX(), e.getY()); - } - - @Override - public void mouseEntered(MouseEvent e) { - setValues("Entered", e.getX(), e.getY()); - } - - @Override - public void mouseExited(MouseEvent e) { - setValues("Exited", e.getX(), e.getY()); - } - - @Override - public void mouseDragged(MouseEvent e) { - setValues("Dragging", e.getX(), e.getY()); - } - - @Override - public void mouseMoved(MouseEvent e) { - setValues("Moving", e.getX(), e.getY()); - } - - // capture popup menu event - @Override - public void processMouseEvent(MouseEvent e) { - if (e.isPopupTrigger()) - aPopupMenu.show(this, e.getX(), e.getY()); - super.processMouseEvent(e); - } - - // process popup menu event - @Override - public void actionPerformed(ActionEvent e) { - // "Erase" - if (e.getSource() == thePopupMenuItems[0]) { } - - // "Reset" - if (e.getSource() == thePopupMenuItems[1]) { - init(); - } - - // "Randomize" - if (e.getSource() == thePopupMenuItems[2]) { } - } - - // start the applet - @Override - public void start() { } - - // stop the applet - @Override - public void stop() { } - - // display the image in the Applet's Graphics context - @Override - public void paint(Graphics g) { - g.drawImage(buffer, 0, 0, this); - // clear previous image from buffer - if(null != gContext) { // image may not be ready - gContext.setColor(Color.black); - gContext.fillRect(0, 0, izMaxWidth, izMaxHeight); - - // update frame and frameflip count - ivFrames++; - if (ivFrameCount < ivFrameFlipCount) { - bvOddFrame = false; - ivFrameCount++; - } else { - if (ivFrameCount < ivFrameFlipCount * 2) { - bvOddFrame = true; - ivFrameCount++; - } else { - bvOddFrame = false; - ivFrameCount = 0; - } - } - } - - try { - Thread.sleep(1); - } catch (InterruptedException e) { - showStatus(e.toString()); - } - repaint(); // display buffered image - } - - // override update to eliminate flicker - @Override - public void update(Graphics g) { - paint(g); - } - - public abstract void genericInit(); - - public void applicationInit() { - isApplet = false; - izMaxHeight = 1024;//384; // try to use a power of 2 - izMaxWidth = 1024;//384; - setOriginXPixel(izMaxWidth >> 1); - setOriginYPixel(izMaxHeight >> 1); - setRadiusX(izMaxWidth >> 1); - setRadiusY(izMaxHeight >> 1); - setExtentX(izMaxWidth); - setExtentY(izMaxHeight); - this.genericInit(); - - Frame aFrame = new Frame("Mandelbrot (c) 2013 F.Michael O'Brien"); - //AnimApplet2 anApplet = new AnimApplet2(); - aFrame.add("Center", this); - aFrame.setSize(izMaxWidth + 10, izMaxHeight + 30); - //aFrame.show(); - aFrame.setVisible(true); - this.init(); - this.start(); - } - -/* // allow application use outside of browser, appletviewer - public static void main(String args[]) { - AnimApplet2 anApplet = new AnimApplet2(); - anApplet.applicationInit(); - }*/ - - @Override - public String getAppletInfo() { - return "(2011) Written by F.Michael O'Brien"; - } - - public int getOriginXPixel() { return originXPixel; } - public void setOriginXPixel(int originXPixel) { this.originXPixel = originXPixel; } - public int getOriginYPixel() { return originYPixel; } - public void setOriginYPixel(int originYPixel) { this.originYPixel = originYPixel; } - public int getRadiusX() { return radiusX; } - public void setRadiusX(int radiusX) { this.radiusX = radiusX; } - public int getRadiusY() { return radiusY; } - public void setRadiusY(int radiusY) { this.radiusY = radiusY; } - public int getExtentX() { return extentX; } - public void setExtentX(int extentX) { this.extentX = extentX; } - public int getExtentY() { return extentY; } - public void setExtentY(int extentY) { this.extentY = extentY; } - public Graphics getgContext() { return gContext; } -} +package org.obrienscience.fractal; + +import java.applet.Applet; +import java.awt.AWTEvent; +import java.awt.Color; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + +public abstract class AnimApplet2 extends Applet implements MouseListener, MouseMotionListener, ActionListener { + private static final long serialVersionUID = -5412190348711102401L; + public static final String MAX_HEIGHT = "1024"; + public static final String MAX_WIDTH = "1024"; + /** we are running as an applet unless we enter main() */ + private static boolean isApplet = true; + + // vars used to blink objects + protected boolean bvOddFrame = true; + protected int ivFrameCount = 0; + protected int ivFrameFlipCount = 10; + protected int ivFrames = 0; + protected int xPos, yPos = 0; + protected String eventString; + protected int counter = 0; + + //protected static int izMaxWidth, izMaxHeight, izSleepTime = 1; // milliseconds to sleep + protected static int izMaxWidth, izMaxHeight = 1; // milliseconds to sleep + // private custom objects + + // The next two objects are for double-buffering + protected Graphics gContext; // off-screen graphics context + protected Image buffer; // buffer in which to draw image + + // popup menu + protected String svPopupNames[] = { "Erase", "Reset", "Randomize" }; + protected MenuItem thePopupMenuItems[]; + protected PopupMenu aPopupMenu; + + private int originXPixel; + private int originYPixel; + private int radiusX; + private int radiusY; + private int extentX; + private int extentY; + + // load the images when the applet begins executing + @Override + public void init() { + //this.genericInit(); + // applet listen for mouse events, ok + addMouseListener(this); + addMouseMotionListener(this); + if (isApplet) { + String maxHeight = getParameter("maxHeight"); + if(null == maxHeight || maxHeight.length() < 1) { + maxHeight = MAX_HEIGHT; + } + String maxWidth = getParameter("maxWidth"); + if(null == maxWidth || maxWidth.length() < 1) { + maxWidth = MAX_WIDTH; + } + izMaxHeight = Integer.parseInt(maxHeight); + izMaxWidth = Integer.parseInt(maxWidth); + } + + // create popup menu + aPopupMenu = new PopupMenu("Popup"); + thePopupMenuItems = new MenuItem[svPopupNames.length]; + + for (int i = 0; i < svPopupNames.length; i++) { + thePopupMenuItems[i] = new MenuItem(svPopupNames[i]); + aPopupMenu.add(thePopupMenuItems[i]); + thePopupMenuItems[i].addActionListener(this); + } + + // add popup menu to this canvas + add(aPopupMenu); + enableEvents(AWTEvent.MOUSE_EVENT_MASK); + + // create graphics subsystem + buffer = createImage(izMaxWidth, izMaxHeight); // create image buffer + gContext = buffer.getGraphics(); // get graphics context + + // set background of buffer to black + gContext.setColor(Color.black); + gContext.fillRect(0, 0, izMaxWidth, izMaxHeight + 30); + } + + private void setValues(String event, int x, int y) { + eventString = event; + xPos = x; + yPos = y; // repaint(); + } + + @Override + public void mouseClicked(MouseEvent e) { + setValues("Clicked", e.getX(), e.getY()); + } + + @Override + public void mousePressed(MouseEvent e) { + setValues("Pressed", e.getX(), e.getY()); + } + + @Override + public void mouseReleased(MouseEvent e) { + setValues("Released", e.getX(), e.getY()); + } + + @Override + public void mouseEntered(MouseEvent e) { + setValues("Entered", e.getX(), e.getY()); + } + + @Override + public void mouseExited(MouseEvent e) { + setValues("Exited", e.getX(), e.getY()); + } + + @Override + public void mouseDragged(MouseEvent e) { + setValues("Dragging", e.getX(), e.getY()); + } + + @Override + public void mouseMoved(MouseEvent e) { + setValues("Moving", e.getX(), e.getY()); + } + + // capture popup menu event + @Override + public void processMouseEvent(MouseEvent e) { + if (e.isPopupTrigger()) + aPopupMenu.show(this, e.getX(), e.getY()); + super.processMouseEvent(e); + } + + // process popup menu event + @Override + public void actionPerformed(ActionEvent e) { + // "Erase" + if (e.getSource() == thePopupMenuItems[0]) { } + + // "Reset" + if (e.getSource() == thePopupMenuItems[1]) { + init(); + } + + // "Randomize" + if (e.getSource() == thePopupMenuItems[2]) { } + } + + // start the applet + @Override + public void start() { } + + // stop the applet + @Override + public void stop() { } + + // display the image in the Applet's Graphics context + @Override + public void paint(Graphics g) { + g.drawImage(buffer, 0, 0, this); + // clear previous image from buffer + if(null != gContext) { // image may not be ready + gContext.setColor(Color.black); + gContext.fillRect(0, 0, izMaxWidth, izMaxHeight); + + // update frame and frameflip count + ivFrames++; + if (ivFrameCount < ivFrameFlipCount) { + bvOddFrame = false; + ivFrameCount++; + } else { + if (ivFrameCount < ivFrameFlipCount * 2) { + bvOddFrame = true; + ivFrameCount++; + } else { + bvOddFrame = false; + ivFrameCount = 0; + } + } + } + + try { + Thread.sleep(1); + } catch (InterruptedException e) { + showStatus(e.toString()); + } + repaint(); // display buffered image + } + + // override update to eliminate flicker + @Override + public void update(Graphics g) { + paint(g); + } + + public abstract void genericInit(); + + public void applicationInit() { + isApplet = false; + izMaxHeight = 1024;//384; // try to use a power of 2 + izMaxWidth = 1024;//384; + setOriginXPixel(izMaxWidth >> 1); + setOriginYPixel(izMaxHeight >> 1); + setRadiusX(izMaxWidth >> 1); + setRadiusY(izMaxHeight >> 1); + setExtentX(izMaxWidth); + setExtentY(izMaxHeight); + this.genericInit(); + + Frame aFrame = new Frame("Mandelbrot (c) 2013 F.Michael O'Brien"); + //AnimApplet2 anApplet = new AnimApplet2(); + aFrame.add("Center", this); + aFrame.setSize(izMaxWidth + 10, izMaxHeight + 30); + //aFrame.show(); + aFrame.setVisible(true); + this.init(); + this.start(); + } + +/* // allow application use outside of browser, appletviewer + public static void main(String args[]) { + AnimApplet2 anApplet = new AnimApplet2(); + anApplet.applicationInit(); + }*/ + + @Override + public String getAppletInfo() { + return "(2011) Written by F.Michael O'Brien"; + } + + public int getOriginXPixel() { return originXPixel; } + public void setOriginXPixel(int originXPixel) { this.originXPixel = originXPixel; } + public int getOriginYPixel() { return originYPixel; } + public void setOriginYPixel(int originYPixel) { this.originYPixel = originYPixel; } + public int getRadiusX() { return radiusX; } + public void setRadiusX(int radiusX) { this.radiusX = radiusX; } + public int getRadiusY() { return radiusY; } + public void setRadiusY(int radiusY) { this.radiusY = radiusY; } + public int getExtentX() { return extentX; } + public void setExtentX(int extentX) { this.extentX = extentX; } + public int getExtentY() { return extentY; } + public void setExtentY(int extentY) { this.extentY = extentY; } + public Graphics getgContext() { return gContext; } +} diff --git a/org/obrienscience/fractal/Mandelbrot.java b/src/main/java/org/obrienscience/fractal/Mandelbrot.java old mode 100755 new mode 100644 similarity index 97% rename from org/obrienscience/fractal/Mandelbrot.java rename to src/main/java/org/obrienscience/fractal/Mandelbrot.java index 595f33b..788a2af --- a/org/obrienscience/fractal/Mandelbrot.java +++ b/src/main/java/org/obrienscience/fractal/Mandelbrot.java @@ -1,322 +1,322 @@ - -package org.obrienscience.fractal; - -import java.awt.Color; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import java.awt.image.Raster; -import java.io.File; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; - -import javax.imageio.ImageIO; - -// TODO: zoom sequence entity -public class Mandelbrot extends AnimApplet2 { - // There is only the need for one of the following statics - private static final long serialVersionUID = 6502859074457924892L; - /** Get number of (hyperthreaded + real) cores. IE: p630 with HT=2, Core2 E8400=2 and Core i7-920 = 8 */ - public static final int CORES = 32;//Runtime.getRuntime().availableProcessors() << 8; - public static List rgbColors; - public static List currentColors; - private long frame = 1; - - static { - rgbColors = new ArrayList(); - for(int i=0;i<256;i++) { rgbColors.add(new Color(0,0,i)); } - for(int i=0;i<256;i++) { rgbColors.add(new Color(0,i,0)); } - for(int i=0;i<256;i++) { rgbColors.add(new Color(i,0,0)); } - for(int i=0;i<256;i++) { rgbColors.add(new Color(0,i,i)); } - for(int i=0;i<256;i++) { rgbColors.add(new Color(i,0,i)); } - for(int i=0;i<256;i++) { rgbColors.add(new Color(i,i,0)); } - for(int i=0;i<256;i++) { rgbColors.add(new Color(i,i,i)); } - currentColors = rgbColors; - } - - //private int frameNumber = 0; - private double realPerPixelX; - private double realPerPixelY; - private double gridXStart = -2; - private double gridYStart = -1.5; - private double gridXEnd = 1; - private double gridYEnd = 1.5; - //private double gridZoomOffset = 0.01; - private int maximumOrbitPath = 65536;//1791;// 7* 255; - private double maximumOrbitRadius = 2; - private double originalOriginX = 0; - private double originalOriginY = 0; - //private double radiusZoomOffset = 0.0005; - private double radiusZoomFactor = 0.9; - private int direction = -1; - private double radius = 10; - - private List threadCompleteList = new ArrayList(); - private List workUnits = new ArrayList(); - public BufferedImage getBufferedImage() { - return bufferedImage; - } - - public void setBufferedImage(BufferedImage bufferedImage) { - this.bufferedImage = bufferedImage; - } - private BufferedImage bufferedImage; - - - private long startTimestamp; - - //0.001643721971153 + 0.822467633298876i - public void setOrigin(double x, double y) { - originalOriginX = x; - originalOriginY = y; - } - - public void setRadius(double aRadius) { - radius = aRadius; - // compute edges of window - this.setGridXStart(originalOriginX - radius); - this.setGridXEnd(originalOriginX + radius); - this.setGridYStart(originalOriginY - radius); - this.setGridYEnd(originalOriginY + radius); - } - - public void setParameters2(double x, double y, double radius) { - // compute edges of window - this.setGridXStart(x - radius); - this.setGridXEnd(x + radius); - this.setGridYStart(y - radius); - this.setGridYEnd(y + radius); - } - - - /** - * This function is called by the Java2d framework - */ - @Override - public void paint(Graphics g) { - BufferedImage dest = new BufferedImage(izMaxWidth,izMaxHeight, BufferedImage.TYPE_INT_RGB); - setBufferedImage(dest); - g.drawImage(buffer, 0, 0, this); - // clear previous image from buffer - if (null != gContext) { // image may not be ready - //gContext.setColor(Color.black); - //gContext.fillRect(0, 0, izMaxWidth, izMaxHeight); - //displayCurrentSolution(); - - // Repaint only when all threads are complete - boolean threadsFinished = false; - long threadCount = 0; - while(!threadsFinished) { - for(Boolean complete : threadCompleteList) { - if(complete) { - threadCount++; - } - } - if(threadCount == threadCompleteList.size()) { - // all threads finished - lets create new threads and exit/recalculate - threadsFinished = true; - for(int core=0;core 10 && direction > 0) { - radiusZoomFactor = 0.9; - direction = -1; - } - radius = radius * radiusZoomFactor;// - radiusZoomOffset; - setRadius(radius); - } - - private synchronized void addWorkUnits() { - // Setup thread handlers by dividing up the work - for(int core=0;core getThreadCompleteList() { return threadCompleteList; } - public void setThreadCompleteList(List threadCompleteList) { this.threadCompleteList = threadCompleteList; } - public Boolean isThreadComplete(int index) { return threadCompleteList.get(index); } - public void setThreadComplete(int index, Boolean flag) { threadCompleteList.set(index, flag); } - public List getWorkUnits() { return workUnits; } - public void setWorkUnits(List workUnits) { this.workUnits = workUnits; } - public double getRealPerPixelX() { return realPerPixelX; } - public void setRealPerPixelX(double realPerPixelX) { this.realPerPixelX = realPerPixelX; } - public double getRealPerPixelY() { return realPerPixelY; } - public void setRealPerPixelY(double realPerPixelY) { this.realPerPixelY = realPerPixelY; } - public double getGridXStart() { return gridXStart; } - public double getGridYStart() { return gridYStart; } - public double getGridXEnd() { return gridXEnd; } - public double getGridYEnd() { return gridYEnd; } - public int getMaximumOrbitPath() { return maximumOrbitPath; } - public void setMaximumOrbitPath(int maximumOrbitPath) { this.maximumOrbitPath = maximumOrbitPath; } - public double getMaximumOrbitRadius() { return maximumOrbitRadius; } - public void setMaximumOrbitRadius(double maximumOrbitRadius) { this.maximumOrbitRadius = maximumOrbitRadius; } - public static List getCurrentColors() { return currentColors; } - public static void setCurrentColors(List currentColors) { Mandelbrot.currentColors = currentColors; } - public synchronized void setGridXStart(double gridXStart) { - this.gridXStart = gridXStart; - recalculateParameters(); - } - public synchronized void setGridYStart(double gridYStart) { - this.gridYStart = gridYStart; - recalculateParameters(); - } - public synchronized void setGridXEnd(double gridXEnd) { - this.gridXEnd = gridXEnd; - recalculateParameters(); - } - public synchronized void setGridYEnd(double gridYEnd) { - this.gridYEnd = gridYEnd; - recalculateParameters(); - } - - /* - public void displayCurrentSolution() { - double h,v; - int iterations; - for(int x=0;x rgbColors; + public static List currentColors; + private long frame = 1; + + static { + rgbColors = new ArrayList(); + for(int i=0;i<256;i++) { rgbColors.add(new Color(0,0,i)); } + for(int i=0;i<256;i++) { rgbColors.add(new Color(0,i,0)); } + for(int i=0;i<256;i++) { rgbColors.add(new Color(i,0,0)); } + for(int i=0;i<256;i++) { rgbColors.add(new Color(0,i,i)); } + for(int i=0;i<256;i++) { rgbColors.add(new Color(i,0,i)); } + for(int i=0;i<256;i++) { rgbColors.add(new Color(i,i,0)); } + for(int i=0;i<256;i++) { rgbColors.add(new Color(i,i,i)); } + currentColors = rgbColors; + } + + //private int frameNumber = 0; + private double realPerPixelX; + private double realPerPixelY; + private double gridXStart = -2; + private double gridYStart = -1.5; + private double gridXEnd = 1; + private double gridYEnd = 1.5; + //private double gridZoomOffset = 0.01; + private int maximumOrbitPath = 65536;//1791;// 7* 255; + private double maximumOrbitRadius = 2; + private double originalOriginX = 0; + private double originalOriginY = 0; + //private double radiusZoomOffset = 0.0005; + private double radiusZoomFactor = 0.9; + private int direction = -1; + private double radius = 10; + + private List threadCompleteList = new ArrayList(); + private List workUnits = new ArrayList(); + public BufferedImage getBufferedImage() { + return bufferedImage; + } + + public void setBufferedImage(BufferedImage bufferedImage) { + this.bufferedImage = bufferedImage; + } + private BufferedImage bufferedImage; + + + private long startTimestamp; + + //0.001643721971153 + 0.822467633298876i + public void setOrigin(double x, double y) { + originalOriginX = x; + originalOriginY = y; + } + + public void setRadius(double aRadius) { + radius = aRadius; + // compute edges of window + this.setGridXStart(originalOriginX - radius); + this.setGridXEnd(originalOriginX + radius); + this.setGridYStart(originalOriginY - radius); + this.setGridYEnd(originalOriginY + radius); + } + + public void setParameters2(double x, double y, double radius) { + // compute edges of window + this.setGridXStart(x - radius); + this.setGridXEnd(x + radius); + this.setGridYStart(y - radius); + this.setGridYEnd(y + radius); + } + + + /** + * This function is called by the Java2d framework + */ + @Override + public void paint(Graphics g) { + BufferedImage dest = new BufferedImage(izMaxWidth,izMaxHeight, BufferedImage.TYPE_INT_RGB); + setBufferedImage(dest); + g.drawImage(buffer, 0, 0, this); + // clear previous image from buffer + if (null != gContext) { // image may not be ready + //gContext.setColor(Color.black); + //gContext.fillRect(0, 0, izMaxWidth, izMaxHeight); + //displayCurrentSolution(); + + // Repaint only when all threads are complete + boolean threadsFinished = false; + long threadCount = 0; + while(!threadsFinished) { + for(Boolean complete : threadCompleteList) { + if(complete) { + threadCount++; + } + } + if(threadCount == threadCompleteList.size()) { + // all threads finished - lets create new threads and exit/recalculate + threadsFinished = true; + for(int core=0;core 10 && direction > 0) { + radiusZoomFactor = 0.9; + direction = -1; + } + radius = radius * radiusZoomFactor;// - radiusZoomOffset; + setRadius(radius); + } + + private synchronized void addWorkUnits() { + // Setup thread handlers by dividing up the work + for(int core=0;core getThreadCompleteList() { return threadCompleteList; } + public void setThreadCompleteList(List threadCompleteList) { this.threadCompleteList = threadCompleteList; } + public Boolean isThreadComplete(int index) { return threadCompleteList.get(index); } + public void setThreadComplete(int index, Boolean flag) { threadCompleteList.set(index, flag); } + public List getWorkUnits() { return workUnits; } + public void setWorkUnits(List workUnits) { this.workUnits = workUnits; } + public double getRealPerPixelX() { return realPerPixelX; } + public void setRealPerPixelX(double realPerPixelX) { this.realPerPixelX = realPerPixelX; } + public double getRealPerPixelY() { return realPerPixelY; } + public void setRealPerPixelY(double realPerPixelY) { this.realPerPixelY = realPerPixelY; } + public double getGridXStart() { return gridXStart; } + public double getGridYStart() { return gridYStart; } + public double getGridXEnd() { return gridXEnd; } + public double getGridYEnd() { return gridYEnd; } + public int getMaximumOrbitPath() { return maximumOrbitPath; } + public void setMaximumOrbitPath(int maximumOrbitPath) { this.maximumOrbitPath = maximumOrbitPath; } + public double getMaximumOrbitRadius() { return maximumOrbitRadius; } + public void setMaximumOrbitRadius(double maximumOrbitRadius) { this.maximumOrbitRadius = maximumOrbitRadius; } + public static List getCurrentColors() { return currentColors; } + public static void setCurrentColors(List currentColors) { Mandelbrot.currentColors = currentColors; } + public synchronized void setGridXStart(double gridXStart) { + this.gridXStart = gridXStart; + recalculateParameters(); + } + public synchronized void setGridYStart(double gridYStart) { + this.gridYStart = gridYStart; + recalculateParameters(); + } + public synchronized void setGridXEnd(double gridXEnd) { + this.gridXEnd = gridXEnd; + recalculateParameters(); + } + public synchronized void setGridYEnd(double gridYEnd) { + this.gridYEnd = gridYEnd; + recalculateParameters(); + } + + /* + public void displayCurrentSolution() { + double h,v; + int iterations; + for(int x=0;x {//RecursiveAction { - private static final long serialVersionUID = 5386834196721056333L; - protected static int sThreshold = 8; - private long rowNumber; - private long rowStart; - private long rowEnd; - private boolean isBaseCase; - private long width; - private long height; - private BufferedImage bufferedImage; - private MandelbrotImager imager; - public static final BigDecimal TWO = new BigDecimal(2); - public static final BigDecimal FOUR = new BigDecimal(4); - public static final int BIGDECIMAL_SCALE = 64; // don't let performance degrade exponentially as size goes to infinity - private static final MathContext context = MathContext.DECIMAL128; - - public MandelbrotForkJoinUnitOfWork(MandelbrotImager imager,BufferedImage bufferedImage, - long rowNumber, long rowStart, long rowEnd, long height, long width) { - this.imager = imager; - this.bufferedImage = bufferedImage; - this.rowNumber = rowNumber; - this.rowStart = rowStart; - this.rowEnd = rowEnd; - this.height = height; - this.width = width; - } - - @Override - protected Boolean compute() { - Boolean allMaxOrbit = true; - if(rowNumber < sThreshold) { // don't subdivide too small so we keep overhead to a minimum - isBaseCase = true; - } - // base case - if(isBaseCase) { - try { - allMaxOrbit = calculate(); - //calculateBigDecimal(); - //System.out.print("."); - } catch (Exception e) { - e.printStackTrace(); - } - return allMaxOrbit; - } - - // recursive case (0-1023),(0-511,512-1023),(0-255,256-511,512-767,768-1023) - long split = (rowEnd - rowStart) >> 1; - long splitRowNumber = rowNumber >> 1; - //System.out.print("f"); - /*invokeAll( - new MandelbrotForkJoinUnitOfWork(imager, bufferedImage, - splitRowNumber, rowStart, rowStart + split, height, width), - new MandelbrotForkJoinUnitOfWork(imager, bufferedImage, - splitRowNumber, rowStart + split, rowEnd, height, width) - );*/ - MandelbrotForkJoinUnitOfWork m0 = new MandelbrotForkJoinUnitOfWork(imager, bufferedImage, - splitRowNumber, rowStart, rowStart + split, height, width); - MandelbrotForkJoinUnitOfWork m1 = new MandelbrotForkJoinUnitOfWork(imager, bufferedImage, - splitRowNumber, rowStart + split, rowEnd, height, width); - // if any of the threads return false then the image contains non-max-orbit data - return m0.invoke() && m1.invoke(); - } - - public Boolean calculate() { - Boolean allMax = true; - double h,v; - double radiusMax = imager.getMaximumOrbitRadius(); - int orbitPath = imager.getMaximumOrbitPath(); - double xstart = imager.getGridXStart(); - double ystart = imager.getGridYStart(); - double xscale = imager.getRealPerPixelX(); - double yscale = imager.getRealPerPixelY(); - for(long x=0;x> imager.getColorPowerMult() != imager.getMaximumOrbitPath())) { // do this only once - allMax = false; - } - } - } - return allMax; - } - - public Boolean calculateBigDecimal() { - Boolean allMax = true; - BigDecimal h,v; - BigDecimal radiusMax = BigDecimal.valueOf(imager.getMaximumOrbitRadius()); - int orbitPath = imager.getMaximumOrbitPath(); - double xstart = imager.getGridXStart(); - double ystart = imager.getGridYStart(); - double xscale = imager.getRealPerPixelX(); - double yscale = imager.getRealPerPixelY(); - for(long x=0;x> imager.getColorPowerMult() != imager.getMaximumOrbitPath()) { - allMax = false; - } - - bufferedImage.setRGB((int)x, (int)y, iter); - } - } - return allMax; - } - - public int computeJuliaBigDecimal(BigDecimal x, BigDecimal y, BigDecimal radiusMax, int pathMax) { - int iterations = 0; - BigDecimal real = new BigDecimal(0); - BigDecimal imag = new BigDecimal(0); - BigDecimal realNext = new BigDecimal(0); - do { - realNext = ((real.multiply(real, context)).subtract( - imag.multiply(imag, context), context)).add(x, context); - imag = ((real.multiply(imag, context)).multiply(TWO, context)).add(y, context); - real = realNext; - iterations++; - } while (realNext.compareTo(FOUR) < 0 && iterations < pathMax); - return iterations << imager.getColorPowerMult(); - } - - public int computeJulia(double x, double y, double radiusMax, int pathMax) { - int iterations = 0; - double real = 0; - double imag = 0; - double realNext = 0; - do { - realNext = ( real * real) - (imag * imag) + x; - imag = (real * imag * 2) + y; - real = realNext; - iterations++; - } while (realNext < 4 && iterations < pathMax); - return iterations << imager.getColorPowerMult(); - } -} +package org.obrienscience.fractal; + +import java.awt.image.BufferedImage; +import java.math.BigDecimal; +import java.math.MathContext; +import java.util.concurrent.RecursiveAction; +import java.util.concurrent.RecursiveTask; + +/** + * Split the image into strips down to possibly a single line + * @author mfobrien + */ +public class MandelbrotForkJoinUnitOfWork extends RecursiveTask {//RecursiveAction { + private static final long serialVersionUID = 5386834196721056333L; + protected static int sThreshold = 8; + private long rowNumber; + private long rowStart; + private long rowEnd; + private boolean isBaseCase; + private long width; + private long height; + private BufferedImage bufferedImage; + private MandelbrotImager imager; + public static final BigDecimal TWO = new BigDecimal(2); + public static final BigDecimal FOUR = new BigDecimal(4); + public static final int BIGDECIMAL_SCALE = 64; // don't let performance degrade exponentially as size goes to infinity + private static final MathContext context = MathContext.DECIMAL128; + + public MandelbrotForkJoinUnitOfWork(MandelbrotImager imager,BufferedImage bufferedImage, + long rowNumber, long rowStart, long rowEnd, long height, long width) { + this.imager = imager; + this.bufferedImage = bufferedImage; + this.rowNumber = rowNumber; + this.rowStart = rowStart; + this.rowEnd = rowEnd; + this.height = height; + this.width = width; + } + + @Override + protected Boolean compute() { + Boolean allMaxOrbit = true; + if(rowNumber < sThreshold) { // don't subdivide too small so we keep overhead to a minimum + isBaseCase = true; + } + // base case + if(isBaseCase) { + try { + allMaxOrbit = calculate(); + //calculateBigDecimal(); + //System.out.print("."); + } catch (Exception e) { + e.printStackTrace(); + } + return allMaxOrbit; + } + + // recursive case (0-1023),(0-511,512-1023),(0-255,256-511,512-767,768-1023) + long split = (rowEnd - rowStart) >> 1; + long splitRowNumber = rowNumber >> 1; + //System.out.print("f"); + /*invokeAll( + new MandelbrotForkJoinUnitOfWork(imager, bufferedImage, + splitRowNumber, rowStart, rowStart + split, height, width), + new MandelbrotForkJoinUnitOfWork(imager, bufferedImage, + splitRowNumber, rowStart + split, rowEnd, height, width) + );*/ + MandelbrotForkJoinUnitOfWork m0 = new MandelbrotForkJoinUnitOfWork(imager, bufferedImage, + splitRowNumber, rowStart, rowStart + split, height, width); + MandelbrotForkJoinUnitOfWork m1 = new MandelbrotForkJoinUnitOfWork(imager, bufferedImage, + splitRowNumber, rowStart + split, rowEnd, height, width); + // if any of the threads return false then the image contains non-max-orbit data + return m0.invoke() && m1.invoke(); + } + + public Boolean calculate() { + Boolean allMax = true; + double h,v; + double radiusMax = imager.getMaximumOrbitRadius(); + int orbitPath = imager.getMaximumOrbitPath(); + double xstart = imager.getGridXStart(); + double ystart = imager.getGridYStart(); + double xscale = imager.getRealPerPixelX(); + double yscale = imager.getRealPerPixelY(); + for(long x=0;x> imager.getColorPowerMult() != imager.getMaximumOrbitPath())) { // do this only once + allMax = false; + } + } + } + return allMax; + } + + public Boolean calculateBigDecimal() { + Boolean allMax = true; + BigDecimal h,v; + BigDecimal radiusMax = BigDecimal.valueOf(imager.getMaximumOrbitRadius()); + int orbitPath = imager.getMaximumOrbitPath(); + double xstart = imager.getGridXStart(); + double ystart = imager.getGridYStart(); + double xscale = imager.getRealPerPixelX(); + double yscale = imager.getRealPerPixelY(); + for(long x=0;x> imager.getColorPowerMult() != imager.getMaximumOrbitPath()) { + allMax = false; + } + + bufferedImage.setRGB((int)x, (int)y, iter); + } + } + return allMax; + } + + public int computeJuliaBigDecimal(BigDecimal x, BigDecimal y, BigDecimal radiusMax, int pathMax) { + int iterations = 0; + BigDecimal real = new BigDecimal(0); + BigDecimal imag = new BigDecimal(0); + BigDecimal realNext = new BigDecimal(0); + do { + realNext = ((real.multiply(real, context)).subtract( + imag.multiply(imag, context), context)).add(x, context); + imag = ((real.multiply(imag, context)).multiply(TWO, context)).add(y, context); + real = realNext; + iterations++; + } while (realNext.compareTo(FOUR) < 0 && iterations < pathMax); + return iterations << imager.getColorPowerMult(); + } + + public int computeJulia(double x, double y, double radiusMax, int pathMax) { + int iterations = 0; + double real = 0; + double imag = 0; + double realNext = 0; + do { + realNext = ( real * real) - (imag * imag) + x; + imag = (real * imag * 2) + y; + real = realNext; + iterations++; + } while (realNext < 4 && iterations < pathMax); + return iterations << imager.getColorPowerMult(); + } +} diff --git a/org/obrienscience/fractal/MandelbrotImager.java b/src/main/java/org/obrienscience/fractal/MandelbrotImager.java old mode 100755 new mode 100644 similarity index 96% rename from org/obrienscience/fractal/MandelbrotImager.java rename to src/main/java/org/obrienscience/fractal/MandelbrotImager.java index 90b07c0..9a3c0d8 --- a/org/obrienscience/fractal/MandelbrotImager.java +++ b/src/main/java/org/obrienscience/fractal/MandelbrotImager.java @@ -1,361 +1,361 @@ -package org.obrienscience.fractal; - -import java.awt.Color; -import java.awt.image.BufferedImage; -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ForkJoinPool; - -import javax.imageio.ImageIO; - -public class MandelbrotImager { - - public static final int CORES = 6;//32;//Runtime.getRuntime().availableProcessors() << 8; - private ForkJoinPool mapReducePool = new ForkJoinPool(CORES); - public static List rgbColors; - public static List currentColors; - private double radius = 10; - - /*static { - rgbColors = new ArrayList(); - for(int i=0;i<256;i++) { rgbColors.add(new Color(0,0,255-i)); } - for(int i=0;i<256;i++) { rgbColors.add(new Color(0,255-i,0)); } - for(int i=0;i<256;i++) { rgbColors.add(new Color(i,0,0)); } - for(int i=0;i<256;i++) { rgbColors.add(new Color(0,255-i,255-i)); } - for(int i=0;i<256;i++) { rgbColors.add(new Color(i,0,i)); } - for(int i=0;i<256;i++) { rgbColors.add(new Color(255-i,255-i,0)); } - for(int i=0;i<256;i++) { rgbColors.add(new Color(i,i,i)); } - currentColors = rgbColors; - }*/ - - public static final double DEFAULT_ORIGIN_X = 0.0; - public static final double DEFAULT_ORIGIN_Y = 0.0; -// public static final double DEFAULT_ORIGIN_X = 0.001643721971153; -// public static final double DEFAULT_ORIGIN_Y = 0.822467633296005; -// public static final double DEFAULT_ORIGIN_X = -0.00573721971153; -// public static final double DEFAULT_ORIGIN_Y = 0.805657633296005; - //public static final double DEFAULT_RADIUS = 0.002000000002001; - public static final double DEFAULT_RADIUS = 10.0; - public static final int FULL_RADIUS = 5; - - // maximum = 16384 = 256 mpixel - private int colorPowerMult = 2; - private int extentX = 16384;//512 << 0;//3; - private int extentY = 16384;//512 << 0;//3; - private double realPerPixelX; - private double realPerPixelY; - private double gridXStart = -2; - private double gridYStart = -1.5; - private double gridXEnd = 1; - private double gridYEnd = 1.5; - private int maximumOrbitPath = 65536 << 0;//1791;// 7* 255; - private double maximumOrbitRadius = 2; - private double originalOriginX = 0; - private double originalOriginY = 0; - private long startTimestamp; - //private static int TRUNC = 100000000; - - public void process() {//int width, int height) { - genericInit(); - int height = this.getExtentX(); - int width = this.getExtentY(); - setRadius(5); - for(int r=0;r<4;r++) { - int frame = 0; - //int frames = (int)Math.pow((2*radius), r); - int trunc = (int)Math.pow(10, (r+1)); - int nextRadius = (int)(radius*trunc); - setRadius(((double)nextRadius)/(trunc * 10)); - //setRadius(radius * 0.05); - int h=0; - int v=0; - System.out.println(); - for(double x=-5;x<5;x+=(radius*2)) { - v=0; - System.out.print("."); - for(double y=-5;y<5;y+=(radius*2)) { -// setOrigin(DEFAULT_ORIGIN_X + (2 * radius * x) + (radius), -// DEFAULT_ORIGIN_Y + (2 * radius * y) + (radius)); - setOrigin(x + (radius), - y + (radius)); - setRadius(radius); - BufferedImage dest = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB); - MandelbrotForkJoinUnitOfWork fork = new MandelbrotForkJoinUnitOfWork( - this, dest, height, 0, height, height, width); - - //System.out.print(".");//Start: " + System.currentTimeMillis()); - long start = System.currentTimeMillis(); - Boolean allMax = mapReducePool.invoke(fork); - long duration = (System.currentTimeMillis() - start); - long end = System.currentTimeMillis(); - // only save significant frames - if(duration > 270 && !allMax) { // 260 for virtual - - System.out.println("\ncompute in: " + duration + " ms :"); - System.out.println("center: " + originalOriginX + "," + originalOriginY); - System.out.println("radius: " + this.radius); - System.out.println("frame : " + frame); - saveImage(dest, duration, frame, trunc, (r), h,v); - - System.out.println("image in: " + (System.currentTimeMillis() - end) + " ms :"); - System.out.println("End : " + System.currentTimeMillis()); - } - frame++; - v++; - } - h++; - } - } - } - public void process2() {//int width, int height) { - genericInit(); - int height = this.getExtentX(); - int width = this.getExtentY(); - setRadius(FULL_RADIUS); - - for(int zoom=0;zoom<4;zoom++) { - int frame = 0; - //int frames = (int)Math.pow((2*radius), r); - int trunc = (int)Math.pow(FULL_RADIUS * 2, (zoom + 1)); - int nextRadius = (int)(radius*trunc); - setRadius(((double)nextRadius)/(trunc * FULL_RADIUS * 2)); - //setRadius(radius * 0.05); - int h=0; - int v=0; - double x=0; - double y=0; - System.out.println(); - for(int horiz=0;horiz 400 && !allMax) { - System.out.println("\ncompute in: " + duration + " ms:"); - System.out.println("center: " + originalOriginX + "," + originalOriginY); - System.out.println("radius: " + this.radius); - System.out.println("frame : " + frame); - saveImage(dest, duration, frame, trunc, (zoom), h,v); - - System.out.println("image in: " + (System.currentTimeMillis() - end) + " ms :"); - System.out.println("End : " + System.currentTimeMillis()); - } else { - if(allMax) { - System.out.print("M"); - } - } - frame++; - v++; - } - h++; - } - } - } - - public void saveImage(BufferedImage image, long duration, int frame, int trunc, int r, int h, int v) { - File f = new File("mandelbrot_p" + - r + "_x" + h + "_y" + v + "_o" + - -// ((double)((double)((int)(originalOriginX * trunc))/trunc)) + "_y" + -// ((double)((double)((int)(originalOriginY * trunc))/trunc)) + "_r" + -// ((double)((double)((int)(radius * trunc))/trunc)) + "_o" + - //originalOriginX + "_y" + - //originalOriginY + "_r" + - //radius + "_o" + - maximumOrbitPath + "_h" + - extentX + "_v" + - extentY + "_c" + - colorPowerMult + //"_t" + - //duration + - "_f" + frame + - ".png"); - try { - ImageIO.write(image, "png", f); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void setOrigin(double x, double y) { - originalOriginX = x; - originalOriginY = y; - } - - - public void setRadius(double aRadius) { - radius = aRadius; - // compute edges of window - this.setGridXStart(originalOriginX - radius); - this.setGridXEnd(originalOriginX + radius); - this.setGridYStart(originalOriginY - radius); - this.setGridYEnd(originalOriginY + radius); - // setup screen real estate - setRealPerPixelX((gridXEnd - gridXStart) / getExtentX()); - setRealPerPixelY((gridYEnd - gridYStart) / getExtentY()); - } - - public void genericInit() { - // setup extents - setOrigin(DEFAULT_ORIGIN_X, DEFAULT_ORIGIN_Y); - setRadius(DEFAULT_RADIUS); - // start the timer - startTimestamp = System.currentTimeMillis(); - } - - public ForkJoinPool getMapReducePool() { - return mapReducePool; - } - - public void setMapReducePool(ForkJoinPool mapReducePool) { - this.mapReducePool = mapReducePool; - } - - public static List getRgbColors() { - return rgbColors; - } - - public static void setRgbColors(List rgbColors) { - MandelbrotImager.rgbColors = rgbColors; - } - - public static List getCurrentColors() { - return currentColors; - } - - public static void setCurrentColors(List currentColors) { - MandelbrotImager.currentColors = currentColors; - } - - public double getRealPerPixelX() { - return realPerPixelX; - } - - public void setRealPerPixelX(double realPerPixelX) { - this.realPerPixelX = realPerPixelX; - } - - public double getRealPerPixelY() { - return realPerPixelY; - } - - public void setRealPerPixelY(double realPerPixelY) { - this.realPerPixelY = realPerPixelY; - } - - public double getGridXStart() { - return gridXStart; - } - - public void setGridXStart(double gridXStart) { - this.gridXStart = gridXStart; - } - - public double getGridYStart() { - return gridYStart; - } - - public void setGridYStart(double gridYStart) { - this.gridYStart = gridYStart; - } - - public double getGridXEnd() { - return gridXEnd; - } - - public void setGridXEnd(double gridXEnd) { - this.gridXEnd = gridXEnd; - } - - public double getGridYEnd() { - return gridYEnd; - } - - public void setGridYEnd(double gridYEnd) { - this.gridYEnd = gridYEnd; - } - - public int getMaximumOrbitPath() { - return maximumOrbitPath; - } - - public void setMaximumOrbitPath(int maximumOrbitPath) { - this.maximumOrbitPath = maximumOrbitPath; - } - - public double getMaximumOrbitRadius() { - return maximumOrbitRadius; - } - - public void setMaximumOrbitRadius(double maximumOrbitRadius) { - this.maximumOrbitRadius = maximumOrbitRadius; - } - - public double getOriginalOriginX() { - return originalOriginX; - } - - public void setOriginalOriginX(double originalOriginX) { - this.originalOriginX = originalOriginX; - } - - public double getOriginalOriginY() { - return originalOriginY; - } - - public void setOriginalOriginY(double originalOriginY) { - this.originalOriginY = originalOriginY; - } - - public int getColorPowerMult() { - return colorPowerMult; - } - - public void setColorPowerMult(int colorPowerMult) { - this.colorPowerMult = colorPowerMult; - } - - public int getExtentX() { - return extentX; - } - - public void setExtentX(int extentX) { - this.extentX = extentX; - } - - public int getExtentY() { - return extentY; - } - - public void setExtentY(int extentY) { - this.extentY = extentY; - } - - public long getStartTimestamp() { - return startTimestamp; - } - - public void setStartTimestamp(long startTimestamp) { - this.startTimestamp = startTimestamp; - } - - public static void main(String[] args) { - MandelbrotImager imager = new MandelbrotImager(); - imager.process(); - } -} +package org.obrienscience.fractal; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ForkJoinPool; + +import javax.imageio.ImageIO; + +public class MandelbrotImager { + + public static final int CORES = 6;//32;//Runtime.getRuntime().availableProcessors() << 8; + private ForkJoinPool mapReducePool = new ForkJoinPool(CORES); + public static List rgbColors; + public static List currentColors; + private double radius = 10; + + /*static { + rgbColors = new ArrayList(); + for(int i=0;i<256;i++) { rgbColors.add(new Color(0,0,255-i)); } + for(int i=0;i<256;i++) { rgbColors.add(new Color(0,255-i,0)); } + for(int i=0;i<256;i++) { rgbColors.add(new Color(i,0,0)); } + for(int i=0;i<256;i++) { rgbColors.add(new Color(0,255-i,255-i)); } + for(int i=0;i<256;i++) { rgbColors.add(new Color(i,0,i)); } + for(int i=0;i<256;i++) { rgbColors.add(new Color(255-i,255-i,0)); } + for(int i=0;i<256;i++) { rgbColors.add(new Color(i,i,i)); } + currentColors = rgbColors; + }*/ + + public static final double DEFAULT_ORIGIN_X = 0.0; + public static final double DEFAULT_ORIGIN_Y = 0.0; +// public static final double DEFAULT_ORIGIN_X = 0.001643721971153; +// public static final double DEFAULT_ORIGIN_Y = 0.822467633296005; +// public static final double DEFAULT_ORIGIN_X = -0.00573721971153; +// public static final double DEFAULT_ORIGIN_Y = 0.805657633296005; + //public static final double DEFAULT_RADIUS = 0.002000000002001; + public static final double DEFAULT_RADIUS = 10.0; + public static final int FULL_RADIUS = 5; + + // maximum = 16384 = 256 mpixel + private int colorPowerMult = 2; + private int extentX = 16384;//512 << 0;//3; + private int extentY = 16384;//512 << 0;//3; + private double realPerPixelX; + private double realPerPixelY; + private double gridXStart = -2; + private double gridYStart = -1.5; + private double gridXEnd = 1; + private double gridYEnd = 1.5; + private int maximumOrbitPath = 65536 << 0;//1791;// 7* 255; + private double maximumOrbitRadius = 2; + private double originalOriginX = 0; + private double originalOriginY = 0; + private long startTimestamp; + //private static int TRUNC = 100000000; + + public void process() {//int width, int height) { + genericInit(); + int height = this.getExtentX(); + int width = this.getExtentY(); + setRadius(5); + for(int r=0;r<4;r++) { + int frame = 0; + //int frames = (int)Math.pow((2*radius), r); + int trunc = (int)Math.pow(10, (r+1)); + int nextRadius = (int)(radius*trunc); + setRadius(((double)nextRadius)/(trunc * 10)); + //setRadius(radius * 0.05); + int h=0; + int v=0; + System.out.println(); + for(double x=-5;x<5;x+=(radius*2)) { + v=0; + System.out.print("."); + for(double y=-5;y<5;y+=(radius*2)) { +// setOrigin(DEFAULT_ORIGIN_X + (2 * radius * x) + (radius), +// DEFAULT_ORIGIN_Y + (2 * radius * y) + (radius)); + setOrigin(x + (radius), + y + (radius)); + setRadius(radius); + BufferedImage dest = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB); + MandelbrotForkJoinUnitOfWork fork = new MandelbrotForkJoinUnitOfWork( + this, dest, height, 0, height, height, width); + + //System.out.print(".");//Start: " + System.currentTimeMillis()); + long start = System.currentTimeMillis(); + Boolean allMax = mapReducePool.invoke(fork); + long duration = (System.currentTimeMillis() - start); + long end = System.currentTimeMillis(); + // only save significant frames + if(duration > 270 && !allMax) { // 260 for virtual + + System.out.println("\ncompute in: " + duration + " ms :"); + System.out.println("center: " + originalOriginX + "," + originalOriginY); + System.out.println("radius: " + this.radius); + System.out.println("frame : " + frame); + saveImage(dest, duration, frame, trunc, (r), h,v); + + System.out.println("image in: " + (System.currentTimeMillis() - end) + " ms :"); + System.out.println("End : " + System.currentTimeMillis()); + } + frame++; + v++; + } + h++; + } + } + } + public void process2() {//int width, int height) { + genericInit(); + int height = this.getExtentX(); + int width = this.getExtentY(); + setRadius(FULL_RADIUS); + + for(int zoom=0;zoom<4;zoom++) { + int frame = 0; + //int frames = (int)Math.pow((2*radius), r); + int trunc = (int)Math.pow(FULL_RADIUS * 2, (zoom + 1)); + int nextRadius = (int)(radius*trunc); + setRadius(((double)nextRadius)/(trunc * FULL_RADIUS * 2)); + //setRadius(radius * 0.05); + int h=0; + int v=0; + double x=0; + double y=0; + System.out.println(); + for(int horiz=0;horiz 400 && !allMax) { + System.out.println("\ncompute in: " + duration + " ms:"); + System.out.println("center: " + originalOriginX + "," + originalOriginY); + System.out.println("radius: " + this.radius); + System.out.println("frame : " + frame); + saveImage(dest, duration, frame, trunc, (zoom), h,v); + + System.out.println("image in: " + (System.currentTimeMillis() - end) + " ms :"); + System.out.println("End : " + System.currentTimeMillis()); + } else { + if(allMax) { + System.out.print("M"); + } + } + frame++; + v++; + } + h++; + } + } + } + + public void saveImage(BufferedImage image, long duration, int frame, int trunc, int r, int h, int v) { + File f = new File("mandelbrot_p" + + r + "_x" + h + "_y" + v + "_o" + + +// ((double)((double)((int)(originalOriginX * trunc))/trunc)) + "_y" + +// ((double)((double)((int)(originalOriginY * trunc))/trunc)) + "_r" + +// ((double)((double)((int)(radius * trunc))/trunc)) + "_o" + + //originalOriginX + "_y" + + //originalOriginY + "_r" + + //radius + "_o" + + maximumOrbitPath + "_h" + + extentX + "_v" + + extentY + "_c" + + colorPowerMult + //"_t" + + //duration + + "_f" + frame + + ".png"); + try { + ImageIO.write(image, "png", f); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void setOrigin(double x, double y) { + originalOriginX = x; + originalOriginY = y; + } + + + public void setRadius(double aRadius) { + radius = aRadius; + // compute edges of window + this.setGridXStart(originalOriginX - radius); + this.setGridXEnd(originalOriginX + radius); + this.setGridYStart(originalOriginY - radius); + this.setGridYEnd(originalOriginY + radius); + // setup screen real estate + setRealPerPixelX((gridXEnd - gridXStart) / getExtentX()); + setRealPerPixelY((gridYEnd - gridYStart) / getExtentY()); + } + + public void genericInit() { + // setup extents + setOrigin(DEFAULT_ORIGIN_X, DEFAULT_ORIGIN_Y); + setRadius(DEFAULT_RADIUS); + // start the timer + startTimestamp = System.currentTimeMillis(); + } + + public ForkJoinPool getMapReducePool() { + return mapReducePool; + } + + public void setMapReducePool(ForkJoinPool mapReducePool) { + this.mapReducePool = mapReducePool; + } + + public static List getRgbColors() { + return rgbColors; + } + + public static void setRgbColors(List rgbColors) { + MandelbrotImager.rgbColors = rgbColors; + } + + public static List getCurrentColors() { + return currentColors; + } + + public static void setCurrentColors(List currentColors) { + MandelbrotImager.currentColors = currentColors; + } + + public double getRealPerPixelX() { + return realPerPixelX; + } + + public void setRealPerPixelX(double realPerPixelX) { + this.realPerPixelX = realPerPixelX; + } + + public double getRealPerPixelY() { + return realPerPixelY; + } + + public void setRealPerPixelY(double realPerPixelY) { + this.realPerPixelY = realPerPixelY; + } + + public double getGridXStart() { + return gridXStart; + } + + public void setGridXStart(double gridXStart) { + this.gridXStart = gridXStart; + } + + public double getGridYStart() { + return gridYStart; + } + + public void setGridYStart(double gridYStart) { + this.gridYStart = gridYStart; + } + + public double getGridXEnd() { + return gridXEnd; + } + + public void setGridXEnd(double gridXEnd) { + this.gridXEnd = gridXEnd; + } + + public double getGridYEnd() { + return gridYEnd; + } + + public void setGridYEnd(double gridYEnd) { + this.gridYEnd = gridYEnd; + } + + public int getMaximumOrbitPath() { + return maximumOrbitPath; + } + + public void setMaximumOrbitPath(int maximumOrbitPath) { + this.maximumOrbitPath = maximumOrbitPath; + } + + public double getMaximumOrbitRadius() { + return maximumOrbitRadius; + } + + public void setMaximumOrbitRadius(double maximumOrbitRadius) { + this.maximumOrbitRadius = maximumOrbitRadius; + } + + public double getOriginalOriginX() { + return originalOriginX; + } + + public void setOriginalOriginX(double originalOriginX) { + this.originalOriginX = originalOriginX; + } + + public double getOriginalOriginY() { + return originalOriginY; + } + + public void setOriginalOriginY(double originalOriginY) { + this.originalOriginY = originalOriginY; + } + + public int getColorPowerMult() { + return colorPowerMult; + } + + public void setColorPowerMult(int colorPowerMult) { + this.colorPowerMult = colorPowerMult; + } + + public int getExtentX() { + return extentX; + } + + public void setExtentX(int extentX) { + this.extentX = extentX; + } + + public int getExtentY() { + return extentY; + } + + public void setExtentY(int extentY) { + this.extentY = extentY; + } + + public long getStartTimestamp() { + return startTimestamp; + } + + public void setStartTimestamp(long startTimestamp) { + this.startTimestamp = startTimestamp; + } + + public static void main(String[] args) { + MandelbrotImager imager = new MandelbrotImager(); + imager.process(); + } +} diff --git a/org/obrienscience/fractal/MandelbrotUnitOfWork.java b/src/main/java/org/obrienscience/fractal/MandelbrotUnitOfWork.java old mode 100755 new mode 100644 similarity index 97% rename from org/obrienscience/fractal/MandelbrotUnitOfWork.java rename to src/main/java/org/obrienscience/fractal/MandelbrotUnitOfWork.java index f7d9e72..38cb495 --- a/org/obrienscience/fractal/MandelbrotUnitOfWork.java +++ b/src/main/java/org/obrienscience/fractal/MandelbrotUnitOfWork.java @@ -1,149 +1,149 @@ -package org.obrienscience.fractal; - -import java.awt.Color; -import java.math.BigDecimal; -import java.util.concurrent.atomic.AtomicLong; - -public class MandelbrotUnitOfWork implements Runnable { - private Mandelbrot mandelbrotManager; - private int threadIndex; - private boolean isThreadIndexOdd = false; - private AtomicLong rowStart; - private AtomicLong rowEnd; - - //public MandelbrotUnitOfWork() { } - public MandelbrotUnitOfWork(Mandelbrot mandelbrotManager, int threadIndex, int rowStart, int rowEnd) { - //this(); - synchronized (this) { - this.mandelbrotManager = mandelbrotManager; - this.threadIndex = threadIndex; - this.rowStart = new AtomicLong(rowStart); - this.rowEnd = new AtomicLong(rowEnd); - if((threadIndex % 2) > 0) { - isThreadIndexOdd = true; - } - } - } - - public static final BigDecimal TWO = new BigDecimal(2); - public int computeJuliaBigDecimal(BigDecimal x, BigDecimal y, BigDecimal radiusMax, int pathMax) { - int iterations = 0; - BigDecimal real = new BigDecimal(0); - BigDecimal imag = new BigDecimal(0); - BigDecimal realNext = new BigDecimal(0); - //double realSquared = real * real; // truncated - //double imagSquared = imag * imag; // truncated - //while (Math.sqrt(realSquared + imagSquared) < radiusMax && iterations < pathMax) { - //while (Math.sqrt((real.multiply(real).add(imag.multiply(imag)))).compareTo(radiusMax) < 0 && iterations < pathMax) { - // use complex plane - //realNext = realSquared - imagSquared + x; - realNext = real.multiply(real).subtract(imag.multiply(imag)).add(x); - imag = (real.multiply(imag).multiply(TWO)).add(y); - real = realNext; - iterations++; - //} - return iterations; - } - - public int computeJulia(double x, double y, double radiusMax, int pathMax) { - int iterations = 0; - double real = 0; - double imag = 0; - double realNext = 0; - //double realSquared = real * real; // truncated - //double imagSquared = imag * imag; // truncated - //while (Math.sqrt(realSquared + imagSquared) < radiusMax && iterations < pathMax) { - //while (Math.sqrt((real * real) + (imag * imag)) < radiusMax && iterations < pathMax) { - double real2; - double imag2; - do { - real2 = real * real; - imag2 = imag * imag; - //while ((real2 + imag2) < 4 && iterations < pathMax) { - // use complex plane - //realNext = realSquared - imagSquared + x; - realNext = real2 - imag2 + x; - imag = (real * imag * 2) + y; - real = realNext; - iterations++; - } while ((real2 + imag2) < 4 && iterations < pathMax); - return iterations; - } - - // Either iterations, hv, xy or start/end - public void run() { - double h,v; - int iterations; - long start = rowStart.get(); - long end = rowEnd.get(); - //for(long x=0;x<12;x++) {//mandelbrotManager.getExtentX();x++) { - Color color; - for(long x=0;x 100) { - //System.out.println("_Thread contention: color was changed mid-function: (thread,writes,x,y) " + threadIndex + "," + rewrites + "," + x + "," + y); - - } - } else { - colorChanged = false; - } - } while (colorChanged); - } - //} -*/ } - //} - } - } - // notify the host thread that we are done - mandelbrotManager.setThreadComplete(threadIndex, true); - // destroy all fields to aide in Thread.exit() - //mandelbrotManager = null; - } - - public Mandelbrot getMandelbrotManager() { return mandelbrotManager; } - public void setMandelbrotManager(Mandelbrot mandelbrotManager) { this.mandelbrotManager = mandelbrotManager; } - public int getThreadIndex() { return threadIndex; } - public void setThreadIndex(int threadIndex) { this.threadIndex = threadIndex; } - - /** - * @param args - */ - public static void main(String[] args) { - // TODO Auto-generated method stub - - } - -} +package org.obrienscience.fractal; + +import java.awt.Color; +import java.math.BigDecimal; +import java.util.concurrent.atomic.AtomicLong; + +public class MandelbrotUnitOfWork implements Runnable { + private Mandelbrot mandelbrotManager; + private int threadIndex; + private boolean isThreadIndexOdd = false; + private AtomicLong rowStart; + private AtomicLong rowEnd; + + //public MandelbrotUnitOfWork() { } + public MandelbrotUnitOfWork(Mandelbrot mandelbrotManager, int threadIndex, int rowStart, int rowEnd) { + //this(); + synchronized (this) { + this.mandelbrotManager = mandelbrotManager; + this.threadIndex = threadIndex; + this.rowStart = new AtomicLong(rowStart); + this.rowEnd = new AtomicLong(rowEnd); + if((threadIndex % 2) > 0) { + isThreadIndexOdd = true; + } + } + } + + public static final BigDecimal TWO = new BigDecimal(2); + public int computeJuliaBigDecimal(BigDecimal x, BigDecimal y, BigDecimal radiusMax, int pathMax) { + int iterations = 0; + BigDecimal real = new BigDecimal(0); + BigDecimal imag = new BigDecimal(0); + BigDecimal realNext = new BigDecimal(0); + //double realSquared = real * real; // truncated + //double imagSquared = imag * imag; // truncated + //while (Math.sqrt(realSquared + imagSquared) < radiusMax && iterations < pathMax) { + //while (Math.sqrt((real.multiply(real).add(imag.multiply(imag)))).compareTo(radiusMax) < 0 && iterations < pathMax) { + // use complex plane + //realNext = realSquared - imagSquared + x; + realNext = real.multiply(real).subtract(imag.multiply(imag)).add(x); + imag = (real.multiply(imag).multiply(TWO)).add(y); + real = realNext; + iterations++; + //} + return iterations; + } + + public int computeJulia(double x, double y, double radiusMax, int pathMax) { + int iterations = 0; + double real = 0; + double imag = 0; + double realNext = 0; + //double realSquared = real * real; // truncated + //double imagSquared = imag * imag; // truncated + //while (Math.sqrt(realSquared + imagSquared) < radiusMax && iterations < pathMax) { + //while (Math.sqrt((real * real) + (imag * imag)) < radiusMax && iterations < pathMax) { + double real2; + double imag2; + do { + real2 = real * real; + imag2 = imag * imag; + //while ((real2 + imag2) < 4 && iterations < pathMax) { + // use complex plane + //realNext = realSquared - imagSquared + x; + realNext = real2 - imag2 + x; + imag = (real * imag * 2) + y; + real = realNext; + iterations++; + } while ((real2 + imag2) < 4 && iterations < pathMax); + return iterations; + } + + // Either iterations, hv, xy or start/end + public void run() { + double h,v; + int iterations; + long start = rowStart.get(); + long end = rowEnd.get(); + //for(long x=0;x<12;x++) {//mandelbrotManager.getExtentX();x++) { + Color color; + for(long x=0;x 100) { + //System.out.println("_Thread contention: color was changed mid-function: (thread,writes,x,y) " + threadIndex + "," + rewrites + "," + x + "," + y); + + } + } else { + colorChanged = false; + } + } while (colorChanged); + } + //} +*/ } + //} + } + } + // notify the host thread that we are done + mandelbrotManager.setThreadComplete(threadIndex, true); + // destroy all fields to aide in Thread.exit() + //mandelbrotManager = null; + } + + public Mandelbrot getMandelbrotManager() { return mandelbrotManager; } + public void setMandelbrotManager(Mandelbrot mandelbrotManager) { this.mandelbrotManager = mandelbrotManager; } + public int getThreadIndex() { return threadIndex; } + public void setThreadIndex(int threadIndex) { this.threadIndex = threadIndex; } + + /** + * @param args + */ + public static void main(String[] args) { + // TODO Auto-generated method stub + + } + +}