From c08504293b8eaac399efaaa5bf55cf3316f7fea6 Mon Sep 17 00:00:00 2001 From: zyt10 Date: Fri, 17 Mar 2017 18:21:11 +1300 Subject: [PATCH] Created canvas and race controllers to display boats on canvas and modified marks and parsers to support them. #story[377] #pair[zyt10, ptg19] --- doc/examples/config.json | 14 +++--- .../seng302/controllers/CanvasController.java | 22 ++++++-- .../seng302/controllers/RaceController.java | 17 +++---- src/main/java/seng302/models/Event.java | 47 +++++++++-------- src/main/java/seng302/models/GateMark.java | 0 src/main/java/seng302/models/OldApp.java | 10 ++-- src/main/java/seng302/models/Race.java | 31 +++++++----- .../java/seng302/models/mark/GateMark.java | 4 +- src/main/java/seng302/models/mark/Mark.java | 17 +++++++ .../seng302/models/parsers/CourseParser.java | 33 ++++++++---- .../java/seng302/models/mark/MarkTest.java | 2 +- .../models/parsers/CourseParserTest.java | 50 +++++++++---------- 12 files changed, 148 insertions(+), 99 deletions(-) delete mode 100644 src/main/java/seng302/models/GateMark.java diff --git a/doc/examples/config.json b/doc/examples/config.json index afea58bf..8a3f3ac2 100644 --- a/doc/examples/config.json +++ b/doc/examples/config.json @@ -1,31 +1,31 @@ { "race-name": "AC35", "time-scale": 1.0, - "race-size": 2, + "race-size": 6, "teams": [ { "team-name": "Oracle Team USA", - "velocity": 20.9 + "velocity": 30.9 }, { "team-name": "Artemis Racing", - "velocity": 18.3 + "velocity": 10.3 }, { "team-name": "Emirates Team New Zealand", - "velocity": 21.5 + "velocity": 51.5 }, { "team-name": "Groupama Team France", - "velocity": 19.9 + "velocity": 9.9 }, { "team-name": "Land Rover BAR", - "velocity": 17.6 + "velocity": 99.6 }, { "team-name": "SoftBank Team Japan", - "velocity": 16.6 + "velocity": 45.6 } ] } \ No newline at end of file diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index 34ce2267..714b6adf 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -12,6 +12,7 @@ import javafx.scene.canvas.GraphicsContext; import javafx.scene.paint.Color; import javafx.util.Duration; import seng302.models.*; +import seng302.models.mark.Mark; import java.util.ArrayList; import java.util.HashMap; @@ -24,14 +25,16 @@ import static java.lang.Math.abs; */ public class CanvasController { @FXML private Canvas canvas; + Race race; + GraphicsContext gc; public void initialize() { - GraphicsContext gc = canvas.getGraphicsContext2D(); + gc = canvas.getGraphicsContext2D(); gc.scale(5,5); RaceController raceController = new RaceController(); raceController.initializeRace(); - Race race = raceController.getRace(); + race = raceController.getRace(); HashMap timelineInfos = new HashMap<>(); HashMap boat_events = race.getEvents(); @@ -60,12 +63,13 @@ public class CanvasController { public void handle(long now) { GraphicsContext gc = canvas.getGraphicsContext2D(); gc.clearRect(0,0,760,360); + drawCourse(); gc.setFill(Color.FORESTGREEN); for (Boat boat: timelineInfos.keySet()){ TimelineInfo timelineInfo = timelineInfos.get(boat); // System.out.println(timelineInfo.getX().doubleValue()); // System.out.println(timelineInfo.getY().doubleValue()); - drawBoat(gc, timelineInfo.getX().doubleValue(), timelineInfo.getY().doubleValue(), boat.getColor()); + drawBoat(timelineInfo.getX().doubleValue(), timelineInfo.getY().doubleValue(), boat.getColor()); } } }; @@ -86,7 +90,7 @@ public class CanvasController { } - private void drawBoat(GraphicsContext gc, double x, double y, Color color) { + private void drawBoat(double x, double y, Color color) { x = abs(x - 32.313291) * 1000; // to prevent negative longtitude y = abs(y + 64.887057) * 1000; // to prevent negative latitude @@ -95,4 +99,14 @@ public class CanvasController { gc.setFill(color); gc.fillOval(x, y, diameter, diameter); } + + private void drawCourse(){ + for (Mark mark: race.getCourse()){ + double x = abs(mark.getLatitude() - 32.313291) * 1000; // to prevent negative longtitude + double y = abs(mark.getLongitude() + 64.887057) * 1000; // to prevent negative latitude + + gc.setFill(Color.BLACK); + gc.fillOval(x, y, 2, 2); + } + } } diff --git a/src/main/java/seng302/controllers/RaceController.java b/src/main/java/seng302/controllers/RaceController.java index bad178d2..11f3a318 100644 --- a/src/main/java/seng302/controllers/RaceController.java +++ b/src/main/java/seng302/controllers/RaceController.java @@ -1,8 +1,9 @@ package seng302.controllers; import seng302.models.Boat; -import seng302.models.FileParser; -import seng302.models.Mark; +import seng302.models.OldFileParser; +import seng302.models.parsers.*; +import seng302.models.mark.*; import seng302.models.Race; import java.io.FileNotFoundException; @@ -38,11 +39,11 @@ public class RaceController { public Race createRace(String configFile) throws Exception { Race race = new Race(); - FileParser fp; + OldFileParser fp; // Read team names from file try{ - fp = new FileParser(configFile); + fp = new OldFileParser(configFile); } catch (FileNotFoundException e){ System.out.println("Config file does not exist"); @@ -76,12 +77,8 @@ public class RaceController { race.addBoat(new Boat(boatNames.get(i), (Double) (teams.get(i).get("velocity")))); } - // Add marks to race in order - race.addMark(new Mark("Start", 32.296038,-64.854401 )); - race.addMark(new Mark("Mid Mark", 32.292881,-64.843231 )); - race.addMark(new Mark("Leeward Gate", 32.283808,-64.850012 )); - race.addMark(new Mark("Windward Gate", 32.309908,-64.833665 )); - race.addMark(new Mark("Finish", 32.318439,-64.837367 )); + CourseParser cp = new CourseParser("doc/examples/course.xml"); + race.addCourse(cp.getCourse()); return race; } diff --git a/src/main/java/seng302/models/Event.java b/src/main/java/seng302/models/Event.java index 54f92690..85da94a3 100644 --- a/src/main/java/seng302/models/Event.java +++ b/src/main/java/seng302/models/Event.java @@ -1,5 +1,6 @@ package seng302.models; +import seng302.models.mark.Mark; import seng302.models.mark.SingleMark; import java.text.SimpleDateFormat; @@ -11,10 +12,10 @@ import java.util.Date; */ public class Event { private Double time; // Time the event occurs - private Boat boat; + private Boat boat; private boolean isFinishingEvent = false; // This event occurs when a boat finishes the race - private SingleMark singleMark1; // This mark - private SingleMark singleMark2; // Next SingleMark + private Mark mark1; // This mark + private Mark mark2; // Next mark /** @@ -24,12 +25,12 @@ public class Event { * @param eventTime, what time the event happens * @param eventBoat, the boat that the event belongs to */ - public Event(Double eventTime, Boat eventBoat, SingleMark singleMark1, SingleMark singleMark2) { + public Event(Double eventTime, Boat eventBoat, Mark mark1, Mark mark2) { this.time = eventTime; this.boat = eventBoat; //this.leg = eventLeg; - this.singleMark1 = singleMark1; - this.singleMark2 = singleMark2; + this.mark1 = mark1; + this.mark2 = mark2; } /** @@ -39,10 +40,10 @@ public class Event { * @param eventTime, what time the event happens * @param eventBoat, the boat that the event belongs to */ - public Event(Double eventTime, Boat eventBoat, SingleMark singleMark1) { + public Event(Double eventTime, Boat eventBoat, SingleMark mark1) { this.time = eventTime; this.boat = eventBoat; - this.singleMark1 = singleMark1; + this.mark1 = mark1; this.isFinishingEvent = true; } @@ -110,21 +111,21 @@ public class Event { return (this.getTimeString() + ", " + this.getBoat().getTeamName() + " finished the race"); } System.out.println(this.getDistanceBetweenMarks()); - return (this.getTimeString() + ", " + this.getBoat().getTeamName() + " passed " + this.singleMark1.getName() + " going heading " + this.getBoatHeading() + "°"); + return (this.getTimeString() + ", " + this.getBoat().getTeamName() + " passed " + this.mark1.getName() + " going heading " + this.getBoatHeading() + "°"); } /** * @return the distance between the two marks */ - public double getDistanceBetweenMarks(){ - //return Math.sqrt(Math.pow(singleMark1.getLatitude()-singleMark2.getLatitude(), 2) + Math.pow(singleMark1.getLongitude()-singleMark2.getLongitude(), 2)); + public double getDistanceBetweenMarks() { + //return Math.sqrt(Math.pow(mark1.getLatitude()-mark2.getLatitude(), 2) + Math.pow(mark1.getLongitude()-mark2.getLongitude(), 2)); double earth_radius = 6378.137; - double dLat = this.singleMark2.getLatitude() * Math.PI / 180 - this.singleMark1.getLatitude() * Math.PI / 180; - double dLon = this.singleMark2.getLongitude() * Math.PI / 180 - this.singleMark1.getLongitude() * Math.PI / 180; + double dLat = this.mark2.getLatitude() * Math.PI / 180 - this.mark1.getLatitude() * Math.PI / 180; + double dLon = this.mark2.getLongitude() * Math.PI / 180 - this.mark1.getLongitude() * Math.PI / 180; - double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(this.singleMark1.getLatitude() * Math.PI / 180) * Math.sin(dLon/2) * Math.sin(dLon/2); + double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(this.mark1.getLatitude() * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2); - double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); double d = earth_radius * c; return d * 1000; @@ -133,8 +134,8 @@ public class Event { /** * @return the boats heading */ - public double getBoatHeading(){ - double bearing = Math.atan2(singleMark2.getLatitude() - singleMark1.getLatitude(), singleMark2.getLongitude() - singleMark1.getLongitude()); + public double getBoatHeading() { + double bearing = Math.atan2(mark2.getLatitude() - mark1.getLatitude(), mark2.getLongitude() - mark1.getLongitude()); if (bearing < 0) { bearing += Math.PI * 2; } @@ -143,17 +144,19 @@ public class Event { /** * Get the mark the event happened on + * * @return the mark */ - public SingleMark getMark(){ - return this.singleMark1; + public Mark getMark() { + return this.mark2; } /** * Get the next mark + * * @return the next mark */ - public SingleMark getNextMark(){ - return this.singleMark2; + public Mark getNextMark() { + return this.mark1; } -} +} \ No newline at end of file diff --git a/src/main/java/seng302/models/GateMark.java b/src/main/java/seng302/models/GateMark.java deleted file mode 100644 index e69de29b..00000000 diff --git a/src/main/java/seng302/models/OldApp.java b/src/main/java/seng302/models/OldApp.java index 094ae681..420b19ec 100644 --- a/src/main/java/seng302/models/OldApp.java +++ b/src/main/java/seng302/models/OldApp.java @@ -57,11 +57,11 @@ public class OldApp { } // Add marks to race in order - race.addMark(new SingleMark("Start", 32.296038,-64.854401 )); - race.addMark(new SingleMark("Mid SingleMark", 32.292881,-64.843231 )); - race.addMark(new SingleMark("Leeward Gate", 32.283808,-64.850012 )); - race.addMark(new SingleMark("Windward Gate", 32.309908,-64.833665 )); - race.addMark(new SingleMark("Finish", 32.318439,-64.837367 )); +// race.addMark(new SingleMark("Start", 32.296038,-64.854401 )); +// race.addMark(new SingleMark("Mid SingleMark", 32.292881,-64.843231 )); +// race.addMark(new SingleMark("Leeward Gate", 32.283808,-64.850012 )); +// race.addMark(new SingleMark("Windward Gate", 32.309908,-64.833665 )); +// race.addMark(new SingleMark("Finish", 32.318439,-64.837367 )); return race; } diff --git a/src/main/java/seng302/models/Race.java b/src/main/java/seng302/models/Race.java index 649319b9..7695a17b 100644 --- a/src/main/java/seng302/models/Race.java +++ b/src/main/java/seng302/models/Race.java @@ -1,7 +1,6 @@ package seng302.models; -import seng302.models.mark.Mark; -import seng302.models.mark.SingleMark; +import seng302.models.mark.*; import java.lang.reflect.Array; import java.util.*; @@ -13,7 +12,7 @@ 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 - private ArrayList marks; // Marks in the race + private List course; // Marks in the race private int numberOfBoats = 0; private long startTime = 0; private double timeScale = 1; @@ -24,7 +23,7 @@ public class Race { public Race() { this.boats = new ArrayList(); this.finishingOrder = new ArrayList(); - this.marks = new ArrayList(); + this.course = new ArrayList(); // create a priority queue with a custom Comparator to order events // this.events = new PriorityQueue(new Comparator() { @@ -143,14 +142,14 @@ public class Race { for (Boat boat : this.boats) { double totalDistance = 0; - int numberOfMarks = this.marks.size(); + int numberOfMarks = this.course.size(); for(int i = 0; i < numberOfMarks; i++){ Double time = (Double) (1000 * totalDistance / boat.getVelocity()); // If there are singleMarks after this event if (i < numberOfMarks-1) { - Event event = new Event(time, boat, marks.get(i), marks.get(i + 1)); + Event event = new Event(time, boat, course.get(i), course.get(i + 1)); try { events.get(boat).add(event); @@ -230,13 +229,21 @@ public class Race { // this.startTime = System.currentTimeMillis(); // iterateEvents(); } +// +// /** +// * Add a singleMark to the race (in order) +// * @param singleMark, the singleMark to add +// */ +// public void addMark(SingleMark singleMark){ +// this.marks.add(singleMark); +// } - /** - * Add a singleMark to the race (in order) - * @param singleMark, the singleMark to add - */ - public void addMark(SingleMark singleMark){ - this.marks.add(singleMark); + public void addCourse(List course){ + this.course = course; + } + + public List getCourse() { + return course; } public HashMap getEvents() { diff --git a/src/main/java/seng302/models/mark/GateMark.java b/src/main/java/seng302/models/mark/GateMark.java index 04ee6263..208d2416 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) { - super(name, MarkType.GATE_MARK); + public GateMark(String name, SingleMark singleMark1, SingleMark singleMark2, double latitude, double longitude) { + super(name, MarkType.GATE_MARK, latitude, longitude); this.singleMark1 = singleMark1; this.singleMark2 = singleMark2; } diff --git a/src/main/java/seng302/models/mark/Mark.java b/src/main/java/seng302/models/mark/Mark.java index 2b2cad73..08d1f1eb 100644 --- a/src/main/java/seng302/models/mark/Mark.java +++ b/src/main/java/seng302/models/mark/Mark.java @@ -8,6 +8,8 @@ public abstract class Mark { private String name; private MarkType markType; + private double latitude; + private double longitude; /** * Create a mark instance by passing its name and type @@ -19,6 +21,13 @@ public abstract class Mark { this.markType = markType; } + public Mark(String name, MarkType markType, double latitude, double longitude) { + this.name = name; + this.markType = markType; + this.latitude = latitude; + this.longitude = longitude; + } + public String getName() { return name; } @@ -34,4 +43,12 @@ public abstract class Mark { public void setMarkType(MarkType markType) { this.markType = markType; } + + public double getLatitude() { + return latitude; + } + + public double getLongitude() { + return longitude; + } } diff --git a/src/main/java/seng302/models/parsers/CourseParser.java b/src/main/java/seng302/models/parsers/CourseParser.java index ade4f3b7..0ad0c471 100644 --- a/src/main/java/seng302/models/parsers/CourseParser.java +++ b/src/main/java/seng302/models/parsers/CourseParser.java @@ -4,6 +4,8 @@ import org.w3c.dom.*; import seng302.models.mark.*; import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.NoSuchElementException; /** @@ -13,6 +15,7 @@ import java.util.NoSuchElementException; public class CourseParser extends FileParser { private Document doc; + private HashMap marks = new HashMap<>(); public CourseParser(String path) { super(path); @@ -48,7 +51,7 @@ public class CourseParser extends FileParser { * * @return an arrayList of gates, or null if no gate has been found. */ - public ArrayList getGateMarks() { + private void generateGateMarks() { ArrayList gateMarks = new ArrayList<>(); try { @@ -62,14 +65,13 @@ 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); - gateMarks.add(gateMark); + GateMark gateMark = new GateMark(name, mark1, mark2, mark1.getLatitude(), mark1.getLongitude()); + marks.put(name, gateMark); } } } catch (Exception e) { e.printStackTrace(); } - return gateMarks; } /** @@ -77,7 +79,7 @@ public class CourseParser extends FileParser { * * @return an arrayList of marks, or null if no gate has been found. */ - public ArrayList getSingleMarks() { + private void generateSingleMarks() { ArrayList singleMarks = new ArrayList<>(); try { @@ -89,14 +91,13 @@ public class CourseParser extends FileParser { if (n.getNodeType() == Node.ELEMENT_NODE) { Element element = (Element) n; if (element.getNodeName() == "mark") { - singleMarks.add(generateSingleMark(n)); + Mark mark = generateSingleMark(n); + marks.put(mark.getName(), mark); } } } - return singleMarks; } catch (Exception e) { e.printStackTrace(); - return null; } } @@ -105,7 +106,7 @@ public class CourseParser extends FileParser { * * @return an arrayList of the names of ordered course marks */ - public ArrayList getOrder() { + private ArrayList getOrder() { ArrayList markOrder = new ArrayList<>(); try { @@ -122,4 +123,18 @@ public class CourseParser extends FileParser { } return markOrder; } + + public ArrayList getCourse() { + generateSingleMarks(); + generateGateMarks(); + ArrayList course = new ArrayList<>(); + try { + for (String mark : getOrder()) { + course.add(marks.get(mark)); + } + } catch (Exception e) { + e.printStackTrace(); + } + return course; + } } diff --git a/src/test/java/seng302/models/mark/MarkTest.java b/src/test/java/seng302/models/mark/MarkTest.java index d9ae1d35..f1943c64 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); + this.gateMark = new GateMark("testMark_GM", singleMark1, singleMark2, singleMark1.getLatitude(), singleMark2.getLongitude()); } @Test diff --git a/src/test/java/seng302/models/parsers/CourseParserTest.java b/src/test/java/seng302/models/parsers/CourseParserTest.java index d3e489ee..96add4a8 100644 --- a/src/test/java/seng302/models/parsers/CourseParserTest.java +++ b/src/test/java/seng302/models/parsers/CourseParserTest.java @@ -1,5 +1,6 @@ package seng302.models.parsers; +import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader; import org.junit.Before; import org.junit.Test; import seng302.models.mark.*; @@ -23,43 +24,38 @@ public class CourseParserTest { @Test public void getGates() throws Exception { - ArrayList gateMarks = cp.getGateMarks(); - assertEquals(4, gateMarks.size()); + ArrayList course = cp.getCourse(); - assertEquals("Start", gateMarks.get(0).getName()); - assertEquals("Leeward Gate", gateMarks.get(1).getName()); - assertEquals("Windward Gate", gateMarks.get(2).getName()); - assertEquals("Finish", gateMarks.get(3).getName()); + assertTrue(MarkType.GATE_MARK == course.get(0).getMarkType()); - assertEquals("Start1", gateMarks.get(0).getSingleMark1().getName()); - assertEquals("Start2", gateMarks.get(0).getSingleMark2().getName()); - assertEquals(32.293834, gateMarks.get(0).getSingleMark2().getLatitude(), 0.00000001); - assertEquals(-64.855195, gateMarks.get(0).getSingleMark2().getLongitude(), 0.00000001); + GateMark gateMark1 = (GateMark) course.get(0); + assertEquals(32.293834, gateMark1.getSingleMark2().getLatitude(), 0.00000001); + assertEquals(-64.855195, gateMark1.getSingleMark2().getLongitude(), 0.00000001); - assertEquals("Finish1", gateMarks.get(3).getSingleMark1().getName()); - assertEquals("Finish2", gateMarks.get(3).getSingleMark2().getName()); - assertEquals(32.318303, gateMarks.get(3).getSingleMark2().getLatitude(), 0.00000001); - assertEquals(-64.834974, gateMarks.get(3).getSingleMark2().getLongitude(), 0.00000001); + GateMark gateMark2 = (GateMark) course.get(5); + + assertEquals("Finish1", gateMark2.getSingleMark1().getName()); + assertEquals("Finish2", gateMark2.getSingleMark2().getName()); + assertEquals(32.318303, gateMark2.getSingleMark2().getLatitude(), 0.00000001); + assertEquals(-64.834974, gateMark2.getSingleMark2().getLongitude(), 0.00000001); } @Test public void getMarks() throws Exception { - ArrayList marks = cp.getSingleMarks(); - assertEquals(1, marks.size()); - assertEquals("Mid Mark", marks.get(0).getName()); + ArrayList course = cp.getCourse(); + assertEquals("Mid Mark", course.get(1).getName()); } @Test - public void getOrder() throws Exception { - ArrayList order = cp.getOrder(); - - assertEquals(6, order.size()); - assertEquals("Start", order.get(0)); - assertEquals("Mid Mark", order.get(1)); - assertEquals("Leeward Gate", order.get(2)); - assertEquals("Windward Gate", order.get(3)); - assertEquals("Leeward Gate", order.get(4)); - assertEquals("Finish", order.get(5)); + public void getOrder() { + ArrayList course = cp.getCourse(); + assertEquals(6, course.size()); + assertEquals("Start", course.get(0).getName()); + assertEquals("Mid Mark", course.get(1).getName()); + assertEquals("Leeward Gate", course.get(2).getName()); + assertEquals("Windward Gate", course.get(3).getName()); + assertEquals("Leeward Gate", course.get(4).getName()); + assertEquals("Finish", course.get(5).getName()); } } \ No newline at end of file