diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index c0b20e26..a679e52f 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -1,19 +1,25 @@ package seng302.controllers; import javafx.animation.*; +import javafx.beans.property.SimpleDoubleProperty; import javafx.fxml.FXML; +import javafx.geometry.Point2D; +import javafx.scene.Group; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.layout.AnchorPane; import javafx.scene.paint.Color; import javafx.scene.text.Font; +import javafx.util.Pair; import seng302.models.Boat; -import seng302.models.TimelineInfo; +import seng302.models.BoatGroup; +import seng302.models.Colors; import seng302.models.mark.GateMark; import seng302.models.mark.Mark; import seng302.models.mark.MarkType; import seng302.models.mark.SingleMark; +import java.sql.Time; import java.util.*; /** @@ -27,61 +33,174 @@ public class CanvasController { private RaceViewController raceViewController; private ResizableCanvas canvas; + private Group group; private GraphicsContext gc; + private List boatGroups = new ArrayList<>(); - private final double ORIGIN_LAT = 32.321504; - private final double ORIGIN_LON = -64.857063; - private final int SCALE = 16000; + private final int MARK_SIZE = 10; + private final int BUFFER_SIZE = 25; + private final int CANVAS_WIDTH = 1000; + private final int CANVAS_HEIGHT = 1000; + private final int LHS_BUFFER = BUFFER_SIZE; + private final int RHS_BUFFER = BUFFER_SIZE + MARK_SIZE / 2; + private final int TOP_BUFFER = BUFFER_SIZE; + private final int BOT_BUFFER = TOP_BUFFER + MARK_SIZE / 2; + private final int FRAME_RATE = 60; + + private double distanceScaleFactor; + private ScaleDirection scaleDirection; + private Mark minLatPoint; + private Mark minLonPoint; + private Mark maxLatPoint; + private Mark maxLonPoint; + private int referencePointX; + private int referencePointY; + private double metersToPixels; + + public AnimationTimer timer; + + private enum ScaleDirection { + HORIZONTAL, + VERTICAL + } public void setup(RaceViewController raceViewController){ this.raceViewController = raceViewController; } public void initialize() { + raceViewController = new RaceViewController(); canvas = new ResizableCanvas(); + group = new Group(); + canvasPane.getChildren().add(canvas); + canvasPane.getChildren().add(group); // Bind canvas size to stack pane size. - canvas.widthProperty().bind(canvasPane.widthProperty()); - canvas.heightProperty().bind(canvasPane.heightProperty()); + canvas.widthProperty().bind(new SimpleDoubleProperty(CANVAS_WIDTH)); + canvas.heightProperty().bind(new SimpleDoubleProperty(CANVAS_HEIGHT)); + group.minWidth(CANVAS_WIDTH); + group.minHeight(CANVAS_HEIGHT); + } + + public void initializeCanvas (){ + gc = canvas.getGraphicsContext2D(); + gc.save(); + gc.setFill(Color.SKYBLUE); + gc.fillRect(0,0, CANVAS_WIDTH, CANVAS_HEIGHT); + gc.restore(); + drawCourse(); + drawBoats(); +// drawFps(12); +// // overriding the handle so that it can clean canvas and redraw boats and course marks +// AnimationTimer timer = new AnimationTimer() { +// private long lastUpdate = 0; +// private long lastFpsUpdate = 0; +// private int lastFpsCount = 0; +// private int fpsCount = 0; +// boolean done = true; +// +// @Override +// public void handle(long now) { +// if (true){ //if statement for limiting refresh rate if needed +//// gc.clearRect(0, 0, canvas.getWidth(),canvas.getHeight()); +//// gc.setFill(Color.SKYBLUE); +//// gc.fillRect(0,0,canvas.getWidth(),canvas.getHeight()); +// +// +// // If race has started, draw the boats and play the timeline +// if (raceViewController.getRace().getRaceTime() > 1) { +// raceViewController.playTimelines(); +// } +// // Race has not started, pause the timelines +// else { +// raceViewController.pauseTimelines(); +// } +// lastUpdate = now; +// fpsCount ++; +// if (now - lastFpsUpdate >= 1000000000){ +// lastFpsCount = fpsCount; +// fpsCount = 0; +// lastFpsUpdate = now; +// } +// } +// } +// }; +// timer.start(); + //try { + // Thread.sleep(10000); + //}catch (Exception e) { + // e.printStackTrace(); + //} + timer = new AnimationTimer() { - - // overriding the handle so that it can clean canvas and redraw boats and course marks - AnimationTimer timer = new AnimationTimer() { - private long lastUpdate = 0; - private long lastFpsUpdate = 0; - private int lastFpsCount = 0; - private int fpsCount = 0; + private int countdown = 60; + private int[] currentRaceMarker = {1, 1, 1, 1, 1, 1}; + List marks = raceViewController.getRace().getCourse(); @Override public void handle(long now) { - if (true){ //if statement for limiting refresh rate if needed - gc.clearRect(0, 0, canvas.getWidth(),canvas.getHeight()); - gc.setFill(Color.SKYBLUE); - gc.fillRect(0,0,canvas.getWidth(),canvas.getHeight()); - drawCourse(); - drawBoats(); - drawFps(lastFpsCount); + boolean raceFinished = true; + boolean descending; + boolean leftToRight; + int boatIndex = 0; + Mark nextMark; + if (countdown == 0) { + for (BoatGroup boatGroup : boatGroups) { + if (currentRaceMarker[boatIndex] < marks.size()) { + if (currentRaceMarker[boatIndex] == 6) { + int debugLine = 4; + } + double xb4 = boatGroup.getLayoutX(); + double yb4 = boatGroup.getLayoutY(); + nextMark = marks.get(currentRaceMarker[boatIndex]); - // If race has started, draw the boats and play the timeline - if (raceViewController.getRace().getRaceTime() > 1){ - raceViewController.playTimelines(); + descending = nextMark.getY() > boatGroup.getLayoutY(); + leftToRight = nextMark.getX() < boatGroup.getLayoutX(); + + boatGroup.updatePosition(1000 / 60); + if (descending && nextMark.getY() < boatGroup.getLayoutY()) { + currentRaceMarker[boatIndex]++; + boatGroup.setDestination( + marks.get(currentRaceMarker[boatIndex]).getX(), marks.get(currentRaceMarker[boatIndex]).getY() + ); + } else if (!descending && nextMark.getY() > boatGroup.getLayoutY()) { + currentRaceMarker[boatIndex]++; + boatGroup.setDestination( + marks.get(currentRaceMarker[boatIndex]).getX(), marks.get(currentRaceMarker[boatIndex]).getY() + ); + } else if (leftToRight && nextMark.getX() > boatGroup.getLayoutX()) { + currentRaceMarker[boatIndex]++; + boatGroup.setDestination( + marks.get(currentRaceMarker[boatIndex]).getX(), marks.get(currentRaceMarker[boatIndex]).getY() + ); + } else if (!leftToRight && nextMark.getX() < boatGroup.getLayoutX()) { + currentRaceMarker[boatIndex]++; + boatGroup.setDestination( + marks.get(currentRaceMarker[boatIndex]).getX(), marks.get(currentRaceMarker[boatIndex]).getY() + ); + } + + double xnew = boatGroup.getLayoutX(); + double ynew = boatGroup.getLayoutY(); + double dx = xnew - xb4; + double dy = ynew -yb4; + raceFinished = false; + boatIndex++; + } } - // Race has not started, pause the timelines - else { - raceViewController.pauseTimelines(); - } - lastUpdate = now; - fpsCount ++; - if (now - lastFpsUpdate >= 1000000000){ - lastFpsCount = fpsCount; - fpsCount = 0; - lastFpsUpdate = now; + if (raceFinished) { + System.out.println("DONZEO LADS"); + this.stop(); } + } else { + countdown--; } } }; - timer.start(); + for (Mark m : raceViewController.getRace().getCourse()) + System.out.println(m.getName()); + //timer.start(); } class ResizableCanvas extends Canvas { @@ -129,76 +248,25 @@ public class CanvasController { * Draws all the boats. */ private void drawBoats() { - Map timelineInfos = raceViewController.getTimelineInfos(); - for (Boat boat : timelineInfos.keySet()) { - TimelineInfo timelineInfo = timelineInfos.get(boat); +// Map timelineInfos = raceViewController.getTimelineInfos(); + List boats = raceViewController.getStartingBoats(); + List marks = raceViewController.getRace().getCourse(); + Double startingX = (double) marks.get(0).getX(); + Double startingY = (double) marks.get(0).getY(); + Double firstMarkX = (double) marks.get(1).getX(); + Double firstMarkY = (double) marks.get(1).getY(); - boat.setLocation(timelineInfo.getY().doubleValue(), timelineInfo.getX().doubleValue()); - - drawBoat(boat.getLongitude(), boat.getLatitude(), boat.getColor(), boat.getShortName(), boat.getSpeedInKnots(), boat.getHeading()); + for (Boat boat : boats) { + BoatGroup boatGroup = new BoatGroup(boat, Colors.getColor()); + boatGroup.moveBoatTo(startingX, startingY, 0d); + boatGroup.setDestination(firstMarkX, firstMarkY); + boatGroup.forceRotation(); + group.getChildren().add(boatGroup); + boatGroups.add(boatGroup); +// drawBoat(boat.getLongitude(), boat.getLatitude(), boat.getColor(), boat.getShortName(), boat.getSpeedInKnots(), boat.getHeading()); } } - /** - * Draw the wake line behind a boat - * @param gc The graphics context used for drawing the wake - * @param x the x position of the boat - * @param y the y position of the boat - * @param speed the speed of the boat - * @param color the color of the wake line - * @param heading the heading of the boat - */ - private void drawWake(GraphicsContext gc, double x, double y, double speed, Color color, double heading){ - double angle = Math.toRadians(heading); - speed = speed * 2; - Point newP = new Point(0, speed); - newP.rotate(angle); - - gc.setStroke(color); - gc.setLineWidth(1.0); - gc.strokeLine(x, y, newP.x + x, newP.y + y); - } - - /** - * Draws a boat with given (x, y) position in the given color - * - * @param lat - * @param lon - * @param color - * @param name - * @param speed - */ - private void drawBoat(double lat, double lon, Color color, String name, double speed, double heading) { - // Latitude - double x = (lon - ORIGIN_LON) * SCALE; - double y = (ORIGIN_LAT - lat) * SCALE; - - gc.setFill(color); - - if (raceViewController.isDisplayAnnotations()) { - // Set boat text - gc.setFont(new Font(14)); - gc.setLineWidth(3); - gc.fillText(name + ", " + speed + " knots", x + 15, y + 15); - } -// double diameter = 9; -// gc.fillOval(x, y, diameter, diameter); - double angle = Math.toRadians(heading); - - Point p1 = new Point(0, -15); // apex point - Point p2 = new Point(7, 4); // base point - Point p3 = new Point(-7, 4); // base point - p1.rotate(angle); - p2.rotate(angle); - p3.rotate(angle); - double[] xx = new double[] {p1.x + x, p2.x + x, x, p3.x + x}; - double[] yy = new double[] {p1.y + y, p2.y + y, y, p3.y + y}; - gc.fillPolygon(xx, yy, 4); - - if (raceViewController.isDisplayAnnotations()){ - drawWake(gc, x, y, speed, color, heading); - } - } /** * Inner class for creating point so that you can rotate it around origin point. @@ -225,10 +293,11 @@ public class CanvasController { * Draws the course. */ private void drawCourse() { + fitToCanvas(); for (Mark mark : raceViewController.getRace().getCourse()) { if (mark.getMarkType() == MarkType.SINGLE_MARK) { drawSingleMark((SingleMark) mark, Color.BLACK); - } else if (mark.getMarkType() == MarkType.GATE_MARK) { + } else { drawGateMark((GateMark) mark); } } @@ -240,11 +309,8 @@ public class CanvasController { * @param singleMark */ private void drawSingleMark(SingleMark singleMark, Color color) { - double x = (singleMark.getLongitude() - ORIGIN_LON) * SCALE; - double y = (ORIGIN_LAT - singleMark.getLatitude()) * SCALE; - gc.setFill(color); - gc.fillRect(x,y,5.5,5.5); + gc.fillOval(singleMark.getX(), singleMark.getY(),MARK_SIZE,MARK_SIZE); } /** @@ -256,28 +322,228 @@ public class CanvasController { Color color = Color.BLUE; if (gateMark.getName().equals("Start")){ - color = Color.RED; + color = Color.GREEN; } if (gateMark.getName().equals("Finish")){ - color = Color.GREEN; + color = Color.RED; } drawSingleMark(gateMark.getSingleMark1(), color); drawSingleMark(gateMark.getSingleMark2(), color); GraphicsContext gc = canvas.getGraphicsContext2D(); - + gc.save(); gc.setStroke(color); + if (gateMark.getMarkType() == MarkType.OPEN_GATE) + gc.setLineDashes(3, 5); - // Convert lat/lon to x,y - double x1 = (gateMark.getSingleMark1().getLongitude()- ORIGIN_LON) * SCALE; - double y1 = (ORIGIN_LAT - gateMark.getSingleMark1().getLatitude()) * SCALE; + gc.setLineWidth(2); + gc.strokeLine( + gateMark.getSingleMark1().getX() + MARK_SIZE / 2, + gateMark.getSingleMark1().getY() + MARK_SIZE / 2, + gateMark.getSingleMark2().getX() + MARK_SIZE / 2, + gateMark.getSingleMark2().getY() + MARK_SIZE / 2 + ); + gc.restore(); + } - double x2 = (gateMark.getSingleMark2().getLongitude() - ORIGIN_LON) * SCALE; - double y2 = (ORIGIN_LAT - gateMark.getSingleMark2().getLatitude()) * SCALE; + /** + * Calculates x and y location for every marker that fits it to the canvas the race will be drawn on. + */ + private void fitToCanvas() { + findMinMaxPoint(); + double minLonToMaxLon = scaleRaceExtremities(); + calculateReferencePointLocation(minLonToMaxLon); + givePointsXY(); + findMetersToPixels(); + } - gc.setLineWidth(1); - gc.strokeLine(x1, y1, x2, y2); + + /** + * Sets the class variables minLatPoint, maxLatPoint, minLonPoint, maxLonPoint to the marker with the leftmost + * marker, rightmost marker, southern most marker and northern most marker respectively. + */ + private void findMinMaxPoint() { + List sortedPoints = new ArrayList<>(); + for (Mark mark : raceViewController.getRace().getCourse()) + { + if (mark.getMarkType() == MarkType.SINGLE_MARK) + sortedPoints.add(mark); + else { + sortedPoints.add(((GateMark) mark).getSingleMark1()); + sortedPoints.add(((GateMark) mark).getSingleMark2()); + } + } + sortedPoints.sort(Comparator.comparingDouble(Mark::getLatitude)); + minLatPoint = sortedPoints.get(0); + maxLatPoint = sortedPoints.get(sortedPoints.size()-1); + + sortedPoints.sort(Comparator.comparingDouble(Mark::getLongitude)); + //If the course is on a point on the earth where longitudes wrap around. + // TODO: 30/03/17 cir27 - Correctly account for longitude wrapping around. + if (sortedPoints.get(sortedPoints.size()-1).getLongitude() - sortedPoints.get(0).getLongitude() > 180) + Collections.reverse(sortedPoints); + minLonPoint = sortedPoints.get(0); + maxLonPoint = sortedPoints.get(sortedPoints.size()-1); + } + + /** + * Calculates the location of a reference point, this is always the point with minimum latitude, in relation to the + * canvas. + * + * @param minLonToMaxLon The horizontal distance between the point of minimum longitude to maximum longitude. + */ + private void calculateReferencePointLocation (double minLonToMaxLon) { + Mark referencePoint = minLatPoint; + double referenceAngle; + double mapWidth = canvas.getWidth(); + double mapHeight = canvas.getHeight(); + + if (scaleDirection == ScaleDirection.HORIZONTAL) { + referenceAngle = Mark.calculateHeadingRad(referencePoint, minLonPoint) - (Math.PI * (3/4)); + referencePointX = LHS_BUFFER + (int) Math.round(distanceScaleFactor * Math.cos(referenceAngle) * Mark.calculateDistance(referencePoint, minLonPoint)); + + referenceAngle = Mark.calculateHeadingRad(referencePoint, maxLatPoint); + if (referenceAngle > (Math.PI / 2)) { + referenceAngle = (Math.PI * 2) - referenceAngle; + } + referencePointY = (int) Math.round(mapHeight - (TOP_BUFFER + BOT_BUFFER)); + referencePointY -= (int) Math.round(distanceScaleFactor * Math.cos(referenceAngle) * Mark.calculateDistance(referencePoint, maxLatPoint)); + referencePointY = (int) Math.round(referencePointY / 2d); + referencePointY += TOP_BUFFER; + referencePointY += (int) Math.round(distanceScaleFactor * Math.cos(referenceAngle) * Mark.calculateDistance(referencePoint, maxLatPoint)); + } else { + referencePointY = (int) Math.round(mapHeight - BOT_BUFFER); + + referenceAngle = (Math.PI * 2) - Mark.calculateHeadingRad(referencePoint, minLonPoint); + + referencePointX = LHS_BUFFER; + referencePointX += (int) Math.round(distanceScaleFactor * Math.sin(referenceAngle) * Mark.calculateDistance(referencePoint, minLonPoint)); + referencePointX += (int) Math.round(((mapWidth - (LHS_BUFFER + RHS_BUFFER)) - (minLonToMaxLon * distanceScaleFactor)) / 2); + } + referencePoint.setX(referencePointX); + referencePoint.setY(referencePointY); + } + + /** + * Finds the scale factor necessary to fit all race markers within the onscreen map and assigns it to distanceScaleFactor + * Returns the max horizontal distance of the map. + */ + private double scaleRaceExtremities () { + double vertAngle = Mark.calculateHeadingRad(minLatPoint, maxLatPoint); + if (vertAngle > Math.PI) + vertAngle = (2 * Math.PI) - vertAngle; + double vertDistance = Math.cos(vertAngle) * Mark.calculateDistance(minLatPoint, maxLatPoint); + + double horiAngle = Mark.calculateHeadingRad(minLonPoint, maxLonPoint); + if (horiAngle <= (Math.PI / 2)) + horiAngle = (Math.PI / 2) - horiAngle; + else + horiAngle = horiAngle - (Math.PI / 2); + double horiDistance = Math.cos(horiAngle) * Mark.calculateDistance(minLonPoint, maxLonPoint); + + double vertScale = (canvas.getHeight() - (TOP_BUFFER + BOT_BUFFER)) / vertDistance; + + if ((horiDistance * vertScale) > (canvas.getWidth() - (RHS_BUFFER + LHS_BUFFER))) { + distanceScaleFactor = (canvas.getWidth() - (RHS_BUFFER + LHS_BUFFER)) / horiDistance; + scaleDirection = ScaleDirection.HORIZONTAL; + } else { + distanceScaleFactor = vertScale; + scaleDirection = ScaleDirection.VERTICAL; + } + return horiDistance; + } + + /** + * Give all markers in the course an x,y location relative to a given reference with a known x,y location. Distances + * are scaled according to the distanceScaleFactor variable. + */ + private void givePointsXY() { + Point2D canvasLocation; + List allPoints = new ArrayList<>(raceViewController.getRace().getCourse()); + + for (Mark mark : allPoints) { + if (mark.getMarkType() != MarkType.SINGLE_MARK) { + GateMark gateMark = (GateMark) mark; + + canvasLocation = findScaledXY(gateMark.getSingleMark1()); + gateMark.getSingleMark1().setX((int) canvasLocation.getX()); + gateMark.getSingleMark1().setY((int) canvasLocation.getY()); + + canvasLocation = findScaledXY(gateMark.getSingleMark2()); + gateMark.getSingleMark2().setX((int) canvasLocation.getX()); + gateMark.getSingleMark2().setY((int) canvasLocation.getY()); + } + if (mark.getMarkType() == MarkType.CLOSED_GATE) + ((GateMark) mark).assignXYCentered(); + else { + canvasLocation = findScaledXY(mark); + mark.setX((int) canvasLocation.getX()); + mark.setY((int) canvasLocation.getY()); + } + } + } + + private Point2D findScaledXY (Mark unscaled) { + return findScaledXY (minLatPoint.getLatitude(), minLatPoint.getLongitude(), + unscaled.getLatitude(), unscaled.getLongitude()); + } + + private Point2D findScaledXY (double latA, double lonA, double latB, double lonB) { + double distanceFromReference; + double angleFromReference; + int yAxisLocation; + int xAxisLocation; + + angleFromReference = Mark.calculateHeadingRad(latA, lonA, latB, lonB); + distanceFromReference = Mark.calculateDistance(latA, lonA, latB, lonB); + + if (angleFromReference > (Math.PI / 2)) { + angleFromReference = (Math.PI * 2) - angleFromReference; + xAxisLocation = referencePointX; + xAxisLocation -= (int) Math.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference); + } else { + xAxisLocation = referencePointX; + xAxisLocation += (int) Math.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference); + } + yAxisLocation = referencePointY; + yAxisLocation -= (int) Math.round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference); + + return new Point2D(xAxisLocation, yAxisLocation); + } + + + + /** + * Find the number of meters per pixel. + */ + private void findMetersToPixels () { + Double angularDistance; + Double angle; + Double straightLineDistance; + if (scaleDirection == ScaleDirection.HORIZONTAL) { + angularDistance = Mark.calculateDistance(minLonPoint, maxLonPoint); + angle = Mark.calculateHeadingRad(minLonPoint, maxLonPoint); + if (angle > Math.PI / 2) { + straightLineDistance = Math.cos(angle - Math.PI) * angularDistance; + } else { + straightLineDistance = Math.cos(angle) * angularDistance; + } + metersToPixels = (CANVAS_WIDTH - RHS_BUFFER - LHS_BUFFER) / straightLineDistance; + } else { + angularDistance = Mark.calculateDistance(minLatPoint, maxLatPoint); + angle = Mark.calculateHeadingRad(minLatPoint, maxLatPoint); + if (angle < Math.PI / 2) { + straightLineDistance = Math.cos(angle) * angularDistance; + } else { + straightLineDistance = Math.cos(-angle + Math.PI * 2) * angularDistance; + } + metersToPixels = (CANVAS_HEIGHT - TOP_BUFFER - BOT_BUFFER) / straightLineDistance; + } + } + + private Point2D latLonToXY (double latitude, double longitude) { + return findScaledXY(minLatPoint.getLatitude(), minLatPoint.getLongitude(), latitude, longitude); } } \ No newline at end of file diff --git a/src/main/java/seng302/controllers/RaceViewController.java b/src/main/java/seng302/controllers/RaceViewController.java index 965fbc7d..8acfba2b 100644 --- a/src/main/java/seng302/controllers/RaceViewController.java +++ b/src/main/java/seng302/controllers/RaceViewController.java @@ -2,10 +2,7 @@ package seng302.controllers; import javafx.animation.Animation; import javafx.animation.KeyFrame; -import javafx.animation.KeyValue; import javafx.animation.Timeline; -import javafx.beans.property.DoubleProperty; -import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; @@ -42,6 +39,7 @@ public class RaceViewController { @FXML private CanvasController includedCanvasController; + private ArrayList startingBoats = new ArrayList<>(); private boolean displayAnnotations; private boolean displayFps; private Timeline timerTimeline; @@ -50,24 +48,29 @@ public class RaceViewController { private Race race; public void initialize() { - includedCanvasController.setup(this); RaceController raceController = new RaceController(); raceController.initializeRace(); race = raceController.getRace(); + for (Boat boat : race.getBoats()) { + startingBoats.add(boat); + } +// try{ +// initializeTimelines(); +// } +// catch (Exception e){ +// e.printStackTrace(); +// } - initializeTimer(); + includedCanvasController.setup(this); + includedCanvasController.initializeCanvas(); + //initializeTimer(); initializeSettings(); - try{ - initializeTimelines(); - } - catch (Exception e){ - e.printStackTrace(); - } //set wind direction!!!!!!! can't find another place to put my code --haoming double windDirection = new ConfigParser("/config/config.xml").getWindDirection(); windDirectionText.setText(String.format("%.1f°", windDirection)); windArrowText.setRotate(windDirection); + includedCanvasController.timer.start(); } private void initializeSettings(){ @@ -114,39 +117,39 @@ public class RaceViewController { */ private void initializeTimelines() { HashMap boat_events = race.getEvents(); - for (Boat boat : boat_events.keySet()) { - // x, y are the real time coordinates - DoubleProperty x = new SimpleDoubleProperty(); - DoubleProperty y = new SimpleDoubleProperty(); - - List keyFrames = new ArrayList<>(); - List events = boat_events.get(boat); - - // iterates all events and convert each event to keyFrame, then add them into a list - for (Event event : events) { - if (event.getIsFinishingEvent()) { - keyFrames.add( - new KeyFrame(Duration.seconds(event.getTime()), - onFinished -> {race.setBoatFinished(boat); handleEvent(event);}, - new KeyValue(x, event.getThisMark().getLatitude()), - new KeyValue(y, event.getThisMark().getLongitude()) - ) - ); - } else { - keyFrames.add( - new KeyFrame(Duration.seconds(event.getTime()), - onFinished ->{ - handleEvent(event); - boat.setHeading(event.getBoatHeading()); - }, - new KeyValue(x, event.getThisMark().getLatitude()), - new KeyValue(y, event.getThisMark().getLongitude()) - ) - ); - } - } - timelineInfos.put(boat, new TimelineInfo(new Timeline(keyFrames.toArray(new KeyFrame[keyFrames.size()])), x, y)); + startingBoats.add(boat); +// // x, y are the real time coordinates +// DoubleProperty x = new SimpleDoubleProperty(); +// DoubleProperty y = new SimpleDoubleProperty(); +// +// List keyFrames = new ArrayList<>(); +// List events = boat_events.get(boat); +// +// // iterates all events and convert each event to keyFrame, then add them into a list +// for (Event event : events) { +// if (event.getIsFinishingEvent()) { +// keyFrames.add( +// new KeyFrame(Duration.seconds(event.getTime()), +// onFinished -> {race.setBoatFinished(boat); handleEvent(event);}, +// new KeyValue(x, event.getThisMark().getLatitude()), +// new KeyValue(y, event.getThisMark().getLongitude()) +// ) +// ); +// } else { +// keyFrames.add( +// new KeyFrame(Duration.seconds(event.getTime()), +// onFinished ->{ +// handleEvent(event); +// boat.setHeading(event.getBoatHeading()); +// }, +// new KeyValue(x, event.getThisMark().getLatitude()), +// new KeyValue(y, event.getThisMark().getLongitude()) +// ) +// ); +// } +// } +// timelineInfos.put(boat, new TimelineInfo(new Timeline(keyFrames.toArray(new KeyFrame[keyFrames.size()])), x, y)); } setRaceDuration(); } @@ -277,4 +280,8 @@ public class RaceViewController { public Map getTimelineInfos() { return timelineInfos; } + + public ArrayList getStartingBoats(){ + return startingBoats; + } } \ No newline at end of file diff --git a/src/main/java/seng302/models/Boat.java b/src/main/java/seng302/models/Boat.java index 0973ad38..004ddc57 100644 --- a/src/main/java/seng302/models/Boat.java +++ b/src/main/java/seng302/models/Boat.java @@ -1,20 +1,23 @@ package seng302.models; import javafx.scene.paint.Color; +import javafx.scene.shape.Polygon; +import javafx.scene.text.Text; +import javafx.scene.transform.Rotate; +import javafx.scene.transform.Translate; +import javafx.util.Pair; /** * Represents a boat in the race. */ public class Boat { - private String teamName; // The name of the team, this is also the name of the boat - private double velocity; // In meters/second - private double lat; // Boats position - private double lon; // - - private double distanceToNextMark; - private Color color; - private int markLastPast; + private String teamName; + private double velocity; + private double lat; + private double lon; private double heading; + private int markLastPast; private String shortName; public Boat(String teamName) { @@ -22,7 +25,6 @@ public class Boat { this.velocity = 10; // Default velocity this.lat = 0.0; this.lon = 0.0; - this.distanceToNextMark = 0.0; this.shortName = ""; } @@ -36,8 +38,6 @@ public class Boat { public Boat(String teamName, double boatVelocity, String shortName) { this.teamName = teamName; this.velocity = boatVelocity; - this.distanceToNextMark = 0.0; - this.color = Colors.getColor(); this.shortName = shortName; } @@ -88,8 +88,9 @@ public class Boat { this.lon = lon; } - public void setDistanceToNextMark(double distance){ - this.distanceToNextMark = distance; + public Pair getLocation () + { + return new Pair<>(this.lat, this.lon); } public double getLatitude(){ @@ -100,8 +101,12 @@ public class Boat { return this.lon; } - public Color getColor() { - return color; + public void setLatitude (double latitude) { + this.lat = latitude; + } + + public void setlongitude (double longitude) { + this.lon =longitude; } public double getSpeedInKnots(){ @@ -116,15 +121,16 @@ public class Boat { return markLastPast; } - public void setHeading(double heading){ - this.heading = heading; - } - public double getHeading(){ return this.heading; } + public void setHeading(double heading) { + this.heading = heading; + } + public String getShortName(){ return this.shortName; } + } \ No newline at end of file diff --git a/src/main/java/seng302/models/BoatGroup.java b/src/main/java/seng302/models/BoatGroup.java new file mode 100644 index 00000000..06ea1306 --- /dev/null +++ b/src/main/java/seng302/models/BoatGroup.java @@ -0,0 +1,175 @@ +package seng302.models; + +import javafx.scene.Group; +import javafx.scene.Node; +import javafx.scene.paint.Color; +import javafx.scene.shape.Polygon; +import javafx.scene.text.Text; +import javafx.scene.transform.Rotate; +import javafx.scene.transform.Translate; + +/** + * Created by CJIRWIN on 25/04/2017. + */ +public class BoatGroup extends Group{ + private static final double TEAMNAME_X_OFFSET = 15d; + private static final double TEAMNAME_Y_OFFSET = -20d; + private static final double VELOCITY_X_OFFSET = 15d; + private static final double VELOCITY_Y_OFFSET = -10d; + private static final double VELOCITY_WAKE_RATIO = 2d; + private static final double BOAT_HEIGHT = 15d; + private static final double BOAT_WIDTH = 10d; + //Time between sections of race - Should be changed to 200 for actual program. + private static double expectedUpdateInterval = 2000; + + private Boat boat; + + private double rotationalGoal; + private double currentRotation; + private double rotationalVelocity; + private double pixelVelocityX; + private double pixelVelocityY; + + public BoatGroup (Boat boat, Color color){ + super(); + this.boat = boat; + initChildren(color); + } + + public BoatGroup (Boat boat, Color color, double... points) + { + super(); + initChildren(color, points); + } + + private void initChildren (Color color, double... points) { + Polygon boatPoly = new Polygon(points); + boatPoly.setFill(color); + + Polygon wake = new Polygon( + 5.0,0.0, + 10.0, boat.getVelocity() * VELOCITY_WAKE_RATIO, + 0.0, boat.getVelocity() * VELOCITY_WAKE_RATIO + ); + wake.setFill(Color.DARKBLUE); + + Text teamNameObject = new Text(boat.getShortName()); + Text velocityObject = new Text(String.valueOf(boat.getVelocity())); + + boatPoly.setLayoutX(0); + boatPoly.setLayoutY(0); + boatPoly.relocate(boatPoly.getLayoutX(), boatPoly.getLayoutY()); + + teamNameObject.setX(TEAMNAME_X_OFFSET); + teamNameObject.setY(TEAMNAME_Y_OFFSET); + teamNameObject.relocate(teamNameObject.getX(), teamNameObject.getY()); + + velocityObject.setX(VELOCITY_X_OFFSET); + velocityObject.setY(VELOCITY_Y_OFFSET); + velocityObject.relocate(velocityObject.getX(), velocityObject.getY()); + + wake.setLayoutX(0); + wake.setLayoutY(0); + wake.relocate(wake.getLayoutX(), wake.getLayoutY()); + + super.getChildren().addAll(boatPoly, wake, teamNameObject, velocityObject); + } + + private void initChildren (Color color) { + initChildren(color, + BOAT_WIDTH / 2, 0.0, + BOAT_WIDTH, BOAT_HEIGHT, + 0.0, BOAT_HEIGHT); + } + /** + * Moves the boat and its children annotations from its current coordinates by specified amounts. + * @param dx The amount to move the X coordinate by + * @param dy The amount to move the Y coordinate by + */ + void moveBy(Double dx, Double dy, Double rotation) { + super.setLayoutX(super.getLayoutX() + dx); + super.setLayoutY(super.getLayoutY() + dy); + rotateBoat(rotation); + } + + /** + * Moves the boat and its children annotations to coordinates specified + * @param x The X coordinate to move the boat to + * @param y The Y coordinate to move the boat to + */ + public void moveBoatTo(Double x, Double y, Double rotation) { + super.relocate(x, y); + currentRotation = 0; + rotateBoat(rotation); + } + + public void updatePosition (double timeInterval) { + double dx = pixelVelocityX * timeInterval; + double dy = pixelVelocityY * timeInterval; + double rotation = 0d; + if (rotationalGoal > currentRotation && rotationalVelocity > 0) { + rotation = rotationalVelocity * timeInterval; + } else if (rotationalGoal < currentRotation && rotationalVelocity < 0) { + rotation = rotationalVelocity * timeInterval; + } + moveBy(dx, dy, rotation); + } + + public void setDestination (double newXValue, double newYValue) { + this.pixelVelocityX = (newXValue - super.getLayoutX()) / expectedUpdateInterval; + this.pixelVelocityY = (newYValue - super.getLayoutY()) / expectedUpdateInterval; + //this.destinationX = newXValue; + //this.destinationY = newYValue; + this.rotationalGoal = Math.abs( + Math.toDegrees( + Math.atan( + (newYValue - super.getLayoutY()) / (newXValue - super.getLayoutX()) + ) + ) + ); + if (super.getLayoutY() >= newYValue && super.getLayoutX() <= newXValue) + rotationalGoal = 90 - rotationalGoal; + else if (super.getLayoutY() < newYValue && super.getLayoutX() <= newXValue) + rotationalGoal = 90 + rotationalGoal; + else if (super.getLayoutY() >= newYValue && super.getLayoutX() > newXValue) + rotationalGoal = 270 + rotationalGoal; + else + rotationalGoal = 270 - rotationalGoal; + // TODO: 25/04/2017 cir27 - Verify this logic is correct. Want to produce the shortest path. + if (Math.abs(360 - rotationalGoal + currentRotation) < Math.abs(rotationalGoal - currentRotation)) { + System.out.println("ROTATE"); + this.rotationalVelocity = (360 - rotationalGoal + currentRotation) / expectedUpdateInterval; + } else { + this.rotationalVelocity = (rotationalGoal - currentRotation) / expectedUpdateInterval; + } + } + + public void rotateBoat (double rotationDeg) { + currentRotation += rotationDeg; + Node boatPoly = super.getChildren().get(0); + boatPoly.getTransforms().clear(); + boatPoly.getTransforms().add(new Rotate(currentRotation, BOAT_WIDTH/2, 0)); + Node wake = super.getChildren().get(1); + wake.getTransforms().clear(); + wake.getTransforms().add(new Translate(0, BOAT_HEIGHT)); + wake.getTransforms().add(new Rotate(currentRotation, BOAT_WIDTH/2, -BOAT_HEIGHT)); + } + + public static double getExpectedUpdateInterval() { + return expectedUpdateInterval; + } + + public static void setExpectedUpdateInterval(double expectedUpdateInterval) { + BoatGroup.expectedUpdateInterval = expectedUpdateInterval; + } + + public void forceRotation () { + rotateBoat (rotationalGoal - currentRotation); + } + + public void toogleAnnotations () { + super.getChildren().get(1).setVisible(false); + super.getChildren().get(2).setVisible(false); + super.getChildren().get(3).setVisible(false); + } +} diff --git a/src/main/java/seng302/models/Colors.java b/src/main/java/seng302/models/Colors.java index 419753dc..23ef8f4e 100644 --- a/src/main/java/seng302/models/Colors.java +++ b/src/main/java/seng302/models/Colors.java @@ -11,10 +11,9 @@ public enum Colors { static Integer index = 0; public static Color getColor() { - index++; - if (index > 6) { - index = 1; + if (index == 6) { + index = 0; } - return Color.valueOf(values()[index-1].toString()); + return Color.valueOf(values()[index++].toString()); } } diff --git a/src/main/java/seng302/models/Event.java b/src/main/java/seng302/models/Event.java index e803845d..df298741 100644 --- a/src/main/java/seng302/models/Event.java +++ b/src/main/java/seng302/models/Event.java @@ -16,7 +16,7 @@ public class Event { private Mark mark1; // This mark private Mark mark2; // Next mark private int markPosInRace; // the position of the current mark in the race course - + private double heading; private final double ORIGIN_LAT = 32.320504; private final double ORIGIN_LON = -64.857063; private final double SCALE = 16000; @@ -36,6 +36,8 @@ public class Event { this.mark1 = mark1; this.mark2 = mark2; this.markPosInRace = markPosInRace; + this.heading = angleFromCoordinate(mark1, mark2); + } /** @@ -92,7 +94,7 @@ public class Event { if (this.isFinishingEvent) { return (this.getTimeString() + ", " + this.getBoat().getTeamName() + " finished the race"); } - System.out.println(this.getDistanceBetweenMarks()); +// System.out.println(this.getDistanceBetweenMarks()); return (this.getTimeString() + ", " + this.getBoat().getTeamName() + " passed " + this.mark1.getName() + " going heading " + this.getBoatHeading() + "°"); } @@ -138,6 +140,30 @@ public class Event { } + /** + * Calculates the angle between to angular co-ordinates on a sphere. + * + * @param geoPointOne first geographical location + * @param geoPointTwo second geographical location + * @return the angle from point one to point two + */ + private Double angleFromCoordinate(Mark geoPointOne, Mark geoPointTwo) { + if (geoPointTwo == null) + return null; + + double x1 = geoPointOne.getLatitude(); + double y1 = -geoPointOne.getLongitude(); + double x2 = geoPointTwo.getLatitude(); + double y2 = -geoPointTwo.getLongitude(); + + return Math.toDegrees(Math.atan2(x2-x1, y2-y1)); + + } + + public double getHeading() { + return heading; + } + public Mark getThisMark() { return this.mark1; } diff --git a/src/main/java/seng302/models/Race.java b/src/main/java/seng302/models/Race.java index 165d9468..01d1adf8 100644 --- a/src/main/java/seng302/models/Race.java +++ b/src/main/java/seng302/models/Race.java @@ -9,6 +9,7 @@ import java.util.*; * Created by mra106 on 8/3/2017. */ public class Race { + private ArrayList boats; // The boats in the race private ArrayList finishingOrder; // The order in which the boats finish the race private HashMap events = new HashMap<>(); // The events that occur in the race diff --git a/src/main/java/seng302/models/mark/GateMark.java b/src/main/java/seng302/models/mark/GateMark.java index 2b152e65..2dfb9fdd 100644 --- a/src/main/java/seng302/models/mark/GateMark.java +++ b/src/main/java/seng302/models/mark/GateMark.java @@ -16,8 +16,8 @@ public class GateMark extends Mark { * @param singleMark1 one single mark inside of the gate mark * @param singleMark2 the second mark inside of the gate mark */ - public GateMark(String name, SingleMark singleMark1, SingleMark singleMark2, double latitude, double longitude) { - super(name, MarkType.GATE_MARK, latitude, longitude); + public GateMark(String name, MarkType type, SingleMark singleMark1, SingleMark singleMark2, double latitude, double longitude) { + super(name, type, latitude, longitude); this.singleMark1 = singleMark1; this.singleMark2 = singleMark2; } @@ -47,4 +47,16 @@ public class GateMark extends Mark { //return (this.getSingleMark1().getLongitude() + this.getSingleMark2().getLongitude()) / 2; return (this.getSingleMark1().getLongitude()); } + + public void assignXYCentered () { + System.out.println("POSSIBLE GOOF " + xValue + " " + yValue); + System.out.println(singleMark1.getX() + " " + singleMark1.getY()); + System.out.println(singleMark2.getX() + " " + singleMark2.getY()); + double dx = singleMark2.getX() - singleMark1.getX(); + System.out.println("dx + " + dx); + double dy = singleMark2.getY() - singleMark1.getY(); + xValue = (int) Math.round(singleMark1.getX() + dx / 2); + yValue = (int) Math.round(singleMark1.getY() + dy / 2); + System.out.println("PROBABLE GAAF " + xValue + " " + yValue); + } } diff --git a/src/main/java/seng302/models/mark/Mark.java b/src/main/java/seng302/models/mark/Mark.java index 3e635856..98af4057 100644 --- a/src/main/java/seng302/models/mark/Mark.java +++ b/src/main/java/seng302/models/mark/Mark.java @@ -10,6 +10,8 @@ public abstract class Mark { private MarkType markType; private double latitude; private double longitude; + Integer xValue; + Integer yValue; /** * Create a mark instance by passing its name and type @@ -28,6 +30,76 @@ public abstract class Mark { this.longitude = longitude; } + /** + * Calculated the heading in radians from first Mark to the second Mark. + * + * @param pointOne First Mark + * @param pointTwo Second Mark + * @return Heading in radians + */ + public static Double calculateHeadingRad(Mark pointOne, Mark pointTwo) { + Double longitude1 = pointOne.getLongitude(); + Double longitude2 = pointTwo.getLongitude(); + Double latitude1 = pointOne.getLatitude(); + Double latitude2 = pointTwo.getLatitude(); + return calculateHeadingRad(latitude1, longitude1, latitude2, longitude2); + } + + /** + * Calculate the heading in radians from geographical location with latitude1, longitude 1 to geographical + * latitude2, longitude 2 + * @param longitude1 Longitude of first point in degrees + * @param longitude2 Longitude of second point in degrees + * @param latitude1 Latitude of first point in degrees + * @param latitude2 Latitude of first point in degrees + * @return Heading in radians + */ + public static double calculateHeadingRad (Double latitude1, Double longitude1, Double latitude2, Double longitude2) { + latitude1 = Math.toRadians(latitude1); + latitude2 = Math.toRadians(latitude2); + Double longDiff= Math.toRadians(longitude2-longitude1); + Double y = Math.sin(longDiff)*Math.cos(latitude2); + Double x = Math.cos(latitude1)*Math.sin(latitude2)-Math.sin(latitude1)*Math.cos(latitude2)*Math.cos(longDiff); + return Math.atan2(y, x); + } + + /** + * Calculates the distance in meters from the first Mark to a second Mark + * + * @param pointOne First Mark + * @param pointTwo Second Mark + * @return Distance in meters + */ + public static Double calculateDistance(Mark pointOne, Mark pointTwo) { + Double longitude1 = pointOne.getLongitude(); + Double longitude2 = pointTwo.getLongitude(); + Double latitude1 = pointOne.getLatitude(); + Double latitude2 = pointTwo.getLatitude(); + return calculateDistance(latitude1, longitude1, latitude2, longitude2); + } + + /** + * Calculate the distance in meters from geographical location with latitude1, longitude 1 to geographical + * latitude2, longitude 2 + * + * @param longitude1 Longitude of first point in degrees + * @param longitude2 Longitude of second point in degrees + * @param latitude1 Latitude of first point in degrees + * @param latitude2 Latitude of first point in degrees + * @return Distance in meters + */ + public static Double calculateDistance (Double latitude1, Double longitude1, Double latitude2, Double longitude2) { + Double theta = longitude1 - longitude2; + Double dist = Math.sin(Math.toRadians(latitude1)) * Math.sin(Math.toRadians(latitude2)) + + Math.cos(Math.toRadians(latitude1)) * Math.cos(Math.toRadians(latitude2)) * + Math.cos(Math.toRadians(theta)); + dist = Math.acos(dist); + dist = Math.toDegrees(dist); + dist = dist * 60 * 1.1508; //nautical mile (distance between two degrees) * (degrees in a minute) + dist = dist * 1609.344; //ratio of miles to metres + return dist; + } + public String getName() { return name; } @@ -51,4 +123,21 @@ public abstract class Mark { public double getLongitude() { return longitude; } + + public int getX () { + return xValue; + } + + public int getY () { + return yValue; + } + + public void setX (int x) { + this.xValue = x; + } + + public void setY (int y) { + this.yValue = y; + } + } diff --git a/src/main/java/seng302/models/mark/MarkType.java b/src/main/java/seng302/models/mark/MarkType.java index 3de5cba3..4ac6a9e3 100644 --- a/src/main/java/seng302/models/mark/MarkType.java +++ b/src/main/java/seng302/models/mark/MarkType.java @@ -5,5 +5,5 @@ package seng302.models.mark; * Created by Haoming Yin (hyi25) on 17/3/17. */ public enum MarkType { - SINGLE_MARK, GATE_MARK + SINGLE_MARK, OPEN_GATE, CLOSED_GATE } diff --git a/src/main/java/seng302/models/parsers/CourseParser.java b/src/main/java/seng302/models/parsers/CourseParser.java index 0ad0c471..04a40e0a 100644 --- a/src/main/java/seng302/models/parsers/CourseParser.java +++ b/src/main/java/seng302/models/parsers/CourseParser.java @@ -65,7 +65,11 @@ public class CourseParser extends FileParser { String name = element.getElementsByTagName("name").item(0).getTextContent(); SingleMark mark1 = generateSingleMark(element.getElementsByTagName("mark").item(0)); SingleMark mark2 = generateSingleMark(element.getElementsByTagName("mark").item(1)); - GateMark gateMark = new GateMark(name, mark1, mark2, mark1.getLatitude(), mark1.getLongitude()); + GateMark gateMark; + if (name.equals("Start") || name.equals("Finish")) + gateMark = new GateMark(name, MarkType.CLOSED_GATE, mark1, mark2, mark1.getLatitude(), mark1.getLongitude()); + else + gateMark = new GateMark(name, MarkType.OPEN_GATE, mark1, mark2, mark1.getLatitude(), mark1.getLongitude()); marks.put(name, gateMark); } } diff --git a/src/test/java/seng302/ColorsTest.java b/src/test/java/seng302/ColorsTest.java index a6681b26..6fc07b41 100644 --- a/src/test/java/seng302/ColorsTest.java +++ b/src/test/java/seng302/ColorsTest.java @@ -1,14 +1,10 @@ package seng302; import javafx.scene.paint.Color; +import org.junit.Assert; import org.junit.Test; -import seng302.models.Boat; import seng302.models.Colors; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -16,30 +12,13 @@ import static org.junit.Assert.assertEquals; * Created by ryan_ on 16/03/2017. */ public class ColorsTest { - //@Test + + @Test public void testNextColor() { - List boats = new ArrayList<>(); - boats.add(new Boat("Team 1")); - boats.add(new Boat("Team 2")); - boats.add(new Boat("Team 3")); - boats.add(new Boat("Team 4")); - boats.add(new Boat("Team 5")); - boats.add(new Boat("Team 6")); - - int count = 0; - List enumColors = new ArrayList<>(); - while (count < 6) { - Color color = Colors.getColor(); - enumColors.add(color); - count++; + Color expectedColors[] = {Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.BLUE, Color.PURPLE}; + for (int i = 0; i<6; i++) + { + Assert.assertEquals(expectedColors[i], Colors.getColor()); } - - List boatColors = new ArrayList<>(); - for (Boat boat : boats) { - Color color = boat.getColor(); - boatColors.add(color); - } - - assertEquals(enumColors, boatColors); } } diff --git a/src/test/java/seng302/models/mark/MarkTest.java b/src/test/java/seng302/models/mark/MarkTest.java index f1943c64..b48f5818 100644 --- a/src/test/java/seng302/models/mark/MarkTest.java +++ b/src/test/java/seng302/models/mark/MarkTest.java @@ -18,7 +18,7 @@ public class MarkTest { public void setUp() throws Exception { this.singleMark1 = new SingleMark("testMark_SM1", 12.23234, -34.342); this.singleMark2 = new SingleMark("testMark_SM2", 12.23239, -34.352); - this.gateMark = new GateMark("testMark_GM", singleMark1, singleMark2, singleMark1.getLatitude(), singleMark2.getLongitude()); + this.gateMark = new GateMark("testMark_GM", MarkType.OPEN_GATE, singleMark1, singleMark2, singleMark1.getLatitude(), singleMark2.getLongitude()); } @Test @@ -30,7 +30,7 @@ public class MarkTest { @Test public void getMarkType() throws Exception { assertTrue(this.singleMark2.getMarkType() == MarkType.SINGLE_MARK); - assertTrue(this.gateMark.getMarkType() == MarkType.GATE_MARK); + assertTrue(this.gateMark.getMarkType() == MarkType.OPEN_GATE); } @Test diff --git a/src/test/java/seng302/models/parsers/CourseParserTest.java b/src/test/java/seng302/models/parsers/CourseParserTest.java index 865caec6..201c1b4b 100644 --- a/src/test/java/seng302/models/parsers/CourseParserTest.java +++ b/src/test/java/seng302/models/parsers/CourseParserTest.java @@ -25,7 +25,7 @@ public class CourseParserTest { public void getGates() throws Exception { ArrayList course = cp.getCourse(); - assertTrue(MarkType.GATE_MARK == course.get(0).getMarkType()); + assertTrue(MarkType.OPEN_GATE == course.get(0).getMarkType()); GateMark gateMark1 = (GateMark) course.get(0); assertEquals(32.293771, gateMark1.getSingleMark2().getLatitude(), 0.00000001);