Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.List;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Set;
- import java.util.Random;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.nio.file.Paths;
- import javax.imageio.ImageIO;
- import java.awt.Color;
- import java.awt.Graphics2D;
- import java.awt.Rectangle;
- import java.awt.image.BufferedImage;
- import java.io.IOException;
- public class CartesianPoint {
- public final double X;
- public final double Y;
- public CartesianPoint(double X, double Y) {
- this.X = X;
- this.Y = Y;
- }
- @Override
- public String toString() {
- return String.format("(%f, %f)", X, Y);
- }
- }
- public class ScreenPoint {
- public final int X;
- public final int Y;
- public ScreenPoint(int X, int Y) {
- this.X = X;
- this.Y = Y;
- }
- @Override
- public String toString() {
- return String.format("(%d, %d", X, Y);
- }
- }
- public class Coefficients {
- public final double a;
- public final double b;
- public final double c;
- public final double d;
- public final double e;
- public final double f;
- public Coefficients(double a, double b, double c, double d, double e, double f) {
- this.a = a;
- this.b = b;
- this.c = c;
- this.d = d;
- this.e = e;
- this.f = f;
- }
- public Coefficients(String[] arr) {
- if (arr.length != 6) {
- throw new IllegalArgumentException("Expected arguments: 6. Found: " + arr.length);
- }
- double[] temp = new double[6];
- for (int i = 0; i < 6; i++) {
- temp[i] = Double.parseDouble(arr[i]);
- }
- this.a = temp[0];
- this.b = temp[1];
- this.c = temp[2];
- this.d = temp[3];
- this.e = temp[4];
- this.f = temp[5];
- }
- public CartesianPoint translate(CartesianPoint cpoint) {
- double x = cpoint.X, y = cpoint.Y;
- return new CartesianPoint(a*x + b*y + e, c*x + d*y + f);
- }
- }
- public class Utils {
- private static final Random RANDOM = new Random();
- public static WeightedRandomizer<Coefficients> parseInput(List<String> rawData) {
- List<String[]> arr_list = new ArrayList<>();
- for (String r : rawData) {
- if (r.isEmpty()) {
- continue;
- }
- arr_list.add(r.trim().split("\\s+"));
- }
- Map<Coefficients, Double> map = new HashMap<>();
- int len = arr_list.get(0).length;
- for (String[] arr : arr_list) {
- int cur_len = arr.length;
- if (cur_len != 6 && cur_len != 7) {
- throw new IllegalArgumentException("All coefficients sets need to be of length 6 or 7");
- }
- if (cur_len != len) {
- throw new IllegalArgumentException("Inconsistent number of coefficients in each set");
- }
- if (cur_len == 6) {
- map.put(new Coefficients(arr), 1.0);
- } else {
- map.put(new Coefficients(Arrays.copyOfRange(arr, 0, 6)), Double.parseDouble(arr[6]));
- }
- }
- return new WeightedRandomizer<>(map);
- }
- public static List<ScreenPoint> translatePoints(List<CartesianPoint> points, int width, int height) {
- CartesianPoint first = points.get(0);
- double min_x = first.X, max_x = first.X;
- double min_y = first.Y, max_y = first.Y;
- for (CartesianPoint point : points) {
- double x = point.X, y = point.Y;
- if (x < min_x)
- min_x = x;
- if (x > max_x)
- max_x = x;
- if (y < min_y)
- min_y = y;
- if (y > max_y) {
- max_y = y;
- }
- }
- double dx = max_x - min_x, dy = max_y - min_y;
- List<ScreenPoint> result = new ArrayList<>();
- for (CartesianPoint point : points) {
- int sx = (int)(width * (point.X - min_x) / dx);
- int sy = (int)(height * (max_y - point.Y) / dy);
- result.add(new ScreenPoint(sx, sy));
- }
- return result;
- }
- public static List<CartesianPoint> generatePoints(CartesianPoint startingPoint,
- int numOfPoints, int skipFirst,
- WeightedRandomizer<Coefficients> randomizer) {
- List<CartesianPoint> result = new ArrayList<>();
- for (int i = 0; i < skipFirst; i++) {
- startingPoint = randomizer.choice().translate(startingPoint);
- }
- for (int i = 0, end = numOfPoints - skipFirst; i < end; i++) {
- startingPoint = randomizer.choice().translate(startingPoint);
- result.add(startingPoint);
- }
- return result;
- }
- public static List<CartesianPoint> generatePoints(int numOfPoints, int skipFirst,
- WeightedRandomizer<Coefficients> randomizer) {
- return generatePoints(new CartesianPoint(1, 1), numOfPoints, skipFirst, randomizer);
- }
- public static int randomColor() {
- return RANDOM.nextInt(16777216) - 16777216;
- }
- }
- public class WeightedRandomizer <T> {
- private Set<Map.Entry<T, Double>> lookup;
- private double total = 0;
- public WeightedRandomizer(Map<T, Double> map) {
- Map<T, Double> tempMap = new HashMap<>();
- for (Map.Entry<T, Double> entry : map.entrySet()) {
- total += entry.getValue();
- tempMap.put(entry.getKey(), total);
- }
- this.lookup = tempMap.entrySet();
- }
- public T choice() {
- double r = Math.random() * total;
- for (Map.Entry<T, Double> entry : this.lookup) {
- if (entry.getValue() > r) {
- return entry.getKey();
- }
- }
- throw new IllegalArgumentException();
- }
- }
- public class IFSImageBuilder {
- private final double PHI = 1.618033988749895;
- private Path coefficientsPath;
- private Path savePath;
- private Integer width;
- private Integer height;
- private Integer numberOfPixels;
- private Integer borderSize;
- private Integer skipFirst;
- private Color fractalColor = Color.BLACK;
- private Color backgroundColor = Color.WHITE;
- private boolean timing = true;
- private boolean rainbow = false;
- public IFSImageBuilder setCoefficientsPath(Path coefficientsPath) {
- this.coefficientsPath = coefficientsPath;
- return this;
- }
- public IFSImageBuilder setCoefficientsPath(String coefficientsPath) {
- setCoefficientsPath(Paths.get(coefficientsPath));
- return this;
- }
- public IFSImageBuilder setSavePath(Path savePath) {
- this.savePath = savePath;
- return this;
- }
- public IFSImageBuilder setSavePath(String savePath) {
- setSavePath(Paths.get(savePath));
- return this;
- }
- public IFSImageBuilder setWidth(Integer width) {
- this.width = width;
- return this;
- }
- public IFSImageBuilder setHeight(Integer height) {
- this.height = height;
- return this;
- }
- public IFSImageBuilder setNumberOfPixels(Integer numberOfPixels) {
- this.numberOfPixels = numberOfPixels;
- return this;
- }
- public IFSImageBuilder setBorderSize(Integer borderSize) {
- this.borderSize = borderSize;
- return this;
- }
- public IFSImageBuilder setSkipFirst(Integer skipFirst) {
- this.skipFirst = skipFirst;
- return this;
- }
- public IFSImageBuilder setFractalColor(Color fractalColor) {
- this.fractalColor = fractalColor;
- this.rainbow = false;
- return this;
- }
- public IFSImageBuilder setBackgroundColor(Color backgroundColor) {
- this.backgroundColor = backgroundColor;
- return this;
- }
- public IFSImageBuilder setTiming(boolean timing) {
- this.timing = timing;
- return this;
- }
- public IFSImageBuilder setRainbow(boolean rainbow) {
- this.rainbow = rainbow;
- return this;
- }
- public IFSImage build() {
- if (width == null && height == null) {
- throw new IllegalArgumentException("Missing of the following: width, height");
- }
- if (width == null) {
- width = (int)(height * PHI);
- } else if (height == null) {
- height = (int)(width * PHI);
- }
- if (numberOfPixels == null) {
- numberOfPixels = width * height;
- }
- if (borderSize == null) {
- borderSize = (int)(0.05 * Math.min(width, height));
- }
- if (skipFirst == null) {
- skipFirst = (int)(0.005 * numberOfPixels);
- }
- return new IFSImage(coefficientsPath, width, height, borderSize, numberOfPixels, skipFirst,
- fractalColor, backgroundColor, savePath, timing, rainbow);
- }
- }
- public class IFSImage {
- private IFSImage() { }
- private Path coefficientsPath;
- private Path savePath;
- private int width;
- private int height;
- private int borderSize;
- private int numberOfPixels;
- private int skipFirst;
- private Color fractalColor;
- private Color backgroundColor;
- private boolean timing;
- private boolean rainbow;
- public IFSImage(Path coefficientsPath, int width, int height, int borderSize,
- int numberOfPixels, int skipFirst,
- Color fractalColor, Color backgroundColor,
- Path savePath, boolean timing, boolean rainbow) {
- this.coefficientsPath = coefficientsPath;
- this.width = width;
- this.height = height;
- this.borderSize = borderSize;
- this.numberOfPixels = numberOfPixels;
- this.skipFirst = skipFirst;
- this.fractalColor = fractalColor;
- this.backgroundColor = backgroundColor;
- this.savePath = savePath;
- this.timing = timing;
- this.rainbow = rainbow;
- }
- public void save() throws IOException {
- long start = 0;
- if (timing) {
- start = System.nanoTime();
- }
- int img_width = width + 2*borderSize;
- int img_height = height + 2*borderSize;
- BufferedImage img = new BufferedImage(img_width, img_height, BufferedImage.TYPE_INT_RGB);
- if (!backgroundColor.equals(Color.BLACK)) {
- Graphics2D graphics = img.createGraphics();
- graphics.setColor(backgroundColor);
- graphics.fill(new Rectangle(0, 0, img_width, img_height));
- graphics.dispose();
- }
- List<String> rawData = Files.readAllLines(coefficientsPath);
- WeightedRandomizer<Coefficients> randomizer = Utils.parseInput(rawData);
- List<CartesianPoint> cartesianPoints = Utils.generatePoints(numberOfPixels, skipFirst, randomizer);
- List<ScreenPoint> screenPoints = Utils.translatePoints(cartesianPoints, width, height);
- if (rainbow) {
- for (ScreenPoint point : screenPoints) {
- int color = Utils.randomColor();
- img.setRGB(point.X + borderSize, point.Y + borderSize, color);
- }
- }
- else {
- int fractalColor_int = fractalColor.getRGB();
- for (ScreenPoint point : screenPoints) {
- img.setRGB(point.X + borderSize, point.Y + borderSize, fractalColor_int);
- }
- }
- ImageIO.write(img, "png", savePath.toFile());
- if (timing) {
- double total = (double)(System.nanoTime() - start) / 1e9;
- System.out.printf("Fractal generated in %.4f s", total);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement