diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 38f78dd9..0678ed79 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -6,9 +6,17 @@ - + + - + + + + + + + + @@ -30,42 +38,13 @@ - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + @@ -98,7 +77,6 @@ @@ -157,6 +136,16 @@ true + + + + + + @@ -539,6 +528,8 @@ + + @@ -1035,6 +1026,18 @@ + + + @@ -1105,7 +1108,11 @@ - + + + + + 1445706310136 @@ -1269,11 +1276,17 @@ - - @@ -1288,34 +1301,65 @@ - + - + - - - + + + - - + + + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - @@ -1533,13 +1571,6 @@ - - - - - - - @@ -1554,20 +1585,6 @@ - - - - - - - - - - - - - - @@ -1603,13 +1620,6 @@ - - - - - - - @@ -1631,13 +1641,6 @@ - - - - - - - @@ -1673,74 +1676,120 @@ - + - - + + - + - - + + + + + - + - - + + - + - - + + + - + - - + + + - + - - - - - - - + - - - - + + - + - - + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/out/artifacts/FractalGenerator_jar/FractalGenerator.jar b/out/artifacts/FractalGenerator_jar/FractalGenerator.jar index e4e6d594..a79cdcaf 100644 Binary files a/out/artifacts/FractalGenerator_jar/FractalGenerator.jar and b/out/artifacts/FractalGenerator_jar/FractalGenerator.jar differ diff --git a/src/in/tamchow/fractal/FractalGenerator.java b/src/in/tamchow/fractal/FractalGenerator.java index cb14032f..85277af8 100644 --- a/src/in/tamchow/fractal/FractalGenerator.java +++ b/src/in/tamchow/fractal/FractalGenerator.java @@ -1,6 +1,7 @@ package in.tamchow.fractal; -import in.tamchow.fractal.config.color.ColorMode; +import in.tamchow.fractal.config.color.ColorConfig; +import in.tamchow.fractal.config.color.Colors; import in.tamchow.fractal.config.fractalconfig.FractalParams; import in.tamchow.fractal.imgutils.ImageData; import in.tamchow.fractal.math.complex.Complex; @@ -18,25 +19,23 @@ */ public class FractalGenerator implements Serializable { public static final int MODE_MANDELBROT = 0, MODE_JULIA = 1, MODE_NEWTON = 2; - ArrayList boundary_points; + ColorConfig color; ArrayList roots; - int zoom, zoom_factor, base_precision, scale, color_mode, num_colors, center_x, center_y, mode, color_density; - double boundary_condition, degree, tolerance; + int zoom, zoom_factor, base_precision, scale, center_x, center_y, mode; + double degree, tolerance; long maxiter; ImageData argand; String function; String[][] consts; int[][] escapedata; Complex[][]argand_map; - int[] random_palette, gradient_palette; - private boolean alreadyCreated; private String variableCode; public FractalGenerator(FractalParams params) { - initFractal(params.initParams.width, params.initParams.height, params.initParams.zoom, params.initParams.zoom_factor, params.initParams.base_precision, params.initParams.color_mode, params.initParams.num_colors, params.initParams.color_density, params.initParams.fractal_mode, params.initParams.boundary_condition, params.initParams.function, params.initParams.consts, params.initParams.variableCode, params.initParams.tolerance); + initFractal(params.initParams.width, params.initParams.height, params.initParams.zoom, params.initParams.zoom_factor, params.initParams.base_precision, params.initParams.fractal_mode, params.initParams.function, params.initParams.consts, params.initParams.variableCode, params.initParams.tolerance, params.initParams.color); } - public FractalGenerator(int width, int height, int zoom, int zoom_factor, int base_precision, int colorizer, int num_colors, int color_density, int mode, double boundary_condition, String function, String[][] consts, String variableCode, double tolerance) { - initFractal(width, height, zoom, zoom_factor, base_precision, colorizer, num_colors, color_density, mode, boundary_condition, function, consts, variableCode, tolerance); + public FractalGenerator(int width, int height, int zoom, int zoom_factor, int base_precision, int mode, String function, String[][] consts, String variableCode, double tolerance, ColorConfig color) { + initFractal(width, height, zoom, zoom_factor, base_precision, mode, function, consts, variableCode, tolerance, color); } public ArrayList getRoots() { @@ -63,15 +62,6 @@ public int[][] getEscapedata() { return escapedata; } - public ArrayList getBoundary_points() { - return boundary_points; - } - - public void setBoundary_points(ArrayList boundary_points) { - this.boundary_points.clear(); - this.boundary_points.addAll(boundary_points); - } - public double getDegree() { return degree; } @@ -101,34 +91,14 @@ public void setArgand_map(Complex[][] argand_map) { } } - public int[] getRandom_palette() { - return random_palette; - } - - public int[] getGradient_palette() { - return gradient_palette; - } - - public void setGradient_palette(int[] gradient_palette) { - this.gradient_palette = new int[gradient_palette.length]; - System.arraycopy(gradient_palette, 0, this.gradient_palette, 0, this.gradient_palette.length); - } - - private void initFractal(int width, int height, int zoom, int zoom_factor, int base_precision, int colorizer, int num_colors, int color_density, int mode, double boundary_condition, String function, String[][] consts, String variableCode, double tolerance) { + private void initFractal(int width, int height, int zoom, int zoom_factor, int base_precision, int mode, String function, String[][] consts, String variableCode, double tolerance, ColorConfig color) { setZoom(zoom); setZoom_factor(zoom_factor); setFunction(function); setBase_precision(base_precision); setConsts(consts); setScale((int) (base_precision * Math.pow(zoom, zoom_factor))); - boundary_points = new ArrayList<>(); argand = new ImageData(width, height); - setColor_mode(colorizer); - setColor_density(color_density); - setNum_colors(num_colors); - alreadyCreated=false; - create_colors(); - setBoundary_condition(boundary_condition); setMode(mode); if (mode == MODE_MANDELBROT) { consts[0][0] = "c"; @@ -138,7 +108,7 @@ private void initFractal(int width, int height, int zoom, int zoom_factor, int b setCenter_y(argand.getHeight() / 2); setMaxiter(argand.getHeight() * argand.getWidth()); argand_map=new Complex[argand.getHeight()][argand.getWidth()]; - poupulateMap(); + populateMap(); escapedata = new int[argand.getHeight()][argand.getWidth()]; if (mode != MODE_NEWTON) { degree = new FunctionEvaluator(variableCode, consts).getDegree(function); @@ -146,80 +116,17 @@ private void initFractal(int width, int height, int zoom, int zoom_factor, int b setVariableCode(variableCode); setTolerance(tolerance); roots = new ArrayList<>(); + setColor(color); } - private void create_colors() { - if(!alreadyCreated) { - random_palette = new int[num_colors]; - random_palette[0] = 0x000000; - gradient_palette = new int[num_colors]; - gradient_palette[0] = 0x000000; - for (int pidx = 0x1; pidx < num_colors; pidx++) { - random_palette[pidx] = (((int) (Math.random() * 255)) << 16 | ((int) (Math.random() * 255)) << 8 | ((int) (Math.random() * 255))); - if (color_mode == ColorMode.COLOR_GRADIENT_DIVERGENT_1) { - gradient_palette[pidx] = gradient_palette[pidx - 1] + (0xfffff / (color_density << num_colors)); - } else if (color_mode == ColorMode.COLOR_GRADIENT_DIVERGENT_2) { - gradient_palette[pidx] = gradient_palette[pidx - 1] + (0xfffff >> num_colors); - } - } - alreadyCreated=true; - }else{ - int[] randtmp=new int[random_palette.length],gradtmp=new int[gradient_palette.length]; - System.arraycopy(random_palette, 0, randtmp, 0, random_palette.length); - random_palette = new int[num_colors]; - System.arraycopy(gradient_palette, 0, gradtmp, 0, gradient_palette.length); - System.arraycopy(randtmp,0,random_palette,0,random_palette.length); - gradient_palette = new int[num_colors]; - System.arraycopy(gradtmp,0,gradient_palette,0,gradient_palette.length); - for (int pidx = randtmp.length; pidx < num_colors; pidx++) { - random_palette[pidx] = (((int) (Math.random() * 255)) << 16 | ((int) (Math.random() * 255)) << 8 | ((int) (Math.random() * 255))); - if (color_mode == ColorMode.COLOR_GRADIENT_DIVERGENT_1) { - gradient_palette[pidx] = gradient_palette[pidx - 1] + (0xfffff / (color_density << num_colors)); - } else if (color_mode == ColorMode.COLOR_GRADIENT_DIVERGENT_2) { - gradient_palette[pidx] = gradient_palette[pidx - 1] + (0xfffff >>> num_colors); - } - } - alreadyCreated=true; - } - } - - private void poupulateMap() { + private void populateMap() { for (int i=0;i last = new Stack<>(); FunctionEvaluator fe = new FunctionEvaluator(Complex.ZERO.toString(), variableCode, consts); long ctr = 0; @@ -427,7 +325,6 @@ public void mandelbrotGenerate(int start_x, int end_x, int start_y, int end_y, i public void newtonGenerate(int start_x, int end_x, int start_y, int end_y, int iterations, Complex constant) { - boundary_points.clear(); Polynomial polynomial = Polynomial.fromString(function); Stack last = new Stack<>(); FunctionEvaluator fe = new FunctionEvaluator(Complex.ZERO.toString(), variableCode, consts); @@ -480,7 +377,6 @@ public void newtonGenerate(int start_x, int end_x, int start_y, int end_y, int i } public void newtonGenerate(int start_x, int end_x, int start_y, int end_y, int iterations) { - boundary_points.clear(); Polynomial polynomial = Polynomial.fromString(function); function = polynomial.toString(); Stack last = new Stack<>(); @@ -551,7 +447,6 @@ private int indexOfRoot(Complex z) { return -1; } public void juliaGenerate(int start_x, int end_x, int start_y, int end_y, int iterations, double escape_radius) { - boundary_points.clear(); Stack last = new Stack<>(); FunctionEvaluator fe = new FunctionEvaluator(Complex.ZERO.toString(), variableCode, consts); long ctr = 0; @@ -594,25 +489,34 @@ public void juliaGenerate(int start_x, int end_x, int start_y, int end_y, int it } } + public ColorConfig getColor() { + return color; + } + + public void setColor(ColorConfig color) { + this.color = new ColorConfig(color); + } + public int getColor(int val, Complex[] last, double escape_radius, int iterations) { - int color = 0x0, color1 = 0x0, color2 = 0x0; + int colortmp = 0x0, color1 = 0x0, color2 = 0x0; double renormalized = ((val + 1) - (Math.log(Math.log(last[0].modulus() / Math.log(escape_radius)) / Math.log(degree)))); - switch (color_mode) { - case ColorMode.COLOR_DIVIDE: + double lbnd, ubnd, calc; + switch (color.getMode()) { + case Colors.CALCULATIONS.COLOR_DIVIDE: color1 = (int) (0xffffff / renormalized); color2 = (int) (0xffffff / (renormalized + 1)); - color = interpolate(color1, color2, renormalized - ((int) renormalized)); + colortmp = interpolate(color1, color2, renormalized - ((int) renormalized)); break; - case ColorMode.COLOR_HIGH_CONTRAST: - color = (iterations * val) << 16 | (iterations * val) << 8 | (iterations * val); + case Colors.CALCULATIONS.COLOR_HIGH_CONTRAST: + colortmp = (iterations * val) << 16 | (iterations * val) << 8 | (iterations * val); break; - case ColorMode.COLOR_MULTIPLY: + case Colors.CALCULATIONS.COLOR_MULTIPLY: color1 = (int) renormalized << 16 | (int) renormalized << 8 | (int) renormalized; color2 = (int) (renormalized + 1) << 16 | (int) (renormalized + 1) << 8 | (int) (renormalized + 1); - color = interpolate(color1, color2, renormalized - ((int) renormalized)); + colortmp = interpolate(color1, color2, renormalized - ((int) renormalized)); break; - case ColorMode.COLOR_GRAYSCALE: - color = val << 16 | val << 8 | val; + case Colors.CALCULATIONS.COLOR_GRAYSCALE: + colortmp = val << 16 | val << 8 | val; break; /*case ColorMode.COLOR_MULTIPLY_3: color1=((int)renormalized<<16)<<16|((int)renormalized<<8)<<8|(int)renormalized; @@ -625,31 +529,42 @@ public int getColor(int val, Complex[] last, double escape_radius, int iteration color=interpolate(color1,color2,renormalized-((int)renormalized)); break; */ - case ColorMode.COLOR_NEWTON_1: + case Colors.CALCULATIONS.COLOR_NEWTON_1: /*if(indexOfRoot(last[0])>0) {*/ - color = interpolate(0xffffff, random_palette[(indexOfRoot(last[0]) * color_density) % num_colors], ((double) val / iterations)); + colortmp = interpolate(0xffffff, color.getColor((indexOfRoot(last[0]) * color.color_density) % color.num_colors), ((double) val / iterations)); /*}else { color = interpolate(0xffffff,random_palette[(((int) escape_radius * color_density) % num_colors)],((double) val / iterations)); }*/ break; - case ColorMode.COLOR_NEWTON_2: - color = interpolate(0xffffff, random_palette[(((int) escape_radius * color_density) % num_colors)], renormalized - ((int) renormalized)); + case Colors.CALCULATIONS.COLOR_NEWTON_2: + colortmp = interpolate(0xffffff, color.getColor((int) (escape_radius * color.color_density) % color.num_colors), renormalized - ((int) renormalized)); break; - case ColorMode.COLOR_GRADIENT_DIVERGENT_1: - case ColorMode.COLOR_GRADIENT_DIVERGENT_2: - color1 = gradient_palette[(int) ((renormalized * color_density) % num_colors)]; - color2 = gradient_palette[(int) (((renormalized + 1) * color_density) % num_colors)]; - color = interpolate(color1, color2, renormalized - (int) (renormalized)); + case Colors.CALCULATIONS.CURVATURE_AVERAGE: + lbnd = -Math.PI; + ubnd = Math.PI; + if (last[1].equals(Complex.ZERO) && last[2] == Complex.ZERO) { + calc = Math.PI / 2; + } else { + calc = Math.abs(ComplexOperations.divide(ComplexOperations.subtract(last[0], last[1]), ComplexOperations.subtract(last[1], last[2])).arg()); + } + colortmp = color.splineInterpolated(color.createIndex(calc, lbnd, ubnd), renormalized - (int) renormalized); break; - case ColorMode.COLOR_RANDOM_DIVERGENT: - color1 = random_palette[(int) ((renormalized * color_density) % num_colors)]; - color2 = random_palette[(int) (((renormalized + 1) * color_density) % num_colors)]; - color = interpolate(color1, color2, renormalized - (int) (renormalized)); + case Colors.CALCULATIONS.STRIPE_AVERAGE: + lbnd = 0.0;//min value of 0.5*sin(x)+0.5, min value of sin(x)=-1 + ubnd = 1.0;//max value of 0.5*sin(x)+0.5, max value of sin(x)=1 + calc = 0.5 * Math.sin(color.color_density * last[0].arg()) + 0.5; + colortmp = color.splineInterpolated(color.createIndex(calc, lbnd, ubnd), renormalized - (int) renormalized); + break; + case Colors.CALCULATIONS.TRIANGLE_AREA_INEQUALITY: + lbnd = Math.abs(ComplexOperations.power(last[1], new Complex(degree)).modulus() - new Complex(consts[0][1]).modulus()); + ubnd = ComplexOperations.power(last[1], new Complex(degree)).modulus() + new Complex(consts[0][1]).modulus(); + calc = (last[0].modulus() - lbnd) / (ubnd - lbnd); + colortmp = color.splineInterpolated(color.createIndex(calc, lbnd, ubnd), renormalized - (int) renormalized); break; default: throw new IllegalArgumentException("invalid argument"); } - return color; + return colortmp; } public Complex fromCooordinates(int x, int y) { @@ -689,10 +604,9 @@ public void zoom(int cx, int cy, int level) { setCenter_y(cy); setCenter_x(cx); setZoom_factor(level); - int precision = (argand.getHeight() >= argand.getWidth()) ? argand.getWidth() / 2 : argand.getHeight() / 2; - setBase_precision(precision); + //int precision = (argand.getHeight() >= argand.getWidth()) ? argand.getWidth() / 2 : argand.getHeight() / 2; + //setBase_precision(precision); setScale((int) (base_precision * Math.pow(zoom, zoom_factor))); - boundary_points.clear(); - poupulateMap(); + populateMap(); } } \ No newline at end of file diff --git a/src/in/tamchow/fractal/Main.java b/src/in/tamchow/fractal/Main.java index c493c7cb..aafd7f2d 100644 --- a/src/in/tamchow/fractal/Main.java +++ b/src/in/tamchow/fractal/Main.java @@ -1,7 +1,8 @@ package in.tamchow.fractal; import in.tamchow.fractal.config.ConfigReader; -import in.tamchow.fractal.config.color.ColorMode; +import in.tamchow.fractal.config.color.ColorConfig; +import in.tamchow.fractal.config.color.Colors; import in.tamchow.fractal.config.fractalconfig.FractalConfig; import in.tamchow.fractal.math.complex.Complex; import in.tamchow.fractal.platform_tools.ImageConverter; @@ -9,62 +10,39 @@ import javax.imageio.ImageIO; import java.io.File; import java.io.IOException; +import java.util.Random; /** * Main class, handles CMDLINE input. */ public class Main { public static void main(String[] args) { - String func = "( z ^ 3 ) + ( d * z ) + c", variableCode = "z", poly = "{1,z,3};+;{d,z,1};+;{c,z,0}"; - String[][] consts = {{"c", "-0.8,+0.156i"}, {"d", "-0.7198,+0.911i"}}; - int resx = 401, resy = 401, zoom = 10, zoompow = 0, baseprec = 150, colmode = ColorMode.COLOR_NEWTON_1, numcol = 32, coldens = 125, fracmode = FractalGenerator.MODE_NEWTON, iter = 8; - double bound = 2.0, escrad = 2.0, tolerance = 1e-1; + String func = "( z ^ 2 ) + c", variableCode = "z", poly = "{1,z,3};+;{d,z,1};+;{c,z,0}"; + String[][] consts = {{"c", "-0.1,+0.651i"}, {"d", "-0.7198,+0.911i"}}; + int resx = 801, resy = 801, zoom = 10, zoompow = 0, baseprec = 100, fracmode = FractalGenerator.MODE_JULIA, iter = 8; + double escrad = 2.0, tolerance = 1e-1; + ColorConfig cfg = new ColorConfig(Colors.CALCULATIONS.TRIANGLE_AREA_INEQUALITY, 8, 32); Complex constant = null; - func = poly; - boolean fromFile = false; + //func = poly; + boolean def = (args.length == 0); FractalConfig fccfg = new FractalConfig(0, 0, 0); - if (args.length > 1) { - func = args[0]; - consts[0][0] = args[1].substring(0, args[1].indexOf(':')); - consts[0][1] = args[1].substring(args[1].indexOf(':') + 1, args[1].length()); - variableCode = args[2]; - resx = Integer.valueOf(args[3]); - resy = Integer.valueOf(args[4]); - zoom = Integer.valueOf(args[5]); - zoompow = Integer.valueOf(args[6]); - baseprec = Integer.valueOf(args[7]); - colmode = Integer.valueOf(args[8]); - numcol = Integer.valueOf(args[9]); - coldens = Integer.valueOf(args[10]); - fracmode = Integer.valueOf(args[11]); - bound = Double.valueOf(args[12]); - iter = Integer.valueOf(args[13]); - escrad = Double.valueOf(args[14]); - if (args.length >= 16) { - tolerance = Double.valueOf(args[15]); - } - if (args.length == 17) { - constant = new Complex(args[16]); - } - fromFile = false; - } else if (args.length == 1) { + if (!def) { try { fccfg = ConfigReader.getFractalConfigFromFile(new File(args[0])); - fromFile = true; } catch (IOException ioe) { ioe.printStackTrace(); } } long inittime = System.currentTimeMillis(); FractalGenerator jgen; - if (!fromFile) { - jgen = new FractalGenerator(resx, resy, zoom, zoompow, baseprec, colmode, numcol, coldens, fracmode, bound, func, consts, variableCode, tolerance); + if (def) { + jgen = new FractalGenerator(resx, resy, zoom, zoompow, baseprec, fracmode, func, consts, variableCode, tolerance, cfg); } else { jgen = new FractalGenerator(fccfg.getParams()[0]); } long starttime = System.currentTimeMillis(); System.out.println("Initiating fractal took:" + (starttime - inittime) + "ms"); - if (!fromFile) { + if (def) { if (constant != null) { jgen.generate(iter, escrad, constant); } else { @@ -73,34 +51,44 @@ public static void main(String[] args) { } else { jgen.generate(fccfg.getParams()[0]); } - long gentime = System.currentTimeMillis(); System.out.println("Generating fractal took:" + ((double) (gentime - starttime) / 60000) + "mins"); File pic = new File("D:/Fractal.jpg"); File postpic = new File("D:/Fractal_processed.jpg"); try { ImageIO.write(ImageConverter.toImage(jgen.getArgand()), "jpg", pic); - ImageIO.write(ImageConverter.toImage(jgen.getArgand().getColorAveraged()), "jpg", postpic); + //ImageIO.write(ImageConverter.toImage(jgen.getArgand().getColorAveraged()), "jpg", postpic); } catch (Exception e) { e.printStackTrace(); } long endtime = System.currentTimeMillis(); System.out.println("Writing image took:" + (endtime - gentime) + "ms"); - /*ImageData[] imgs={new ImageData("D:/Fractal.png")}; + System.exit(0); + /*ImageData[] imgs={new ImageData("D:/Fractal.jpg")}; int[] trans={-1}; int wait=1; ImageConfig ic=new ImageConfig(5,40,imgs,trans,wait); ImageDisplay.show(ic,"Images");*/ - /*Random random=new Random(); - jgen.zoom(jgen.toCooordinates(jgen.boundary_points.get(random.nextInt(jgen.boundary_points.size())))[0],jgen.toCooordinates(jgen.boundary_points.get(random.nextInt(jgen.boundary_points.size())))[1],2); + Random random = new Random(); + starttime = System.currentTimeMillis(); + int[] coords = jgen.toCooordinates(jgen.getArgand_map()[random.nextInt(resx)][random.nextInt(resy)]); + jgen.zoom(coords[0], coords[1], 1); //jgen.zoom(jgen.getCenter_x(), jgen.getCenter_y(), 1); - jgen.generate(128); - System.out.println(jgen.boundary_points.get(0)); + if (def) { + if (constant != null) { + jgen.generate(iter, escrad, constant); + } else { + jgen.generate(iter, escrad); + } + } else { + jgen.generate(fccfg.getParams()[0]); + } + endtime = System.currentTimeMillis(); + System.out.println("Generating zoomed fractal took:" + ((double) (endtime - starttime) / 60000) + "mins"); try { - ImageIO.write(Image_ImageData.toImage(jgen.getArgand()), "png", zoompic); - + ImageIO.write(ImageConverter.toImage(jgen.getArgand()), "jpg", postpic); } catch (Exception e) { e.printStackTrace(); - }*/ + } } } diff --git a/src/in/tamchow/fractal/config/color/ColorConfig.java b/src/in/tamchow/fractal/config/color/ColorConfig.java index 5e1cde7d..5ca72233 100644 --- a/src/in/tamchow/fractal/config/color/ColorConfig.java +++ b/src/in/tamchow/fractal/config/color/ColorConfig.java @@ -4,22 +4,79 @@ * Holds colour configuration for custom palettes */ public class ColorConfig { - public int basecolor, step, color_density, num_colors; + public int basecolor, step, color_density, num_colors, mode, palette_type; public int[] palette; + boolean colors_corrected; - public ColorConfig(int color_density, int num_colors, int basecolor) { - initColorConfig(color_density, num_colors, basecolor); + public ColorConfig(int mode, int color_density, int num_colors, int basecolor) { + initColorConfig(mode, color_density, num_colors, basecolor); } + public ColorConfig(int mode, int color_density, int num_colors, int basecolor, int step) { + initColorConfig(mode, color_density, num_colors, basecolor, step); + } public ColorConfig(int[] palette) { setPalette(palette, false); } + public ColorConfig(int mode, int color_density, int num_colors) { + initColorConfig(mode, num_colors); + setColor_density(color_density); + } + public ColorConfig() { palette = null; + setPalette_type(Colors.PALETTE.RANDOM); initColorConfig(0, 0, 0x0, 0); } + public ColorConfig(ColorConfig old) { + initColorConfig(old.getMode(), old.getColor_density(), old.getNum_colors(), old.getBasecolor(), old.getStep()); + setPalette(old.getPalette(), false); + colors_corrected = old.colors_corrected; + } + + public int createIndex(double val, double min, double max) { + return (int) Math.abs(((((val - min) / (max - min))) * color_density) % num_colors); + } + + public int getColor(int index) { + return palette[index]; + } + + public int splineInterpolated(int index, double bias) { + if ((!colors_corrected) && num_colors < 4) { + num_colors = 4; + setBasecolor(basecolor); + setColor_density(color_density); + setMode(mode); + setNum_colors(num_colors); + setStep(step); + if (palette_type == Colors.PALETTE.RANDOM) { + initRandomPalette(num_colors, true); + } else { + initGradientPalette(); + } + colors_corrected = true; + } + double h0 = 0.5 * ((bias * bias) * (bias - 1)), + h1 = 0.5 * (bias * (1 + 4 * bias - 3 * (bias * bias))), + h2 = 0.5 * (2 - 5 * (bias * bias) + 3 * (bias * bias * bias)), + h3 = 0.5 * (bias * (2 * bias - (bias * bias) - 1)); + int i1 = ((index - 1) < 0) ? num_colors - 1 : index - 1, i2 = ((index - 2) < 0) ? num_colors - 2 : index - 2, i3 = ((index - 3) < 0) ? num_colors - 3 : index - 3; + double color = (h0 * palette[index] + h1 * palette[i1] + h2 * palette[i2] + h3 * palette[i3]); + color = (color < 0) ? -color : color; + return (int) color; + } + + public int getPalette_type() { + return palette_type; + } + + public void setPalette_type(int palette_type) { + this.palette_type = palette_type; + } + public int getBasecolor() { return basecolor; } @@ -54,6 +111,7 @@ public void setPalette(int[] palette, boolean preserve) { } public void initRandomPalette(int num_colors, boolean preserve) { + setPalette_type(Colors.PALETTE.RANDOM); if (!preserve) { palette = new int[num_colors]; for (int pidx = 0; pidx < num_colors; pidx++) { @@ -71,6 +129,7 @@ public void initRandomPalette(int num_colors, boolean preserve) { } public void initGradientPalette() { + setPalette_type(Colors.PALETTE.CUSTOM); palette = new int[num_colors]; int baseidx = num_colors / 2; for (int i = 0; i < baseidx; i++) { @@ -81,31 +140,32 @@ public void initGradientPalette() { } } - public void initGrayScalePalette(int max) { - palette = new int[max]; - for (int i = 0; i < palette.length; i++) { - palette[i] = i << 16 | i << 8 | i; - } - } - - private void initColorConfig(int color_density, int num_colors, int basecolor, int step) { + private void initColorConfig(int mode, int color_density, int num_colors, int basecolor, int step) { + colors_corrected = false; setColor_density(color_density); setNum_colors(num_colors); setBasecolor(basecolor); setStep(step); initGradientPalette(); + setMode(mode); } - private void initColorConfig(int color_density, int num_colors, int basecolor) { + + private void initColorConfig(int mode, int color_density, int num_colors, int basecolor) { + colors_corrected = false; setColor_density(color_density); setNum_colors(num_colors); setBasecolor(basecolor); calcStep(); initGradientPalette(); + setMode(mode); } - private void initColorConfig(int num_colors) { + private void initColorConfig(int mode, int num_colors) { + colors_corrected = false; + setNum_colors(num_colors); initRandomPalette(num_colors, false); + setMode(mode); } private void calcStep() { @@ -128,31 +188,40 @@ public void setNum_colors(int num_colors) { this.num_colors = num_colors; } + public int getMode() { + return mode; + } + + public void setMode(int mode) { + this.mode = mode; + } + public void colorsFromString(String[] colors) { - if (colors[0].startsWith("0x")) { + mode = Integer.parseInt(colors[0]); + if (colors[1].startsWith("0x")) { int[] palette = new int[colors.length]; - for (int i = 0; i < colors.length; i++) { + for (int i = 1; i < colors.length; i++) { palette[i] = Integer.parseInt(colors[i], 16); } setPalette(palette, false); } else { switch (colors.length) { - case 1: - initColorConfig(Integer.parseInt(colors[0])); - break; - case 3: - initColorConfig(Integer.parseInt(colors[0]), Integer.parseInt(colors[1]), Integer.parseInt(colors[2], 16)); + case 2: + initColorConfig(mode, Integer.parseInt(colors[1])); break; case 4: - initColorConfig(Integer.parseInt(colors[0]), Integer.parseInt(colors[1]), Integer.parseInt(colors[3], 16), Integer.parseInt(colors[2])); + initColorConfig(mode, Integer.parseInt(colors[1]), Integer.parseInt(colors[2]), Integer.parseInt(colors[3], 16)); + break; + case 5: + initColorConfig(mode, Integer.parseInt(colors[1]), Integer.parseInt(colors[2]), Integer.parseInt(colors[4], 16), Integer.parseInt(colors[3])); break; default: - throw new IllegalArgumentException("Unsupoorted Input"); + throw new IllegalArgumentException("Unsupported Input"); } } } public boolean noCustomPalette() { - return palette.length == 0 || palette == null; + return (palette_type == Colors.PALETTE.RANDOM) || (palette.length == 0) || (palette == null); } } diff --git a/src/in/tamchow/fractal/config/color/ColorMode.java b/src/in/tamchow/fractal/config/color/ColorMode.java deleted file mode 100644 index a71f800b..00000000 --- a/src/in/tamchow/fractal/config/color/ColorMode.java +++ /dev/null @@ -1,8 +0,0 @@ -package in.tamchow.fractal.config.color; - -/** - * A few constant values for coloring modes - */ -public class ColorMode { - public static final int COLOR_DIVIDE = 0, COLOR_MULTIPLY = 1, COLOR_HIGH_CONTRAST = 2, COLOR_GRADIENT_DIVERGENT_1 = 3, COLOR_GRADIENT_DIVERGENT_2 = 4, COLOR_RANDOM_DIVERGENT = 5, COLOR_GRAYSCALE = 6, COLOR_NEWTON_1 = 7, COLOR_NEWTON_2 = 8; -} diff --git a/src/in/tamchow/fractal/config/color/Colors.java b/src/in/tamchow/fractal/config/color/Colors.java new file mode 100644 index 00000000..d3df48f1 --- /dev/null +++ b/src/in/tamchow/fractal/config/color/Colors.java @@ -0,0 +1,14 @@ +package in.tamchow.fractal.config.color; + +/** + * A few constant values for coloring modes + */ +public final class Colors { + public static final class CALCULATIONS { + public static final int COLOR_DIVIDE = 0, COLOR_MULTIPLY = 1, COLOR_HIGH_CONTRAST = 2, COLOR_GRAYSCALE = 3, COLOR_NEWTON_1 = 4, COLOR_NEWTON_2 = 5, TRIANGLE_AREA_INEQUALITY = 6, CURVATURE_AVERAGE = 7, STRIPE_AVERAGE = 8; + } + + public static final class PALETTE { + public static final int RANDOM = 0, CUSTOM = 1; + } +} diff --git a/src/in/tamchow/fractal/config/fractalconfig/FractalInitParams.java b/src/in/tamchow/fractal/config/fractalconfig/FractalInitParams.java index 362f048d..5f2c684c 100644 --- a/src/in/tamchow/fractal/config/fractalconfig/FractalInitParams.java +++ b/src/in/tamchow/fractal/config/fractalconfig/FractalInitParams.java @@ -1,7 +1,8 @@ package in.tamchow.fractal.config.fractalconfig; import in.tamchow.fractal.FractalGenerator; -import in.tamchow.fractal.config.color.ColorMode; +import in.tamchow.fractal.config.color.ColorConfig; +import in.tamchow.fractal.config.color.Colors; import java.io.Serializable; @@ -11,34 +12,40 @@ public class FractalInitParams implements Serializable { public String function, variableCode; public String[][] consts; - public int width, height, zoom, zoom_factor, base_precision, color_mode, num_colors, color_density, fractal_mode; - public double boundary_condition, tolerance; + public int width, height, zoom, zoom_factor, base_precision, fractal_mode; + public double tolerance; + public ColorConfig color; public FractalInitParams(FractalInitParams initParams) { - initParams(initParams.width, initParams.height, initParams.zoom, initParams.zoom_factor, initParams.base_precision, initParams.color_mode, initParams.num_colors, initParams.color_density, initParams.fractal_mode, initParams.boundary_condition, initParams.function, initParams.consts, initParams.variableCode, initParams.tolerance); + initParams(initParams.width, initParams.height, initParams.zoom, initParams.zoom_factor, initParams.base_precision, initParams.fractal_mode, initParams.function, initParams.consts, initParams.variableCode, initParams.tolerance, initParams.getColor()); } - public FractalInitParams(int width, int height, int zoom, int zoom_factor, int base_precision, int color_mode, int num_colors, int color_density, int fractal_mode, double boundary_condition, String function, String[][] consts, String variableCode, double tolerance) { - initParams(width, height, zoom, zoom_factor, base_precision, color_mode, num_colors, color_density, fractal_mode, boundary_condition, function, consts, variableCode, tolerance); + public FractalInitParams(int width, int height, int zoom, int zoom_factor, int base_precision, int fractal_mode, String function, String[][] consts, String variableCode, double tolerance, ColorConfig color) { + initParams(width, height, zoom, zoom_factor, base_precision, fractal_mode, function, consts, variableCode, tolerance, color); } public FractalInitParams() { String func = "z ^ 2 + c"; String[][] consts = {{"c", "-0.8,+0.156i"}}; - initParams(1921, 1081, 10, 0, 540, ColorMode.COLOR_DIVIDE, 32, 256, FractalGenerator.MODE_JULIA, 2, func, consts, "z", 1e-5); + ColorConfig cfg = new ColorConfig(Colors.CALCULATIONS.STRIPE_AVERAGE, 32, 256, 0); + initParams(1921, 1081, 10, 0, 540, FractalGenerator.MODE_JULIA, func, consts, "z", 1e-5, cfg); } - private void initParams(int width, int height, int zoom, int zoom_factor, int base_precision, int color_mode, int num_colors, int color_density, int fractal_mode, double boundary_condition, String function, String[][] consts, String variableCode, double tolerance) { + public ColorConfig getColor() { + return new ColorConfig(color); + } + + public void setColor(ColorConfig color) { + this.color = new ColorConfig(color); + } + + private void initParams(int width, int height, int zoom, int zoom_factor, int base_precision, int fractal_mode, String function, String[][] consts, String variableCode, double tolerance, ColorConfig colors) { this.width = width; this.height = height; this.zoom = zoom; this.zoom_factor = zoom_factor; this.base_precision = base_precision; - this.color_mode = color_mode; - this.num_colors = num_colors; - this.color_density = color_density; this.fractal_mode = fractal_mode; - this.boundary_condition = boundary_condition; this.function = function; setConsts(consts); this.variableCode = variableCode; @@ -53,11 +60,18 @@ private void setConsts(String[][] consts) { } public void paramsFromString(String[] params) { - String[][] consts = new String[params.length - 11][2]; - for (int i = 13; i < params.length; i++) { - consts[i - 13][0] = params[i].substring(0, params[i].indexOf(' ')); - consts[i - 13][1] = params[i].substring(params[i].indexOf(' ') + 1, params[i].length()); + String[] con = params[9].split(";"); + String[][] consts = new String[con.length][2]; + for (int i = 0; i < consts.length; i++) { + consts[i][0] = con[i].substring(0, con[i].indexOf(':')); + consts[i][1] = con[i].substring(con[i].indexOf(':') + 1, con[i].length()); + } + String[] colorcfg = new String[params.length - 10]; + for (int i = 0; i < colorcfg.length && (i + 10) < params.length; i++) { + colorcfg[i] = params[i + 10]; } - initParams(Integer.valueOf(params[0]), Integer.valueOf(params[1]), Integer.valueOf(params[2]), Integer.valueOf(params[3]), Integer.valueOf(params[4]), Integer.valueOf(params[5]), Integer.valueOf(params[6]), Integer.valueOf(params[7]), Integer.valueOf(params[8]), Double.valueOf(params[9]), params[10], consts, params[11], Double.valueOf(params[12])); + ColorConfig colorConfig = new ColorConfig(); + colorConfig.colorsFromString(colorcfg); + initParams(Integer.valueOf(params[0]), Integer.valueOf(params[1]), Integer.valueOf(params[2]), Integer.valueOf(params[3]), Integer.valueOf(params[4]), Integer.valueOf(params[5]), params[6], consts, params[7], Double.valueOf(params[8]), colorConfig); } } \ No newline at end of file diff --git a/src/in/tamchow/fractal/math/complex/Complex.java b/src/in/tamchow/fractal/math/complex/Complex.java index daac3928..094b8282 100644 --- a/src/in/tamchow/fractal/math/complex/Complex.java +++ b/src/in/tamchow/fractal/math/complex/Complex.java @@ -1,8 +1,6 @@ package in.tamchow.fractal.math.complex; import java.io.Serializable; -import java.math.RoundingMode; -import java.text.DecimalFormat; /** * Represents a Complex Number as 2 doubles or in cis arg form. Provides utility functions. @@ -83,19 +81,6 @@ public boolean equals(Object complex) { return false; } - public void round() { - try { - DecimalFormat df = new DecimalFormat("00.000000"); - df.setRoundingMode(RoundingMode.HALF_UP); - System.out.println(df.format(ib)); - ib = df.parse(df.format(ib)).doubleValue(); - System.out.println(df.format(a)); - a = df.parse(df.format(a)).doubleValue(); - } catch (Exception e) { - e.printStackTrace(); - } - } - public double arg() { if (a > 0) return Math.atan((ib / a)); else if (a < 0 && ib >= 0) return Math.atan((ib / a)) + Math.PI; diff --git a/src/in/tamchow/fractal/math/matrix/Matrix.java b/src/in/tamchow/fractal/math/matrix/Matrix.java index 840bf381..4921856f 100644 --- a/src/in/tamchow/fractal/math/matrix/Matrix.java +++ b/src/in/tamchow/fractal/math/matrix/Matrix.java @@ -11,6 +11,19 @@ public Matrix(double[][] matrixData) { initMatrix(matrixData.length, matrixData[0].length, matrixData); } + public void fromString(String matrix) { + matrix = matrix.substring(1, matrix.length() - 1);//trim leading and trailing square brackets + String[] rows = matrix.split(";"); + this.rows = rows.length; + this.columns = rows[0].substring(1, rows[0].length() - 1).split(",").length; + matrixData = new double[this.rows][this.columns]; + for (int i = 0; i < matrixData.length && i < rows.length; i++) { + String[] columns = rows[i].substring(1, rows[i].length() - 1).split(","); + for (int j = 0; j < matrixData[i].length && j < columns.length; j++) { + matrixData[i][j] = Double.valueOf(columns[j]); + } + } + } public int getNumRows() { return rows; } diff --git a/src/in/tamchow/fractal/misc/PBrainer.java b/src/in/tamchow/fractal/misc/PBrainer.java index 201114a8..b6fca1a0 100644 --- a/src/in/tamchow/fractal/misc/PBrainer.java +++ b/src/in/tamchow/fractal/misc/PBrainer.java @@ -9,16 +9,16 @@ * A PBrain interpreter */ public class PBrainer { - private static final int SIZE = 65536; String code, codebackup; int[] procidx, operand; - int ptr, proctr, itmp; + int ptr, proctr, itmp, size; public PBrainer() { code = ""; codebackup = code; - procidx = new int[SIZE]; - operand = new int[SIZE]; + size = 65536; + procidx = new int[size]; + operand = new int[size]; for (int i = 0; i < operand.length; i++) { operand[i] = -1; } @@ -32,20 +32,33 @@ public static void main(String[] args) { if (args.length == 0) { throw new IllegalArgumentException("Nothing to interpret"); } - File input = new File(args[0]); - if (!input.exists()) { - System.err.println("File not found, interpreting input"); - executor.code = args[0]; + if (args[0].equalsIgnoreCase("-s")) { + executor.size = Integer.parseInt(args[1]); + if (args[2].equalsIgnoreCase("-f")) { + executor.readFile(args[3]); + } else { + executor.code = args[2]; + } + } else { + if (args[0].equalsIgnoreCase("-f")) { + executor.readFile(args[1]); + } else { + executor.code = args[0]; + } } + executor.execute(); + } + + void readFile(String path) { + File input = new File(path); try { Scanner sc = new Scanner(input); while (sc.hasNextLine()) { - executor.code += sc.nextLine(); + code += sc.nextLine(); } } catch (FileNotFoundException e) { e.printStackTrace(); } - executor.execute(); } public void execute() { @@ -57,31 +70,40 @@ public void execute() { proctr++; break; case '[': + if (code.indexOf(']') == -1) { + System.err.println("Unmatched [ at " + i); + } if (operand[ptr] == 0) { i = code.indexOf(']', i + 1); } continue outer; case ']': + if (code.indexOf('[') == -1) { + System.err.println("Unmatched ] at " + i); + } i = code.lastIndexOf('[', i - 1); continue outer; case ':': - itmp = i + 1; codebackup = code; - code = codebackup.substring(procidx[operand[ptr]], codebackup.indexOf(')', procidx[operand[ptr]])); + itmp = codebackup.indexOf(')', procidx[operand[ptr]]) + 1; + if (itmp - 1 == -1) { + System.err.println("Unmatched ) at " + i); + } + code = codebackup.substring(procidx[operand[ptr]], codebackup.indexOf(')', itmp - 1)); execute(); i = itmp; code = codebackup; continue outer; case '<': if (ptr - 1 < 0) { - ptr = 0; + ptr = size - 1; } else { --ptr; } break; case '>': - if (ptr + 1 > SIZE) { - ptr = SIZE; + if (ptr + 1 > size) { + ptr = 0; } else { ++ptr; } @@ -96,7 +118,7 @@ public void execute() { try { operand[ptr] = System.in.read(); } catch (IOException e) { - e.printStackTrace(); + System.err.print("Input error: " + e.getMessage()); } break; case '.':