diff --git a/src/main/java/seng302/Controllers/RaceController.java b/src/main/java/seng302/Controllers/RaceController.java index 91a692e1..f28d5abc 100644 --- a/src/main/java/seng302/Controllers/RaceController.java +++ b/src/main/java/seng302/Controllers/RaceController.java @@ -12,9 +12,12 @@ import javafx.scene.control.TableView; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import javafx.util.Callback; +import org.geotools.referencing.GeodeticCalculator; import seng302.Constants; +import seng302.GPSCoordinate; import seng302.Model.*; +import java.awt.geom.Point2D; import java.net.URL; import java.util.ArrayList; import java.util.ResourceBundle; @@ -138,7 +141,7 @@ public class RaceController extends Controller { */ private ArrayList generateBermudaCourseLegs() { ArrayList legs = new ArrayList<>(); - Leg leg1 = new Leg("Start to Mark 1", Constants.startLineMarker1, Constants.mark1, 0); + Leg leg1 = new Leg("Start to Mark 1", Constants.startLineMarker1, Constants.startLineMarker2, Constants.mark1, null, 0); Leg leg2 = new Leg("Mark 1 to Leeward Gate", Constants.mark1, Constants.leewardGate1, 1); Leg leg3 = new Leg("Leeward Gate to Windward Gate", Constants.leewardGate1, Constants.windwardGate1, 2); Leg leg4 = new Leg("Windward Gate to Leeward Gate", Constants.windwardGate1, Constants.leewardGate1, 3); diff --git a/src/main/java/seng302/Model/Leg.java b/src/main/java/seng302/Model/Leg.java index c3466f8b..e396e8d7 100644 --- a/src/main/java/seng302/Model/Leg.java +++ b/src/main/java/seng302/Model/Leg.java @@ -14,7 +14,11 @@ public class Leg { private int legNumber; private GPSCoordinate startGPSCoordinate; + private GPSCoordinate startMarker1; + private GPSCoordinate startMarker2; private GPSCoordinate endGPSCoordinate; + private GPSCoordinate endMarker1; + private GPSCoordinate endMarker2; /** * Leg Initialiser @@ -29,6 +33,23 @@ public class Leg { this.distance = calculateDistance(); } + /** + * Leg Initialiser + * + * @param name Name of the Leg + */ + public Leg(String name, GPSCoordinate start1, GPSCoordinate start2, GPSCoordinate end1, GPSCoordinate end2, int number) { + this.name = name; + this.startMarker1 = start1; + this.startMarker2 = start2; + this.endMarker1 = end1; + this.endMarker2 = end2; + this.legNumber = number; + calculateStart(); + calculateEnd(); + this.distance = calculateDistance(); + } + /** * Construction Method * @@ -57,6 +78,24 @@ public class Leg { return distance; } + + public GPSCoordinate getStartMarker1() { + return startMarker1; + } + + public GPSCoordinate getStartMarker2() { + return startMarker2; + } + + public GPSCoordinate getEndMarker1() { + return endMarker1; + } + + public GPSCoordinate getEndMarker2() { + return endMarker2; + } + + /** * Returns the coordinates in GPSCoordinate class of the boats starting coordinate. * @@ -101,4 +140,13 @@ public class Leg { return calc.getOrthodromicDistance() / Constants.NMToMetersConversion; } + + private void calculateStart() { + //TO DO: Make this function set the start node as halfway between the two markers + } + + private void calculateEnd() { + //TO DO: Make this function set the end node as halfway between the two markers + } + } diff --git a/src/main/java/seng302/Model/Race.java b/src/main/java/seng302/Model/Race.java index 8bc8c209..9016cea4 100644 --- a/src/main/java/seng302/Model/Race.java +++ b/src/main/java/seng302/Model/Race.java @@ -4,8 +4,11 @@ package seng302.Model; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; +import org.geotools.referencing.GeodeticCalculator; import seng302.Controllers.RaceController; +import seng302.GPSCoordinate; +import java.awt.geom.Point2D; import java.util.ArrayList; /** @@ -33,21 +36,32 @@ public abstract class Race implements Runnable { * @param legs Number of marks in order that the boats pass in order to complete the race. */ public Race(BoatInRace[] boats, ArrayList legs, RaceController controller, int scaleFactor) { - if (boats.length > 0) { - for (BoatInRace boat : boats) { - if (boat != null) { - boat.setScaledVelocity(boat.getVelocity() * scaleFactor); - } - } - } this.startingBoats = FXCollections.observableArrayList(boats); this.legs = legs; this.legs.add(new Leg("Finish", this.legs.size())); this.controller = controller; this.scaleFactor = scaleFactor; + + initialiseBoats(); } + + private void initialiseBoats() { + Leg startLeg = legs.get(0); + + + + if (startingBoats.size() > 0) { + for (BoatInRace boat : startingBoats) { + if (boat != null) { + boat.setScaledVelocity(boat.getVelocity() * scaleFactor); + + boat.setCurrentLeg(startLeg); + } + } + } + } /** * Constructor for Race class * @@ -89,6 +103,8 @@ public abstract class Race implements Runnable { */ private void preRace() { //show the boats participating. + ArrayList startPositons = getSpreadStartingPositions(); + for (int i = 0; i < startingBoats.size(); i++) { if (startingBoats.get(i) != null) { startingBoats.get(i).setCurrentLeg(legs.get(0)); @@ -252,4 +268,35 @@ public abstract class Race implements Runnable { */ protected abstract void updatePosition(BoatInRace boat, int millisecondsElapsed); + /** + * Creates a list of starting positions for the different boats, so they do not appear cramped at the start line + * @return + */ + public ArrayList getSpreadStartingPositions() { + + int nBoats = startingBoats.size(); + GPSCoordinate marker1 = legs.get(0).getStartMarker1(); + GPSCoordinate marker2 = legs.get(0).getStartMarker2(); + GeodeticCalculator initialCalc = new GeodeticCalculator(); + initialCalc.setStartingGeographicPoint(marker1.getLongitude(), marker1.getLatitude()); + initialCalc.setDestinationGeographicPoint(marker2.getLongitude(), marker2.getLatitude()); + + double azimuth = initialCalc.getAzimuth(); + double distanceBetweenMarkers = initialCalc.getOrthodromicDistance(); + double distanceBetweenBoats = distanceBetweenMarkers / (nBoats + 1); + + GeodeticCalculator positionCalc = new GeodeticCalculator(); + positionCalc.setStartingGeographicPoint(marker1.getLongitude(), marker1.getLatitude()); + ArrayList positions = new ArrayList<>(); + + for (int i = 0; i < nBoats; i++) { + positionCalc.setDirection(azimuth, distanceBetweenBoats); + Point2D position = positionCalc.getDestinationGeographicPoint(); + positions.add(new GPSCoordinate(position.getY(), position.getX())); + + positionCalc = new GeodeticCalculator(); + positionCalc.setStartingGeographicPoint(position); + } + return positions; + } }