diff --git a/src/main/java/edu/Main.java b/src/main/java/edu/Main.java
deleted file mode 100644
index 323f96f..0000000
--- a/src/main/java/edu/Main.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package edu;
-
-import edu.project4.ImageFormat;
-import edu.project4.ImageUtils;
-import edu.project4.processor.GammaCorrection;
-import edu.project4.processor.ImageProcessor;
-import edu.project4.render.FractalFlameConfiguration;
-import edu.project4.render.MultiThreadRenderer;
-import edu.project4.render.Renderer;
-import edu.project4.render.SingleThreadRenderer;
-import edu.project4.transformation.DiskTransformation;
-import edu.project4.transformation.SinusoidalTransformation;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.List;
-import java.util.Random;
-
-public final class Main {
- private final static Logger LOGGER = LogManager.getLogger();
- static Random random = new Random();
-
- private Main() {
- }
-
- public static void main(String[] args) throws IOException {
-// long time3 = System.nanoTime();
-// Renderer renderer1 = new SingleThreadRenderer();
-// var image1 = renderer1.render(
-// new FractalFlameConfiguration(1920, 1080, 20000, 1000, 1),
-// List.of(new SinusoidalTransformation())
-// );
-// ImageProcessor processor1 = new GammaCorrection(2.2);
-// processor1.process(image1);
-// ImageUtils.print(image1);
-// long time4 = System.nanoTime() - time3;
-// System.out.println("single-threaded time: " + ((time4) / 1000000) + " milisec");
- for (int i = 2; i < 6; i++) {
- long time1 = System.nanoTime();
- Renderer renderer = new MultiThreadRenderer(i);
- var image = renderer.render(
- new FractalFlameConfiguration(1920, 1080, 20000, 1000, 1),
- List.of(new SinusoidalTransformation())
- );
- ImageProcessor processor = new GammaCorrection(2.2);
- processor.process(image);
- ImageUtils.print(image);
- long time2 = System.nanoTime() - time1;
- System.out.println("multi-threaded time " + i + " threads: " + ((time2) / 1000000) + " milisec");
- }
- }
-}
diff --git a/src/main/java/edu/project4/ImageUtils.java b/src/main/java/edu/project4/ImageUtils.java
index acdfad2..866081b 100644
--- a/src/main/java/edu/project4/ImageUtils.java
+++ b/src/main/java/edu/project4/ImageUtils.java
@@ -20,13 +20,11 @@ private ImageUtils() {
public static void save(FractalImage image, Path filename, ImageFormat format) throws IOException {
BufferedImage bufferedImage = convertFractalToBuffered(image);
- String fileFormat;
- switch (format) {
- case ImageFormat.BMP -> fileFormat = "bmp";
- case ImageFormat.JPEG -> fileFormat = "jpeg";
- default -> fileFormat = "png";
- }
- filename = Path.of(String.format("%s.%s",filename.toString(), fileFormat));
+ String fileFormat = switch (format) {
+ case ImageFormat.BMP -> "bmp";
+ case ImageFormat.JPEG -> "jpeg";
+ default -> "png";
+ };
ImageIO.write(bufferedImage, fileFormat, filename.toFile());
}
diff --git a/src/main/java/edu/project4/processor/GammaCorrection.java b/src/main/java/edu/project4/processor/GammaCorrection.java
index aed3431..2ec42dd 100644
--- a/src/main/java/edu/project4/processor/GammaCorrection.java
+++ b/src/main/java/edu/project4/processor/GammaCorrection.java
@@ -5,7 +5,7 @@
import static java.lang.Math.log10;
import static java.lang.Math.pow;
-public class GammaCorrection implements ImageProcessor{
+public class GammaCorrection implements ImageProcessor {
private final double gamma;
private double maxNormal;
@@ -19,7 +19,8 @@ public void process(FractalImage image) {
setNormals(image);
changeBrightness(image);
}
- private void setNormals(FractalImage image){
+
+ private void setNormals(FractalImage image) {
var pixels = image.pixels();
for (int row = 0; row < image.height(); row++) {
for (int col = 0; col < image.width(); col++) {
@@ -34,12 +35,13 @@ private void setNormals(FractalImage image){
}
}
}
- private void changeBrightness(FractalImage image){
+
+ private void changeBrightness(FractalImage image) {
var pixels = image.pixels();
for (int row = 0; row < image.height(); row++) {
for (int col = 0; col < image.width(); col++) {
Pixel pixel = pixels[row][col];
- if(pixel.hitCount() != 0){
+ if (pixel.hitCount() != 0) {
double normal = pixel.normal() / maxNormal;
int r = (int) (pixel.r() * pow(normal, (1.0 / gamma)));
int g = (int) (pixel.g() * pow(normal, (1.0 / gamma)));
diff --git a/src/main/java/edu/project4/render/ConcurrentPixelTwoDimensionalArray.java b/src/main/java/edu/project4/render/ConcurrentPixelTwoDimensionalArray.java
index e11de43..c20db3b 100644
--- a/src/main/java/edu/project4/render/ConcurrentPixelTwoDimensionalArray.java
+++ b/src/main/java/edu/project4/render/ConcurrentPixelTwoDimensionalArray.java
@@ -1,8 +1,6 @@
package edu.project4.render;
import edu.project4.Pixel;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Two-dimensional array of objects
@@ -10,7 +8,6 @@
* Warning: The number of columns must be the same
*/
public class ConcurrentPixelTwoDimensionalArray {
- private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Pixel[][] array;
public ConcurrentPixelTwoDimensionalArray(int rows, int columns) {
diff --git a/src/main/java/edu/project4/render/MultiThreadRenderer.java b/src/main/java/edu/project4/render/MultiThreadRenderer.java
index 0630c8b..ce9caba 100644
--- a/src/main/java/edu/project4/render/MultiThreadRenderer.java
+++ b/src/main/java/edu/project4/render/MultiThreadRenderer.java
@@ -4,18 +4,19 @@
import edu.project4.FractalImage;
import edu.project4.Pixel;
import edu.project4.transformation.Transformation;
-import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class MultiThreadRenderer implements Renderer {
- private static final Random random = new Random();
+ private final static Random RANDOM = new Random();
+ private final static int AFFINE_FACTORS = 5;
+ private final static int MAX_WAITING_MINUTES_FOR_RENDERER = 3;
- private final int threadCount;
+ private int threadCount;
public MultiThreadRenderer(int threadCount) {
this.threadCount = threadCount;
@@ -24,18 +25,20 @@ public MultiThreadRenderer(int threadCount) {
@Override
public FractalImage render(FractalFlameConfiguration configuration, List variations) {
ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
- Transformation transformation = variations.get(random.nextInt(0, variations.size()));
+ Transformation transformation = variations.get(RANDOM.nextInt(0, variations.size()));
int xResolution = configuration.width();
int yResolution = configuration.height();
var pixels = createInitialPixels(xResolution, yResolution);
- var affineFactors = createFactors(5);
+ var affineFactors = createFactors(AFFINE_FACTORS);
AtomicInteger sample = new AtomicInteger(0);
for (int i = 0; i < threadCount; i++) {
executorService.execute(new RenderThread(configuration, affineFactors, transformation, pixels, sample));
}
executorService.shutdown();
- while (!executorService.isTerminated()) {
-
+ try {
+ executorService.awaitTermination(MAX_WAITING_MINUTES_FOR_RENDERER, TimeUnit.MINUTES);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
}
return new FractalImage(pixels.toArray(), xResolution, yResolution);
}
@@ -69,10 +72,11 @@ private ConcurrentPixelTwoDimensionalArray createInitialPixels(int width, int he
}
private double randomFactor() {
- return random.nextDouble(-1, 1);
+ return RANDOM.nextDouble(-1, 1);
}
+ @SuppressWarnings("MagicNumber")
private int randomColor() {
- return random.nextInt(64, 256) + 64;
+ return RANDOM.nextInt(64, 256) + 64;
}
}
diff --git a/src/main/java/edu/project4/render/RenderThread.java b/src/main/java/edu/project4/render/RenderThread.java
index b13afbc..8170b0a 100644
--- a/src/main/java/edu/project4/render/RenderThread.java
+++ b/src/main/java/edu/project4/render/RenderThread.java
@@ -9,11 +9,12 @@
public class RenderThread implements Runnable {
- private static final Point POINT_MIN = new Point(-1.777, -1.0);
- private static final Point POINT_MAX = new Point(1.777, 1.0);
- private static final double RANGE_X = POINT_MAX.x() - POINT_MIN.x();
- private static final double RANGE_Y = POINT_MAX.y() - POINT_MIN.y();
- private static final Random random = new Random();
+ private final static Point POINT_MIN = new Point(-1.777, -1.0);
+ private final static Point POINT_MAX = new Point(1.777, 1.0);
+ private final static double RANGE_X = POINT_MAX.x() - POINT_MIN.x();
+ private final static double RANGE_Y = POINT_MAX.y() - POINT_MIN.y();
+ private final static Random RANDOM = new Random();
+ private final static int SKIP_ITERATIONS = 20;
private final FractalFlameConfiguration configuration;
private final AffineFactorContainer[] affineFactors;
@@ -42,8 +43,8 @@ public void run() {
for (; sample.get() < configuration.samples(); sample.incrementAndGet()) {
Point next = randomPoint();
- for (int iter = -20; iter < configuration.iterPerSample(); iter++) {
- int iterAffineFactors = random.nextInt(0, affineFactors.length);
+ for (int iter = -SKIP_ITERATIONS; iter < configuration.iterPerSample(); iter++) {
+ int iterAffineFactors = RANDOM.nextInt(0, affineFactors.length);
Point linear = computeLinear(affineFactors[iterAffineFactors], next);
Point nonLinear = transformation.apply(linear);
next = nonLinear;
@@ -58,7 +59,7 @@ public void run() {
int x1 = xResolution - (int) (((POINT_MAX.x() - rotated.x()) / (RANGE_X)) * xResolution);
int y1 = yResolution - (int) (((POINT_MAX.y() - rotated.y()) / (RANGE_Y)) * yResolution);
if (x1 < xResolution && y1 < yResolution) {
- Pixel updatedPixel = getNewColor(pixels.get(y1,x1), affineFactors[iterAffineFactors]);
+ Pixel updatedPixel = getNewColor(pixels.get(y1, x1), affineFactors[iterAffineFactors]);
pixels.set(y1, x1, updatedPixel);
}
}
@@ -83,10 +84,11 @@ private Pixel getNewColor(Pixel pixel, AffineFactorContainer factors) {
}
return new Pixel(r, g, b, pixel.hitCount() + 1, 0);
}
- private Point randomPoint(){
- double newX = random.nextDouble(POINT_MIN.x(), POINT_MAX.x());
- double newY = random.nextDouble(POINT_MIN.y(), POINT_MAX.y());
- return new Point(newX,newY);
+
+ private Point randomPoint() {
+ double newX = RANDOM.nextDouble(POINT_MIN.x(), POINT_MAX.x());
+ double newY = RANDOM.nextDouble(POINT_MIN.y(), POINT_MAX.y());
+ return new Point(newX, newY);
}
private Point computeLinear(AffineFactorContainer factors, Point next) {
diff --git a/src/main/java/edu/project4/render/Renderer.java b/src/main/java/edu/project4/render/Renderer.java
index 3b9cdbc..022a87e 100644
--- a/src/main/java/edu/project4/render/Renderer.java
+++ b/src/main/java/edu/project4/render/Renderer.java
@@ -6,5 +6,5 @@
@FunctionalInterface
public interface Renderer {
- public FractalImage render(FractalFlameConfiguration configuration, List variations);
+ FractalImage render(FractalFlameConfiguration configuration, List variations);
}
diff --git a/src/main/java/edu/project4/render/SingleThreadRenderer.java b/src/main/java/edu/project4/render/SingleThreadRenderer.java
index 9c45e03..4d6ddca 100644
--- a/src/main/java/edu/project4/render/SingleThreadRenderer.java
+++ b/src/main/java/edu/project4/render/SingleThreadRenderer.java
@@ -9,11 +9,14 @@
import java.util.Random;
public class SingleThreadRenderer implements Renderer {
- private static final Random random = new Random();
- private static final Point POINT_MIN = new Point(-1.777, -1.0);
- private static final Point POINT_MAX = new Point(1.777, 1.0);
- private static final double RANGE_X = POINT_MAX.x() - POINT_MIN.x();
- private static final double RANGE_Y = POINT_MAX.y() - POINT_MIN.y();
+ private final static Point POINT_MIN = new Point(-1.777, -1.0);
+ private final static Point POINT_MAX = new Point(1.777, 1.0);
+ private final static double RANGE_X = POINT_MAX.x() - POINT_MIN.x();
+ private final static double RANGE_Y = POINT_MAX.y() - POINT_MIN.y();
+ private final static int SKIP_ITERATIONS = 20;
+ private final static int AFFINE_FACTORS = 5;
+
+ private final Random random = new Random();
@Override
public FractalImage render(FractalFlameConfiguration configuration, List variations) {
@@ -21,11 +24,11 @@ public FractalImage render(FractalFlameConfiguration configuration, List