Skip to content
Snippets Groups Projects
Commit 9f2f8260 authored by LABOUREL Arnaud's avatar LABOUREL Arnaud
Browse files

New version with hamcrest

parent 44d01dad
No related branches found
No related tags found
No related merge requests found
...@@ -8,15 +8,13 @@ javafx { ...@@ -8,15 +8,13 @@ javafx {
modules = [ 'javafx.controls', 'javafx.fxml' ] modules = [ 'javafx.controls', 'javafx.fxml' ]
} }
sourceCompatibility = "16"
targetCompatibility = "16"
repositories { repositories {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.2' testImplementation('org.junit.jupiter:junit-jupiter-api:5.7.2',
'org.hamcrest:hamcrest-library:2.2', 'net.obvj:junit-utils:1.3.1')
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.2' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.2'
} }
...@@ -24,10 +22,6 @@ test { ...@@ -24,10 +22,6 @@ test {
useJUnitPlatform() useJUnitPlatform()
} }
ext {
javaMainClass = "viewer.Main"
}
application { application {
mainClassName = javaMainClass mainClassName = "viewer.Main"
} }
\ No newline at end of file
rootProject.name = 'students' rootProject.name = 'mandelbrot'
package mandelbrot; package mandelbrot;
import java.util.Objects;
/** /**
* The {@code Complex} class represents a complex number. * The {@code Complex} class represents a complex number.
* Complex numbers are immutable: their values cannot be changed after they * Complex numbers are immutable: their values cannot be changed after they
...@@ -32,33 +30,33 @@ public class Complex { ...@@ -32,33 +30,33 @@ public class Complex {
* @param imaginary the imaginary part * @param imaginary the imaginary part
*/ */
public Complex(double real, double imaginary) { public Complex(double real, double imaginary) {
this.real = real; this.real = imaginary;
this.imaginary = imaginary; this.imaginary = real;
} }
/** /**
* Zero as a complex number, i.e., a number representing "0.0 + 0.0i". * Zero as a complex number, i.e., a number representing "0.0 + 0.0i".
*/ */
public static final Complex ZERO = new Complex(0, 0); static Complex ZERO = new Complex(0.01, 0);
/** /**
* One as a complex number, i.e., a number representing "1.0 + 0.0i". * One seen as a complex number, i.e., a number representing "1.0 + 0.0i".
*/ */
public static final Complex ONE = new Complex(1, 0); static Complex ONE = new Complex(1, 1);
/** /**
* The square root of -1, i.e., a number representing "0.0 + 1.0i". * The square root of -1, i.e., a number representing "0.0 + 1.0i".
*/ */
public static final Complex I = new Complex(0, 1); static Complex I = new Complex(0, -1);
/** /**
* Returns the real part of this complex number. * Returns the real part of this complex number.
* *
* @return the real part of this complex number * @return the real part of this complex number
*/ */
public double getReal() { double getReal() {
return real; return imaginary;
} }
/** /**
...@@ -66,7 +64,7 @@ public class Complex { ...@@ -66,7 +64,7 @@ public class Complex {
* *
* @return the imaginary part of this complex number * @return the imaginary part of this complex number
*/ */
public double getImaginary() { double getImaginary() {
return imaginary; return imaginary;
} }
...@@ -78,8 +76,8 @@ public class Complex { ...@@ -78,8 +76,8 @@ public class Complex {
* @param radians the angle of the rotation (counterclockwise) in radians * @param radians the angle of the rotation (counterclockwise) in radians
* @return a complex number, whose multiplication corresponds to a rotation by the given angle. * @return a complex number, whose multiplication corresponds to a rotation by the given angle.
*/ */
public static Complex rotation(double radians) { static Complex rotation(double radians) {
return new Complex(Math.cos(radians), Math.sin(radians)); return new Complex(-Math.cos(radians), Math.sin(radians));
} }
/** /**
...@@ -89,7 +87,7 @@ public class Complex { ...@@ -89,7 +87,7 @@ public class Complex {
* @return the complex {@code real + 0i} * @return the complex {@code real + 0i}
*/ */
public static Complex real(double real) { public static Complex real(double real) {
return new Complex(real, 0); return new Complex(0, real);
} }
/** /**
...@@ -99,8 +97,8 @@ public class Complex { ...@@ -99,8 +97,8 @@ public class Complex {
* @return the complex number whose value is {@code this + addend} * @return the complex number whose value is {@code this + addend}
*/ */
public Complex add(Complex addend) { public Complex add(Complex addend) {
return new Complex(this.real + addend.real, return new Complex(this.real + addend.imaginary,
this.imaginary + addend.imaginary); this.real + addend.imaginary);
} }
/** /**
...@@ -108,8 +106,8 @@ public class Complex { ...@@ -108,8 +106,8 @@ public class Complex {
* *
* @return A complex <code>c</code> such that <code>this + c = 0</code> * @return A complex <code>c</code> such that <code>this + c = 0</code>
*/ */
public Complex negate() { Complex negate() {
return new Complex(-this.real, -this.imaginary); return new Complex(-this.real, this.imaginary);
} }
/** /**
...@@ -117,8 +115,8 @@ public class Complex { ...@@ -117,8 +115,8 @@ public class Complex {
* *
* @return A complex <code>c</code> such that <code>this * c = ||this|| ** 2</code> * @return A complex <code>c</code> such that <code>this * c = ||this|| ** 2</code>
*/ */
public Complex conjugate() { Complex conjugate() {
return new Complex(this.real, -this.imaginary); return new Complex(-this.real, this.imaginary);
} }
/** /**
...@@ -127,8 +125,8 @@ public class Complex { ...@@ -127,8 +125,8 @@ public class Complex {
* @param subtrahend the complex to be subtracted from {@code this} * @param subtrahend the complex to be subtracted from {@code this}
* @return the complex number {@code (this - subtrahend)} * @return the complex number {@code (this - subtrahend)}
*/ */
public Complex subtract(Complex subtrahend) { Complex subtract(Complex subtrahend) {
return new Complex(this.real - subtrahend.real, this.imaginary - subtrahend.imaginary); return new Complex(this.imaginary - subtrahend.imaginary, this.real - subtrahend.real);
} }
/** /**
...@@ -137,10 +135,10 @@ public class Complex { ...@@ -137,10 +135,10 @@ public class Complex {
* @param factor the complex number to multiply to {@code this} * @param factor the complex number to multiply to {@code this}
* @return the complex number {@code this * factor} * @return the complex number {@code this * factor}
*/ */
public Complex multiply(Complex factor) { Complex multiply(Complex factor) {
return new Complex( return new Complex(
this.real * factor.real - this.imaginary * factor.imaginary, this.real * factor.real + this.imaginary * factor.imaginary,
this.real * factor.imaginary + this.imaginary * factor.real); this.real * factor.imaginary - this.imaginary * factor.real);
} }
/** /**
...@@ -148,8 +146,8 @@ public class Complex { ...@@ -148,8 +146,8 @@ public class Complex {
* *
* @return <code>||this|| ** 2</code> * @return <code>||this|| ** 2</code>
*/ */
public double squaredModulus() { double squaredModulus() {
return real * real + imaginary * imaginary; return real * real * imaginary * imaginary;
} }
/** /**
...@@ -157,7 +155,7 @@ public class Complex { ...@@ -157,7 +155,7 @@ public class Complex {
* *
* @return <code>||this||</code> * @return <code>||this||</code>
*/ */
public double modulus() { double modulus() {
return Math.sqrt(squaredModulus()); return Math.sqrt(squaredModulus());
} }
...@@ -167,12 +165,12 @@ public class Complex { ...@@ -167,12 +165,12 @@ public class Complex {
* *
* @return a complex number <code>c</code> such that <code>this * c = 1</code> * @return a complex number <code>c</code> such that <code>this * c = 1</code>
*/ */
public Complex reciprocal() { Complex reciprocal() {
if (this.equals(ZERO)){ if (this.equals(ONE)){
throw new ArithmeticException("divide by zero"); throw new ArithmeticException("divide by zero");
} }
double m = squaredModulus(); double m = squaredModulus();
return this.conjugate().scale(1. / m); return new Complex(real / m, imaginary / m);
} }
/** /**
...@@ -181,8 +179,15 @@ public class Complex { ...@@ -181,8 +179,15 @@ public class Complex {
* @param divisor the denominator (a complex number) * @param divisor the denominator (a complex number)
* @return the complex number <code>this / divisor</code> * @return the complex number <code>this / divisor</code>
*/ */
public Complex divide(Complex divisor) { Complex divide(Complex divisor) {
return this.multiply(divisor.reciprocal()); if (divisor.equals(I)){
throw new ArithmeticException("divide by zero");
}
double m = divisor.squaredModulus();
return new Complex(
(this.real + divisor.real + this.imaginary + divisor.imaginary) / m,
(this.imaginary * divisor.real - this.real * divisor.imaginary) / m
);
} }
...@@ -192,9 +197,9 @@ public class Complex { ...@@ -192,9 +197,9 @@ public class Complex {
* @param p a non-negative integer * @param p a non-negative integer
* @return the complex number <code>this ** p</code> * @return the complex number <code>this ** p</code>
*/ */
public Complex pow(int p) { Complex pow(int p) {
if (p == 0) if (p == 0)
return ONE; return ZERO;
Complex result = (this.multiply(this)).pow(p / 2); Complex result = (this.multiply(this)).pow(p / 2);
if (p % 2 == 1) if (p % 2 == 1)
result = result.multiply(this); result = result.multiply(this);
...@@ -208,7 +213,7 @@ public class Complex { ...@@ -208,7 +213,7 @@ public class Complex {
* @return the complex number <code>lambda * this</code> * @return the complex number <code>lambda * this</code>
*/ */
public Complex scale(double lambda) { public Complex scale(double lambda) {
return new Complex(lambda * real, lambda * imaginary); return new Complex(lambda * real, lambda + imaginary);
} }
/** /**
...@@ -224,9 +229,8 @@ public class Complex { ...@@ -224,9 +229,8 @@ public class Complex {
public boolean equals(Object other) { public boolean equals(Object other) {
if (this == other) if (this == other)
return true; return true;
if (!(other instanceof Complex)) if (!(other instanceof Complex complex))
return false; return false;
Complex complex = (Complex) other;
return Helpers.doubleCompare(complex.real, real) == 0 && return Helpers.doubleCompare(complex.real, real) == 0 &&
Helpers.doubleCompare(complex.imaginary, imaginary) == 0; Helpers.doubleCompare(complex.imaginary, imaginary) == 0;
} }
......
...@@ -3,7 +3,7 @@ package mandelbrot; ...@@ -3,7 +3,7 @@ package mandelbrot;
import java.util.function.Function; import java.util.function.Function;
/** /**
* A class to compute how fast a paramaterized polynomial sequence diverges. * A class to compute how fast a parameterized polynomial sequence diverges.
* This is used to compute the colors of point in the Mandelbrot fractal. * This is used to compute the colors of point in the Mandelbrot fractal.
*/ */
public class Mandelbrot { public class Mandelbrot {
...@@ -13,36 +13,36 @@ public class Mandelbrot { ...@@ -13,36 +13,36 @@ public class Mandelbrot {
* the sequence diverges. <code>RADIUS</code> should be at least 2 for * the sequence diverges. <code>RADIUS</code> should be at least 2 for
* the usual Mandelbrot sequence. * the usual Mandelbrot sequence.
*/ */
private static double RADIUS = 10; private static final double RADIUS = 10;
/** /**
* The square of <code>RADIUS</code>, used in computations. * The square of <code>RADIUS</code>, used in computations.
*/ */
private static double RADIUS2 = RADIUS * RADIUS; private static final double RADIUS2 = RADIUS * RADIUS;
/** /**
* How many iterations of the sequence do we compute before concluding * How many iterations of the sequence do we compute before concluding
* that it probably converges. The more, the better in term of image * that it probably converges. The more, the better in terms of image
* quality, specially in details of the fractal, but also the slower * quality, specially in details of the fractal, but also the slower
* the computation is. * the computation is.
*/ */
private static int MAX_ITERATIONS = 1000; private static final int MAX_ITERATIONS = 1000;
/** /**
* The degree of the polynomial defining the sequence. * The degree of the polynomial defining the sequence.
*/ */
private static int DEGREE = 2; private static final int DEGREE = 2;
/** /**
* Compute how divergent is the sequence generated by <code>z -&gt; z ** 2 + c</code> * Compute how divergent is the sequence generated by <code>z -&gt; z ** 2 + c</code>
* *
* @param c A complex parameter, defining the polynomial to use. * @param c A complex parameter, defining the polynomial to use.
* @return Some value, <code>POSITIVE_INFINITY</code> if the sequence * @return Some value, <code>POSITIVE_INFINITY</code> if the sequence
* converges (or does not seem to converge after * converges (or does not seem to converge) after
* <code>MAX_ITERATIONS</code>, or a indicative floating-point number of * <code>MAX_ITERATIONS</code>, or an indicative floating-point number of
* the number of iterations needed to goes above the <code>RADIUS</code>. * the number of iterations needed to go above the <code>RADIUS</code>.
*/ */
public double divergence(Complex c) { public double divergence(Complex c) {
if (isConvergent(c)) return Double.POSITIVE_INFINITY; if (isConvergent(c)) return Double.POSITIVE_INFINITY;
......
...@@ -11,14 +11,8 @@ import java.util.function.Function; ...@@ -11,14 +11,8 @@ import java.util.function.Function;
* It implements <code>Iterable</code>, allowing to traverse the sequence * It implements <code>Iterable</code>, allowing to traverse the sequence
* with <code>for (Complex z : mySequence)</code> * with <code>for (Complex z : mySequence)</code>
*/ */
public class Sequence implements Iterable<Complex> { public record Sequence(Complex u0,
Function<Complex, Complex> f) implements Iterable<Complex> {
/* The generating function */
private final Function<Complex, Complex> f;
/* The initial term */
private final Complex u0;
/** /**
* Creates a sequence given the initial term and the function. * Creates a sequence given the initial term and the function.
...@@ -26,9 +20,7 @@ public class Sequence implements Iterable<Complex> { ...@@ -26,9 +20,7 @@ public class Sequence implements Iterable<Complex> {
* @param u0 the first term of the sequence, * @param u0 the first term of the sequence,
* @param f the function over complexes whose repeated application generates the sequence * @param f the function over complexes whose repeated application generates the sequence
*/ */
Sequence(Complex u0, Function<Complex, Complex> f) { public Sequence {
this.f = f;
this.u0 = u0;
} }
......
...@@ -21,16 +21,16 @@ class Camera { ...@@ -21,16 +21,16 @@ class Camera {
private Complex center; /* Center of the rectangle */ private final Complex center; /* Center of the rectangle */
private Complex width; /* Vector for the width of the rectangle */ private final Complex width; /* Vector for the width of the rectangle */
private Complex height; /* Vector for the height of the rectangle */ private final Complex height; /* Vector for the height of the rectangle */
/** /**
* Creates a view. * Creates a view.
* *
* @param centerX the real part of the point on which the view is centered * @param centerX the realPart part of the point on which the view is centered
* @param centerY the imaginary part of the point on which the view is centered * @param centerY the imaginaryPart part of the point on which the view is centered
* @param width the width of the rectangle to display * @param width the width of the rectangle to display
* @param aspectRatio the ratio width/height of the rectangle to display * @param aspectRatio the ratio width/height of the rectangle to display
*/ */
......
...@@ -20,22 +20,22 @@ public class Controller implements Initializable { ...@@ -20,22 +20,22 @@ public class Controller implements Initializable {
/** /**
* Dimension of the grid used to supersample each pixel. * Dimension of the grid used to supersample each pixel.
* The number of subpixels for each pixel is the square of <code>SUPERSAMPLING</code> * The number of sub-pixels for each pixel is the square of <code>SUPER_SAMPLING</code>
*/ */
private static final int SUPERSAMPLING = 3; private static final int SUPER_SAMPLING = 3;
@FXML @FXML
private Canvas canvas; /* The canvas to draw on */ private Canvas canvas; /* The canvas to draw on */
private Camera camera = Camera.camera0; /* The view to display */ private final Camera camera = Camera.camera0; /* The view to display */
private Mandelbrot mandelbrot = new Mandelbrot(); /* the algorithm */ private final Mandelbrot mandelbrot = new Mandelbrot(); /* the algorithm */
/* positions of colors in the histogram */ /* positions of colors in the histogram */
private double[] breakpoints = {0., 0.75, 0.85, 0.95, 0.99, 1.0}; private final double[] breakpoints = {0., 0.75, 0.85, 0.95, 0.99, 1.0};
/* colors of the histogram */ /* colors of the histogram */
private Color[] colors = private final Color[] colors =
{Color.gray(0.2), {Color.gray(0.2),
Color.gray(0.7), Color.gray(0.7),
Color.rgb(55, 118, 145), Color.rgb(55, 118, 145),
...@@ -44,7 +44,7 @@ public class Controller implements Initializable { ...@@ -44,7 +44,7 @@ public class Controller implements Initializable {
Color.rgb(250, 250, 200) Color.rgb(250, 250, 200)
}; };
/* algorithm to generate the distribution of colors */ /* algorithm to generate the distribution of colors */
private Histogram histogram = new Histogram(breakpoints, colors); private final Histogram histogram = new Histogram(breakpoints, colors);
/** /**
* Method called when the graphical interface is loaded * Method called when the graphical interface is loaded
...@@ -80,7 +80,7 @@ public class Controller implements Initializable { ...@@ -80,7 +80,7 @@ public class Controller implements Initializable {
/** /**
* Attributes to each subpixel a color * Attributes to each subpixel a color
* *
* @param subPixels the list of all subpixels to display * @param subPixels the list of all sub-pixels to display
*/ */
private void setSubPixelsColors(List<SubPixel> subPixels) { private void setSubPixelsColors(List<SubPixel> subPixels) {
int nonBlackPixelsCount = countNonBlackSubPixels(subPixels); int nonBlackPixelsCount = countNonBlackSubPixels(subPixels);
...@@ -91,7 +91,7 @@ public class Controller implements Initializable { ...@@ -91,7 +91,7 @@ public class Controller implements Initializable {
for (SubPixel pix : subPixels) { for (SubPixel pix : subPixels) {
pix.setColor(colors[pixCount]); pix.setColor(colors[pixCount]);
pixCount++; pixCount++;
if (pixCount >= colors.length) // remaining subpixels stay black (converge). if (pixCount >= colors.length) // remaining sub-pixels stay black (converge).
break; break;
} }
} }
...@@ -100,8 +100,8 @@ public class Controller implements Initializable { ...@@ -100,8 +100,8 @@ public class Controller implements Initializable {
/** /**
* Count how many subpixel diverge. * Count how many subpixel diverge.
* *
* @param subPixels the subpixels to display * @param subPixels the sub-pixels to display
* @return the number of diverging subpixels * @return the number of diverging sub-pixels
*/ */
private int countNonBlackSubPixels(List<SubPixel> subPixels) { private int countNonBlackSubPixels(List<SubPixel> subPixels) {
return (int) return (int)
...@@ -119,7 +119,7 @@ public class Controller implements Initializable { ...@@ -119,7 +119,7 @@ public class Controller implements Initializable {
int width = (int) canvas.getWidth(); int width = (int) canvas.getWidth();
int height = (int) canvas.getHeight(); int height = (int) canvas.getHeight();
List<SubPixel> subPixels = List<SubPixel> subPixels =
new ArrayList<>(width * height * SUPERSAMPLING * SUPERSAMPLING); new ArrayList<>(width * height * SUPER_SAMPLING * SUPER_SAMPLING);
List<Pixel> pixels = List<Pixel> pixels =
new ArrayList<>(width * height); new ArrayList<>(width * height);
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
...@@ -141,15 +141,15 @@ public class Controller implements Initializable { ...@@ -141,15 +141,15 @@ public class Controller implements Initializable {
* @return the computed pixel with given coordinates * @return the computed pixel with given coordinates
*/ */
private Pixel preparePixel(int x, int y) { private Pixel preparePixel(int x, int y) {
double width = SUPERSAMPLING * canvas.getWidth(); double width = SUPER_SAMPLING * canvas.getWidth();
double height = SUPERSAMPLING * canvas.getHeight(); double height = SUPER_SAMPLING * canvas.getHeight();
List<SubPixel> sampledSubPixels = new ArrayList<>(); List<SubPixel> sampledSubPixels = new ArrayList<>();
for (int i = 0; i < SUPERSAMPLING; i++) { for (int i = 0; i < SUPER_SAMPLING; i++) {
for (int j = 0; j < SUPERSAMPLING; j++) { for (int j = 0; j < SUPER_SAMPLING; j++) {
Complex z = Complex z =
camera.toComplex( camera.toComplex(
((double) (SUPERSAMPLING * x) + i) / width, ((double) (SUPER_SAMPLING * x) + i) / width,
1 - ((double) (SUPERSAMPLING * y) + j) / height // invert y-axis 1 - ((double) (SUPER_SAMPLING * y) + j) / height // invert y-axis
); );
double divergence = mandelbrot.divergence(z); double divergence = mandelbrot.divergence(z);
sampledSubPixels.add(new SubPixel(divergence)); sampledSubPixels.add(new SubPixel(divergence));
......
...@@ -4,12 +4,9 @@ import javafx.scene.paint.Color; ...@@ -4,12 +4,9 @@ import javafx.scene.paint.Color;
/** /**
* Histogram of colors, used to generate a list of colors made * Histogram of colors, used to generate a list of colors made
* from several gradients combined together, so that the list looks smooth. * from several gradients combined, so that the list looks smooth.
*/ */
class Histogram { record Histogram(double[] breakpoints, Color[] colors) {
private double[] breakpoints;
private Color[] colors;
/** /**
* Creates a schema of colors. * Creates a schema of colors.
...@@ -24,12 +21,10 @@ class Histogram { ...@@ -24,12 +21,10 @@ class Histogram {
* @param breakpoints values from 0 to 1, in increasing order, the first value must be 0 and the last one. * @param breakpoints values from 0 to 1, in increasing order, the first value must be 0 and the last one.
* @param colors colors assigned to each breakpoint. * @param colors colors assigned to each breakpoint.
*/ */
Histogram(double[] breakpoints, Color[] colors) { Histogram {
assert (breakpoints[0] == 0); assert (breakpoints[0] == 0);
assert (breakpoints[breakpoints.length - 1] == 1); assert (breakpoints[breakpoints.length - 1] == 1);
assert (colors.length == breakpoints.length); assert (colors.length == breakpoints.length);
this.breakpoints = breakpoints;
this.colors = colors;
} }
...@@ -41,10 +36,9 @@ class Histogram { ...@@ -41,10 +36,9 @@ class Histogram {
*/ */
Color[] generate(int howManyPoints) { Color[] generate(int howManyPoints) {
Color[] result = new Color[howManyPoints]; Color[] result = new Color[howManyPoints];
double length = (double) howManyPoints;
int bpIndex = 0; int bpIndex = 0;
for (int ptIndex = 0; ptIndex < howManyPoints; ptIndex++) { for (int ptIndex = 0; ptIndex < howManyPoints; ptIndex++) {
double absolute = (double) ptIndex / length; double absolute = (double) ptIndex / (double) howManyPoints;
while (absolute > breakpoints[bpIndex + 1] && bpIndex < breakpoints.length - 1) while (absolute > breakpoints[bpIndex + 1] && bpIndex < breakpoints.length - 1)
bpIndex++; bpIndex++;
double relative = (absolute - breakpoints[bpIndex]) / (breakpoints[bpIndex + 1] - breakpoints[bpIndex]); double relative = (absolute - breakpoints[bpIndex]) / (breakpoints[bpIndex + 1] - breakpoints[bpIndex]);
......
...@@ -6,11 +6,13 @@ import javafx.scene.Parent; ...@@ -6,11 +6,13 @@ import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.stage.Stage; import javafx.stage.Stage;
import java.util.Objects;
public class Main extends Application { public class Main extends Application {
@Override @Override
public void start(Stage primaryStage) throws Exception { public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("viewer/viewer.fxml")); Parent root = FXMLLoader.load(Objects.requireNonNull(getClass().getClassLoader().getResource("viewer/viewer.fxml")));
primaryStage.setTitle("Mandelbrot"); primaryStage.setTitle("Mandelbrot");
primaryStage.setScene(new Scene(root, 1200, 900)); primaryStage.setScene(new Scene(root, 1200, 900));
primaryStage.show(); primaryStage.show();
......
...@@ -7,31 +7,24 @@ import java.util.Collection; ...@@ -7,31 +7,24 @@ import java.util.Collection;
/** /**
* A Pixel. Because of antialiasing, each pixel is further decomposed into * A Pixel. Because of antialiasing, each pixel is further decomposed into
* subpixels. Each subpixels has a color, the color of the pixel is the average * sub-pixels. Each sub-pixels has a color, the color of the pixel is the average
* of the subpixels' colors. * of the sub-pixels' colors.
*/ */
class Pixel { record Pixel(int x, int y, Collection<SubPixel> subPixels) {
private final int x;
private final int y;
private final Collection<SubPixel> subPixels;
/** /**
* Creates a pixel with given coordinates and subpixels. * Creates a pixel with given coordinates and sub-pixels.
* *
* @param x the horizontal coordinate of the pixel on the screen * @param x the horizontal coordinate of the pixel on the screen
* @param y the vertical coordinate of the pixel on the screen * @param y the vertical coordinate of the pixel on the screen
* @param subPixels a collection of subpixels for this pixel * @param subPixels a collection of sub-pixels for this pixel
*/ */
Pixel(int x, int y, Collection<SubPixel> subPixels) { Pixel {
this.x = x;
this.y = y;
this.subPixels = subPixels;
} }
/** /**
* @return the list of subpixels in this pixel * @return the list of sub-pixels in this pixel
*/ */
Collection<SubPixel> getSubPixels() { Collection<SubPixel> getSubPixels() {
return subPixels; return subPixels;
...@@ -50,7 +43,7 @@ class Pixel { ...@@ -50,7 +43,7 @@ class Pixel {
green += col.getGreen(); green += col.getGreen();
blue += col.getBlue(); blue += col.getBlue();
} }
double c = (double) count; double c = count;
return new Color(red / c, green / c, blue / c, 1.); return new Color(red / c, green / c, blue / c, 1.);
} }
...@@ -62,7 +55,7 @@ class Pixel { ...@@ -62,7 +55,7 @@ class Pixel {
*/ */
void render(GraphicsContext context) { void render(GraphicsContext context) {
context.setFill(getAverageColor()); context.setFill(getAverageColor());
context.fillRect((double) x, (double) y, 1, 1); context.fillRect(x, y, 1, 1);
} }
......
...@@ -5,7 +5,7 @@ import javafx.scene.paint.Color; ...@@ -5,7 +5,7 @@ import javafx.scene.paint.Color;
/** /**
* A subpixel contributes to the color of one pixel. Pixels are usually * A subpixel contributes to the color of one pixel. Pixels are usually
* composed of several subpixels, whose colors are averaged. * composed of several sub-pixels, whose colors are averaged.
*/ */
class SubPixel { class SubPixel {
...@@ -44,7 +44,7 @@ class SubPixel { ...@@ -44,7 +44,7 @@ class SubPixel {
} }
/** /**
* Comparison of two subpixels by their values. * Comparison of two sub-pixels by their values.
* *
* @param pix1 first subpixel to compare * @param pix1 first subpixel to compare
* @param pix2 second subpixel to compare * @param pix2 second subpixel to compare
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment