diff --git a/src/main/java/edu/ntnu/stud/chaosgame/Main.java b/src/main/java/edu/ntnu/stud/chaosgame/Main.java index 5772ad92755b69bbed5a3ec0dc6caff8ad2dd744..2d0d60704c296c1e51d6caf77ae428e0dd34474d 100644 --- a/src/main/java/edu/ntnu/stud/chaosgame/Main.java +++ b/src/main/java/edu/ntnu/stud/chaosgame/Main.java @@ -18,26 +18,7 @@ public class Main { public static void main(String[] args) { System.out.println("Hi"); - String path = "src/main/resources/descriptions/TestDescription.txt"; - - - Vector2D minCoords = new Vector2D(0, 0); - Vector2D maxCoords = new Vector2D(1, 1); - - Matrix2x2 transformMatrix1 = new Matrix2x2(0.5, 0, 0, 0.5); - - Vector2D translationVector1 = new Vector2D(0, 0); - Vector2D translationVector2 = new Vector2D(0.25, 0.5); - Vector2D translationVector3 = new Vector2D(0.5, 0); - - AffineTransform2D affineTransform1 = new AffineTransform2D(transformMatrix1, translationVector1); - AffineTransform2D affineTransform2 = new AffineTransform2D(transformMatrix1, translationVector2); - AffineTransform2D affineTransform3 = new AffineTransform2D(transformMatrix1, translationVector3); - - List<Transform2D> transforms = new ArrayList<>(); - transforms.add(affineTransform1); - transforms.add(affineTransform2); - transforms.add(affineTransform3); + String path = "src/main/resources/descriptions/Sierpinski.txt"; ChaosGameDescription description = null; // Declare description @@ -47,14 +28,13 @@ public class Main { //ChaosGameDescription description = new ChaosGameFileHandler().readFromFile(path); //description = new ChaosGameDescription(minCoords, maxCoords, transforms); description = new ChaosGameFileHandler().readFromFile(path); - System.out.println("MaxCoords-object of description: " + description.getMaxCoords()); ChaosCanvas canvas = new ChaosCanvas(100, 100, description.getMinCoords(), description.getMaxCoords()); // Create canvas game = new ChaosGame(description, canvas); } catch (Exception e) { System.out.println(e.getMessage()); // TODO: Alter error handling } - //game.runSteps(100000); + game.runSteps(100000); diff --git a/src/main/java/edu/ntnu/stud/chaosgame/game/ChaosGameFileHandler.java b/src/main/java/edu/ntnu/stud/chaosgame/game/ChaosGameFileHandler.java index 41950f3eaad5e220863a31643681853261c77a14..419eb9f33cd99fd46f743a713aa436b503556ade 100644 --- a/src/main/java/edu/ntnu/stud/chaosgame/game/ChaosGameFileHandler.java +++ b/src/main/java/edu/ntnu/stud/chaosgame/game/ChaosGameFileHandler.java @@ -6,17 +6,14 @@ import edu.ntnu.stud.chaosgame.model.Vector2D; import edu.ntnu.stud.chaosgame.model.transformations.AffineTransform2D; import edu.ntnu.stud.chaosgame.model.transformations.JuliaTransform; import edu.ntnu.stud.chaosgame.model.transformations.Transform2D; -import java.io.FileNotFoundException; + import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.Scanner; -import java.util.logging.Logger; +import java.util.*; + import java.io.BufferedWriter; public class ChaosGameFileHandler { @@ -33,54 +30,54 @@ public class ChaosGameFileHandler { Path paths = Paths.get(path); - try (Scanner scanner = new Scanner(Files.newInputStream(paths))){ - scanner.useLocale(Locale.ENGLISH); // useLocale ensures periods in decimal numbers - scanner.useDelimiter("\\s*,\\s*|\\r?|#[^\\n]"); // useDelimiter with regular expression skips comments + try (Scanner scanner = new Scanner(Files.newInputStream(paths))) { + scanner.useLocale(Locale.ENGLISH); + + // Use a delimiter that splits on commas and new lines, and ignores comment lines. + scanner.useDelimiter("\\s*,\\s*|\\s*\\r?\\n+\\s*|(?m)^#.*$"); + String firstLine = scanner.nextLine().trim(); - if (!firstLine.startsWith("Affine2D") && !firstLine.startsWith("Julia")){ - throw new IllegalStateException("Invalid Chaos Game"); + if (!firstLine.equals("Affine2D")) { + throw new IllegalStateException("Invalid Chaos Game, expected 'Affine2D'."); } - double x0min = scanner.nextDouble(); - double x1min = scanner.nextDouble(); - minimumVector = new Vector2D(x0min,x1min); - - double x0max = scanner.nextDouble(); - double x1max = scanner.nextDouble(); - maximumVector = new Vector2D(x0max,x1max); - - - while(scanner.hasNextDouble()){ - - if (firstLine.startsWith("Affine2D")){ - for (int i = 0; i < 3; i++) { - double a00 = scanner.nextDouble(); - double a01 = scanner.nextDouble(); - double a10 = scanner.nextDouble(); - double a11 = scanner.nextDouble(); - Matrix2x2 matrix2x2 = new Matrix2x2(a00, a01, a10, a11); - - double b0 = scanner.nextDouble(); - double b1 = scanner.nextDouble(); - Vector2D vector2D = new Vector2D(b0, b1); - - Transform2D transform2D = new AffineTransform2D(matrix2x2, vector2D); - transforms.add(transform2D); - } - } else if(firstLine.startsWith("Julia")){ - double realOfComplex = scanner.nextDouble(); - double imaginaryOfComplex = scanner.nextDouble(); - Complex complex = new Complex(realOfComplex,imaginaryOfComplex); - Transform2D juliaTransformPositive = new JuliaTransform(complex,1); - Transform2D juliaTransformNegative = new JuliaTransform(complex,-1); - transforms.add(juliaTransformPositive); - transforms.add(juliaTransformNegative); - } + + // Read the minimum vector + if (scanner.hasNextDouble()) { + double x0min = scanner.nextDouble(); + double x1min = scanner.nextDouble(); + minimumVector = new Vector2D(x0min, x1min); + } else { + throw new IllegalArgumentException("Expected minimum vector coordinates."); } - return new ChaosGameDescription(minimumVector,maximumVector,transforms); - } - catch (IOException e){ - throw new IOException("Failure to read file",e); + + // Read the maximum vector + if (scanner.hasNextDouble()) { + double x0max = scanner.nextDouble(); + double x1max = scanner.nextDouble(); + maximumVector = new Vector2D(x0max, x1max); + } else { + throw new IllegalArgumentException("Expected maximum vector coordinates."); + } + + // Read the transforms + while (scanner.hasNextDouble()) { + double a00 = scanner.nextDouble(); + double a01 = scanner.nextDouble(); + double a10 = scanner.nextDouble(); + double a11 = scanner.nextDouble(); + double b0 = scanner.nextDouble(); + double b1 = scanner.nextDouble(); + + Matrix2x2 matrix2x2 = new Matrix2x2(a00, a01, a10, a11); + Vector2D vector2D = new Vector2D(b0, b1); + Transform2D transform2D = new AffineTransform2D(matrix2x2, vector2D); + transforms.add(transform2D); + } + } catch (IOException e) { + throw new IOException("Failure to read file", e); } + + return new ChaosGameDescription(minimumVector, maximumVector, transforms); } /** @@ -88,7 +85,7 @@ public class ChaosGameFileHandler { * @param description A {@link ChaosGameDescription} description of the chaos game that should be written to file. * @param path A String describing the path to the file that should be written to. */ - public void writeToFile(ChaosGameDescription description, String path){ + public void writeToFile(ChaosGameDescription description, String path) throws IOException{ List<Transform2D> transforms = description.getTransforms(); try (BufferedWriter writer = new BufferedWriter(new FileWriter(path))){ @@ -100,26 +97,25 @@ public class ChaosGameFileHandler { } Vector2D minVector2D = description.getMinCoords(); Vector2D maxVector2D = description.getMaxCoords(); - writer.write(minVector2D.getX0() + "," + minVector2D.getX1()); - writer.write(maxVector2D + ", " + minVector2D); + writer.write(minVector2D.getX0() + ", " + minVector2D.getX1() + "\n"); + writer.write(maxVector2D.getX0() + ", " + maxVector2D.getX1() + "\n"); for(Transform2D transform : transforms){ if (transform instanceof AffineTransform2D affineTransform2D) { Matrix2x2 matrix2x2 = affineTransform2D.getMatrix(); Vector2D vector2D = affineTransform2D.getVector(); writer.write(matrix2x2.getA00() + ", " + matrix2x2.getA01() + ", " + matrix2x2.getA10() + ", " - + matrix2x2.getA11() + ", " + vector2D.getX0() + ", " + vector2D.getX1()); + + matrix2x2.getA11() + ", " + vector2D.getX0() + ", " + vector2D.getX1() + "\n"); } else if (transform instanceof JuliaTransform juliaTransform){ Complex complex = juliaTransform.getC1(); - writer.write(complex.getX0() + ", " + complex.getX1() + ", "); + writer.write(complex.getX0() + ", " + complex.getX1() + "\n"); } } } catch (IOException e) { - // Maybe replace with logger later based on SolarLint - System.out.println("File writing failure on path:" + path + "with error message:" + e.getMessage()); + throw new IOException("Failure to write to file", e); } } diff --git a/src/main/java/edu/ntnu/stud/chaosgame/model/handling/ChaosGame.java b/src/main/java/edu/ntnu/stud/chaosgame/model/handling/ChaosGame.java index 4d7275fd52ea8943b11fb7d792686aa5d4090c45..2c29decbb18fce49912db70aa8ecdbec96c8111b 100644 --- a/src/main/java/edu/ntnu/stud/chaosgame/model/handling/ChaosGame.java +++ b/src/main/java/edu/ntnu/stud/chaosgame/model/handling/ChaosGame.java @@ -62,7 +62,7 @@ public class ChaosGame { for (int i = 0; i < n; i++) { int j = this.random.nextInt(0, this.numOfTransforms); this.currentPoint = this.description.getTransforms().get(j).transform(currentPoint); - System.out.println(currentPoint.getX0() + " " + currentPoint.getX1()); + //System.out.println(currentPoint.getX0() + " " + currentPoint.getX1()); this.canvas.putPixel(currentPoint); } this.canvas.printCanvas(); diff --git a/src/main/resources/descriptions/Sierpinski.txt b/src/main/resources/descriptions/Sierpinski.txt new file mode 100644 index 0000000000000000000000000000000000000000..e98ca28363edecbfbb6f8cd7b0f4b3a80b6a3006 --- /dev/null +++ b/src/main/resources/descriptions/Sierpinski.txt @@ -0,0 +1,6 @@ +Affine2D +0.0, 0.0 +1.0, 1.0 +0.5, 0.0, 0.0, 0.5, 0.0, 0.0 +0.5, 0.0, 0.0, 0.5, 0.25, 0.5 +0.5, 0.0, 0.0, 0.5, 0.5, 0.0