Skip to content
Snippets Groups Projects
Commit 88c51623 authored by Magnus Eik's avatar Magnus Eik
Browse files

Merge remote-tracking branch 'gitlab/features/gui' into features/gui

parents 3f6bf1f0 6d32226e
No related branches found
No related tags found
No related merge requests found
Showing
with 322 additions and 36 deletions
......@@ -8,6 +8,5 @@
</component>
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/idatt2003" vcs="Git" />
</component>
</project>
\ No newline at end of file
......@@ -41,7 +41,7 @@ public class Main extends Application {
//ChaosGameDescription description = new ChaosGameFileHandler().readFromFile(path);
//description = new ChaosGameDescription(minCoords, maxCoords, transforms);
//description = new ChaosGameFileHandler().readFromFile(path);
description = factory.getDescriptions().get(1);
description = factory.getDescriptions().get(0);
ChaosCanvas canvas = new ChaosCanvas(100, 100, description.getMinCoords(), description.getMaxCoords()); // Create canvas
game = new ChaosGame(description, canvas);
......
package edu.ntnu.stud.chaosgame.controller;
import edu.ntnu.stud.chaosgame.controller.game.ChaosCanvas;
import edu.ntnu.stud.chaosgame.controller.game.ChaosGameDescription;
/**
* Observer class for monitoring changes to the active
* ChaosGameDescription {@link ChaosGameDescription} or the canvas {@link ChaosCanvas}
*/
public class ChaosGameObserver {
// TODO: Create class
}
......@@ -56,15 +56,12 @@ public class ChaosCanvas {
this.canvas = new int[height][width];
// Define the affine transformation that maps coordinates to indices in the canvas.
/*this.transformCoordsToIndices = new AffineTransform2D(
new Matrix2x2(0, (height - 1) / (minCoords.getX1() - maxCoords.getX1()), (width - 1) / (maxCoords.getX0() - minCoords.getX0()), 0),
new Vector2D((((height - 1) * maxCoords.getX1()) / (maxCoords.getX1() - minCoords.getX1())),
((width - 1) * minCoords.getX0()) / (minCoords.getX0() - maxCoords.getX0()))
);*/
// Convert the coordinates to indices in the canvas
this.transformCoordsToIndices = new AffineTransform2D(
new Matrix2x2(0, (height-1) / (minCoords.getX1() - maxCoords.getX1()), (width-1) / (maxCoords.getX0() - minCoords.getX0()), 0),
new Vector2D(((height-1)* maxCoords.getX1()) / (maxCoords.getX1() - minCoords.getX1()), (width-1)* minCoords.getX0() / (minCoords.getX0() - maxCoords.getX0())));
new Matrix2x2(0, (height-1) / (minCoords.getX1() - maxCoords.getX1()),
(width-1) / (maxCoords.getX0() - minCoords.getX0()), 0),
new Vector2D(((height-1)* maxCoords.getX1()) / (maxCoords.getX1() - minCoords.getX1()),
(width-1)* minCoords.getX0() / (minCoords.getX0() - maxCoords.getX0())));
}
/**
......@@ -96,13 +93,54 @@ public class ChaosCanvas {
}
/**
* Get the canvas array.
* @return the canvas array
* Get the width and height of the canvas in the form of an array where the first
* index stores the width and the second stores the height.
*
* @return an array of two numbers containing both the width and height.
*/
public int[][] getCanvasArray() {
return canvas;
public int[] getSize() {
return new int[]{this.width, this.height};
}
/**
* Get the vector storing the minimum coordinates.
*
* @return the vector.
*/
public Vector2D getMinCoords() {return this.minCoords; }
/**
* Get the vector storing the maximum coordinates.
*
* @return the vector.
*/
public Vector2D getMaxCoords() { return this.maxCoords; }
/**
* Get the number of points in the canvas with a value of 1.
*
* @return the sum of the points.
*/
public int getNumOfPoints() {
int sum = 0;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
if (canvas[i][j] == 1) {
sum++;
}
}
}
return sum;
}
/**
* Get the affine transform representing the conversion from coordinates to indices.
*
* @return the transform.
*/
public AffineTransform2D getTransformCoordsToIndices() { return this.transformCoordsToIndices; }
/**
* Clear the canvas of all content.
*/
......@@ -114,6 +152,14 @@ public class ChaosCanvas {
}
}
/**
* Get the array defining the size of the canvas.
* @return the array.
*/
public int[][] getCanvasArray() {
return this.canvas;
}
/**
* Prints the current state of the canvas to the console.
* Populated points are represented by 'x', unpopulated points by ' '.
......
package edu.ntnu.stud.chaosgame.controller.game;
import edu.ntnu.stud.chaosgame.model.data.Vector2D;
import edu.ntnu.stud.chaosgame.view.ChaosGameObserver;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
/**
......@@ -19,9 +22,9 @@ public class ChaosGame {
private ChaosGameDescription description;
/**
* The description for this ChaosGame
* Observers monitoring this ChaosGame.
*/
// private ChaosGameDescription description;
private ArrayList<ChaosGameObserver> observers;
/**
* The current point in the chaos game.
......@@ -34,10 +37,16 @@ public class ChaosGame {
private Random random;
/**
* Number of transforms
* Number of transforms.
*/
private int numOfTransforms;
/**
* Basic parameterised constructor.
*
* @param description the ChaosGameDescription.
* @param canvas the ChaosCanvas.
*/
public ChaosGame(ChaosGameDescription description, ChaosCanvas canvas) {
this.canvas = canvas;
this.description = description;
......@@ -46,16 +55,60 @@ public class ChaosGame {
this.currentPoint = new Vector2D(0, 0);
}
/**
* Parameterised constructor with observers.
*
* @param description the ChaosGameDescription.
* @param canvas the ChaosCanvas.
* @param observers the ChaosGameObservers to be added.
*/
public ChaosGame(ChaosGameDescription description, ChaosCanvas canvas, ChaosGameObserver... observers) {
this.canvas = canvas;
this.description = description;
this.random = new Random();
this.numOfTransforms = description.getTransforms().size();
this.currentPoint = new Vector2D(0, 0);
this.observers.addAll(Arrays.asList(observers));
}
/**
* Get the canvas of this chaos game.
*
* @return the canvas.
*/
public ChaosCanvas getCanvas() { return this.canvas; }
/**
* Get the current point in the chaos game.
*
* @return the point.
*/
public Vector2D getCurrentPoint() { return this.currentPoint; }
/**
* Notify the observers that a change has occurred in the ChaosGame.
*/
public void notifyObservers() {
for (ChaosGameObserver observer : this.observers) {
observer.update(this);
}
}
/**
* Add an observer to the ChaosGame.
*
* @param observer the observer to add.
*/
public void addObserver(ChaosGameObserver observer) {
this.observers.add(observer);
}
/**
* Run the chaos game for n iterations.
*
* @param n the number of iterations
* @param n the number of iterations.
*/
public void runSteps(int n) {
for (int i = 0; i < n; i++) {
......
......@@ -2,6 +2,7 @@ package edu.ntnu.stud.chaosgame.controller.game;
import edu.ntnu.stud.chaosgame.model.data.Vector2D;
import edu.ntnu.stud.chaosgame.model.transformations.AffineTransform2D;
import edu.ntnu.stud.chaosgame.model.transformations.Transform2D;
import java.util.List;
......@@ -26,7 +27,8 @@ public class ChaosGameDescription {
private final List<Transform2D> transforms;
/**
* Constructor for ChaosGameDescription
* Constructor for ChaosGameDescription.
*
* @param minCoords Inputs a {@link Vector2D} vector of lower left coordinates for the chaos game.
* @param maxCoords Inputs a {@link Vector2D} vector of upper right coordinates for the chaos game.
* @param transforms Inputs a list of transformations {@link edu.ntnu.stud.chaosgame.model.transformations.AffineTransform2D} used in the chaos game.
......@@ -42,6 +44,7 @@ public class ChaosGameDescription {
/**
* Getter method for transforms
*
* @return Returns a list of transforms in the chaos game.
*/
public List<Transform2D> getTransforms(){
......@@ -50,6 +53,7 @@ public class ChaosGameDescription {
/**
* Getter method for minimum coordinates.
*
* @return Returns a Vector2D containing the minimum coordinates.
*/
public Vector2D getMinCoords(){
......@@ -58,6 +62,7 @@ public class ChaosGameDescription {
/**
* Getter method for maximum coordinates.
*
* @return Returns a Vector2D containing the maximum coordinates.
*/
public Vector2D getMaxCoords(){
......
......@@ -3,6 +3,7 @@ package edu.ntnu.stud.chaosgame.controller.game;
import edu.ntnu.stud.chaosgame.model.data.Complex;
import edu.ntnu.stud.chaosgame.model.data.Matrix2x2;
import edu.ntnu.stud.chaosgame.model.data.Vector2D;
import edu.ntnu.stud.chaosgame.controller.game.ChaosGameDescription;
import edu.ntnu.stud.chaosgame.model.transformations.AffineTransform2D;
import edu.ntnu.stud.chaosgame.model.transformations.JuliaTransform;
import edu.ntnu.stud.chaosgame.model.transformations.Transform2D;
......
......@@ -24,9 +24,9 @@ public class ChaosGameDescriptionFactory {
* The naming of the txt-files must follow the pattern "desc_X.txt" where X is an integer
* incremented by 1 for each file in the directory.
*
* @throws IOException if the method fails to read successfully from one of the data files.
*
*/
public ChaosGameDescriptionFactory() throws IOException {
public ChaosGameDescriptionFactory() {
/**
* The directory where the descriptions are located.
*/
......@@ -34,10 +34,19 @@ public class ChaosGameDescriptionFactory {
this.descriptions = new ArrayList<>();
ChaosGameFileHandler handler = new ChaosGameFileHandler();
File directory = new File(directory1);
int fileCount = Objects.requireNonNull(directory.list()).length;
int fileCount = 0;
for (int i = 0; i < fileCount; i++) {
this.descriptions.add(handler.readFromFile(directory1 + "desc_" + (i + 1) + ".txt"));
try {
fileCount = Objects.requireNonNull(directory.list()).length;
} catch (NullPointerException e) {
System.out.println(e.getMessage()); // TODO: replace with different handling
}
try {
for (int i = 0; i < fileCount; i++) {
this.descriptions.add(handler.readFromFile(directory1 + "desc_" + (i + 1) + ".txt"));
}
} catch (IOException e) {
System.out.println(e.getMessage()); // TODO: replace with different handling
}
}
......
package edu.ntnu.stud.chaosgame.view;
import edu.ntnu.stud.chaosgame.controller.game.ChaosGame;
/**
* Observer interface for monitoring changes to the active
* TODO: Do we want to have separate update methods for the canvas and description or just one for the whole game? (likely the latter)
*/
public interface ChaosGameObserver {
// TODO: Create interface
/**
* Perform update of the ChaosCanvas.
*
* @param canvas the canvas.
*/
//void updateCanvas(ChaosCanvas canvas);
/**
* Perform update of the ChaosGameDescription.
*
* @param description the description.
*/
//void updateDescription(ChaosGameDescription description);
/**
* Update the observer based on changes to the chaos game.
*
* @param game the game this observer is monitoring.
*/
void update(ChaosGame game);
}
package edu.ntnu.stud.chaosgame.game;
import edu.ntnu.stud.chaosgame.model.data.Vector2D;
import edu.ntnu.stud.chaosgame.controller.game.ChaosCanvas;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Test for the ChaosCanvas {@link ChaosCanvas}.
*/
public class ChaosCanvasTest {
private ChaosCanvas canvas;
/**
* Instantiate a canvas before each test
*/
@BeforeEach
void setUp() {
Vector2D minCoords = new Vector2D(0, 0);
Vector2D maxCoords = new Vector2D(1, 1);
this.canvas = new ChaosCanvas(100, 100, minCoords, maxCoords);
}
/**
* Test whether creating the canvas worked properly, and simultanteously test whether
* the getters work as expected.
*/
@Test
void shouldCreateCanvas() {
ChaosCanvas testCanvas = new ChaosCanvas(100, 100,
new Vector2D(0,0), new Vector2D(1,1));
Assertions.assertEquals(testCanvas.getSize()[0], 100);
Assertions.assertEquals(testCanvas.getSize()[1], 100);
Assertions.assertEquals(testCanvas.getMinCoords().getX0(), 0);
Assertions.assertEquals(testCanvas.getMinCoords().getX1(), 0);
Assertions.assertEquals(testCanvas.getMaxCoords().getX0(), 1);
Assertions.assertEquals(testCanvas.getMaxCoords().getX1(), 1);
//Assertions.assertEquals(testCanvas.getTransformCoordsToIndices(), );
}
/**
* Test whether an arbitrary point on the canvas is obtained correctly and hence
* equal to 0.
*/
@Test
void shouldGetPixel() {
Assertions.assertEquals(this.canvas.getPixel(new Vector2D(0.5, 0.5)), 0);
}
/**
* Test whether putting a new pixel in an arbitrary location on the canvas works
* as expected.
*/
@Test
void shouldPutPixel() {
Vector2D point = new Vector2D(0.2, 0.3);
this.canvas.putPixel(point);
// Test whether new point was added
Assertions.assertEquals(this.canvas.getPixel(point), 1);
// Ensure another, arbitrary point was not also added
Assertions.assertEquals(this.canvas.getPixel(new Vector2D(0.1, 0.4)), 0);
}
/**
* Test whether clearing the canvas works as expected.
*/
@Test
void shouldClearCanvas() {
// Put pixels throughout a part of the canvas.
for (int i = 1; i < 101; i++) {
this.canvas.putPixel(new Vector2D( 1.0 / i, 1.0 / i));
// Check that the of the points where a pixel was added, are not equal to 0.
Assertions.assertNotEquals(0, this.canvas.getPixel(new Vector2D(1.0 / i, 1.0 / i)));
}
// Clear the canvas
this.canvas.clearCanvas();
// Ensure that each point where a pixel was added, is now equal to 0.
for (int i = 1; i < 101; i++) {
Assertions.assertEquals(this.canvas.getPixel(new Vector2D(1.0 / i, 1.0 / i)), 0);
}
}
}
package edu.ntnu.stud.chaosgame.game;
import edu.ntnu.stud.chaosgame.controller.game.ChaosCanvas;
import edu.ntnu.stud.chaosgame.controller.game.ChaosGame;
import edu.ntnu.stud.chaosgame.controller.game.ChaosGameDescription;
import edu.ntnu.stud.chaosgame.model.data.Vector2D;
import edu.ntnu.stud.chaosgame.model.generators.ChaosGameDescriptionFactory;
import java.io.IOException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Test for ChaosGame {@link ChaosGame}
*/
public class ChaosGameTest {
private ChaosGame game;
@BeforeEach
void setUp() {
ChaosGameDescriptionFactory factory = new ChaosGameDescriptionFactory();
ChaosGameDescription description = factory.getDescriptions().get(0);
ChaosCanvas canvas = new ChaosCanvas(100, 100, description.getMinCoords(), description.getMaxCoords());
this.game = new ChaosGame(description, canvas);
}
/**
* Test whether creating the ChaosGame works as expected.
*/
@Test
void shouldCreateChaosGame() {
ChaosGameDescriptionFactory factory = new ChaosGameDescriptionFactory();
ChaosGameDescription description = factory.getDescriptions().get(0);
ChaosCanvas canvas = new ChaosCanvas(100, 100, description.getMinCoords(), description.getMaxCoords());
this.game = new ChaosGame(description, canvas);
Assertions.assertEquals(100, this.game.getCanvas().getWidth());
Assertions.assertEquals(100, this.game.getCanvas().getHeight());
Assertions.assertEquals(description.getMinCoords(), this.game.getCanvas().getMinCoords());
Assertions.assertEquals(description.getMaxCoords(), this.game.getCanvas().getMaxCoords());
}
/**
* Test whether running steps successfully changes the current point.
*/
@Test
void shouldRunStepsAndChangeCurrentPoint() {
Vector2D pointOne = this.game.getCurrentPoint();
this.game.runSteps(10);
Vector2D pointTwo = this.game.getCurrentPoint();
// Ensure starting point is not the same as the point after running steps
Assertions.assertNotEquals(pointOne, pointTwo);
}
// TODO: Add tests involving observers
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment