Merge branch 'create-wake-line'

This commit is contained in:
Michael Rausch
2017-03-24 20:39:21 +13:00
8 changed files with 80 additions and 26 deletions
+6 -6
View File
@@ -5,27 +5,27 @@
"teams": [ "teams": [
{ {
"team-name": "Oracle Team USA", "team-name": "Oracle Team USA",
"velocity": 30.9 "velocity": 60.0
}, },
{ {
"team-name": "Artemis Racing", "team-name": "Artemis Racing",
"velocity": 59.3 "velocity": 10.0
}, },
{ {
"team-name": "Emirates Team New Zealand", "team-name": "Emirates Team New Zealand",
"velocity": 51.5 "velocity": 90.0
}, },
{ {
"team-name": "Groupama Team France", "team-name": "Groupama Team France",
"velocity": 29.9 "velocity": 15.0
}, },
{ {
"team-name": "Land Rover BAR", "team-name": "Land Rover BAR",
"velocity": 99.6 "velocity": 70.0
}, },
{ {
"team-name": "SoftBank Team Japan", "team-name": "SoftBank Team Japan",
"velocity": 45.6 "velocity": 45.0
} }
] ]
} }
@@ -48,6 +48,7 @@ public class CanvasController {
@FXML @FXML
private AnchorPane contentAnchorPane; private AnchorPane contentAnchorPane;
@FXML @FXML
private Text windArrowText, windDirectionText; private Text windArrowText, windDirectionText;
@@ -132,7 +133,6 @@ public class CanvasController {
*/ */
public void initialize() { public void initialize() {
gc = canvas.getGraphicsContext2D(); gc = canvas.getGraphicsContext2D();
//gc.scale(2, 2);
RaceController raceController = new RaceController(); RaceController raceController = new RaceController();
raceController.initializeRace(); raceController.initializeRace();
race = raceController.getRace(); race = raceController.getRace();
@@ -145,9 +145,6 @@ public class CanvasController {
@Override @Override
public void handle(long now) { public void handle(long now) {
if (now - lastUpdate >= 33000000){ if (now - lastUpdate >= 33000000){
gc.clearRect(0, 0, 19200, 10800);
drawCourse();
drawBoats();
gc.clearRect(0, 0, canvas.getWidth(),canvas.getHeight()); gc.clearRect(0, 0, canvas.getWidth(),canvas.getHeight());
gc.setFill(Color.SKYBLUE); gc.setFill(Color.SKYBLUE);
gc.fillRect(0,0,canvas.getWidth(),canvas.getHeight()); gc.fillRect(0,0,canvas.getWidth(),canvas.getHeight());
@@ -163,14 +160,17 @@ public class CanvasController {
else if (race.getRaceTime() < 1 || raceStatus == Animation.Status.RUNNING){ else if (race.getRaceTime() < 1 || raceStatus == Animation.Status.RUNNING){
pauseTimelines(); pauseTimelines();
} }
lastUpdate = now; lastUpdate = now;
} }
} }
}; };
try{
generateTimelines(); generateTimelines();
}
catch (Exception e){
e.printStackTrace();
}
timer.start(); timer.start();
loadTimerView(); loadTimerView();
@@ -229,7 +229,10 @@ public class CanvasController {
} else { } else {
keyFrames.add( keyFrames.add(
new KeyFrame(Duration.seconds(event.getTime() / 60 / 60 / 5), new KeyFrame(Duration.seconds(event.getTime() / 60 / 60 / 5),
onFinished -> teamPositionsController.handleEvent(event), onFinished ->{
teamPositionsController.handleEvent(event);
boat.setHeading(event.getBoatHeading());
},
new KeyValue(x, event.getThisMark().getLatitude()), new KeyValue(x, event.getThisMark().getLatitude()),
new KeyValue(y, event.getThisMark().getLongitude()) new KeyValue(y, event.getThisMark().getLongitude())
) )
@@ -248,10 +251,34 @@ public class CanvasController {
private void drawBoats() { private void drawBoats() {
for (Boat boat : timelineInfos.keySet()) { for (Boat boat : timelineInfos.keySet()) {
TimelineInfo timelineInfo = timelineInfos.get(boat); TimelineInfo timelineInfo = timelineInfos.get(boat);
drawBoat(timelineInfo.getX().doubleValue(), timelineInfo.getY().doubleValue(), boat.getColor(), boat.getTeamName(), boat.getSpeedInKnots());
boat.setLocation(timelineInfo.getY().doubleValue(), timelineInfo.getX().doubleValue());
drawBoat(boat.getLongitude(), boat.getLatitude(), boat.getColor(), boat.getTeamName(), 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);
double newX = x + speed * Math.cos(angle);//(nextX * Math.cos(angle) - nextY * Math.sin(angle)) * length;
double newY = y + speed * Math.sin(angle);//(nextX * Math.sin(angle) + nextY * Math.cos(angle)) * length;
gc.setStroke(color);
gc.setLineWidth(1.0);
gc.strokeLine(x+5, y+5, newX, newY);
}
/** /**
* Draws a boat with given (x, y) position in the given color * Draws a boat with given (x, y) position in the given color
* *
@@ -259,7 +286,7 @@ public class CanvasController {
* @param lon * @param lon
* @param color * @param color
*/ */
private void drawBoat(double lat, double lon, Color color, String name, double speed) { private void drawBoat(double lat, double lon, Color color, String name, double speed, double heading) {
// Latitude // Latitude
double x = (lon - ORIGIN_LON) * SCALE; double x = (lon - ORIGIN_LON) * SCALE;
double y = (ORIGIN_LAT - lat) * SCALE; double y = (ORIGIN_LAT - lat) * SCALE;
@@ -274,6 +301,7 @@ public class CanvasController {
gc.fillText(name + ", " + speed + " knots",x+15,y+15); gc.fillText(name + ", " + speed + " knots",x+15,y+15);
gc.fillOval(x, y, diameter, diameter); gc.fillOval(x, y, diameter, diameter);
drawWake(gc, x, y, speed, color, heading);
} }
/** /**
+9
View File
@@ -14,6 +14,7 @@ public class Boat {
private double distanceToNextMark; private double distanceToNextMark;
private Color color; private Color color;
private int markLastPast; private int markLastPast;
private double heading;
public Boat(String teamName) { public Boat(String teamName) {
this.teamName = teamName; this.teamName = teamName;
@@ -110,4 +111,12 @@ public class Boat {
public int getMarkLastPast() { public int getMarkLastPast() {
return markLastPast; return markLastPast;
} }
public void setHeading(double heading){
this.heading = heading;
}
public double getHeading(){
return this.heading;
}
} }
+21 -5
View File
@@ -17,6 +17,11 @@ public class Event {
private Mark mark2; // Next mark private Mark mark2; // Next mark
private int markPosInRace; // the position of the current mark in the race course private int markPosInRace; // the position of the current mark in the race course
private final double ORIGIN_LAT = 32.320504;
private final double ORIGIN_LON = -64.857063;
private final double SCALE = 16000;
/** /**
* Event class containing the time of specific event, related team/boat, and * Event class containing the time of specific event, related team/boat, and
@@ -95,7 +100,6 @@ public class Event {
* @return the distance between the two marks * @return the distance between the two marks
*/ */
public double getDistanceBetweenMarks() { 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 earth_radius = 6378.137;
double dLat = this.mark2.getLatitude() * Math.PI / 180 - this.mark1.getLatitude() * 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 dLon = this.mark2.getLongitude() * Math.PI / 180 - this.mark1.getLongitude() * Math.PI / 180;
@@ -112,11 +116,23 @@ public class Event {
* @return the boats heading * @return the boats heading
*/ */
public double getBoatHeading() { public double getBoatHeading() {
double bearing = Math.atan2(mark2.getLatitude() - mark1.getLatitude(), mark2.getLongitude() - mark1.getLongitude()); if (mark2 == null){
if (bearing < 0) { return 0.0;
bearing += Math.PI * 2;
} }
return bearing * 180 / Math.PI;
double x1 = (mark1.getLongitude() - ORIGIN_LON) * SCALE;
double y1 = (ORIGIN_LAT - mark1.getLatitude()) * SCALE;
double x2 = (mark2.getLongitude() - ORIGIN_LON) * SCALE;
double y2 = (ORIGIN_LAT - mark2.getLatitude()) * SCALE;
double headingRadians = Math.atan2(y2-y1, x2-x1);
if (headingRadians < 0){
headingRadians += 2 * Math.PI;
}
// Convert back to degrees, and flip 180 degrees
return (Math.toDegrees(headingRadians) + 180) % 360;
} }
public Mark getThisMark() { public Mark getThisMark() {
@@ -39,10 +39,12 @@ public class GateMark extends Mark {
} }
public double getLatitude(){ public double getLatitude(){
return (this.getSingleMark1().getLatitude() + this.getSingleMark2().getLatitude()) / 2; //return (this.getSingleMark1().getLatitude() + this.getSingleMark2().getLatitude()) / 2;
return (this.getSingleMark1().getLatitude());
} }
public double getLongitude(){ public double getLongitude(){
return (this.getSingleMark1().getLongitude() + this.getSingleMark2().getLongitude()) / 2; //return (this.getSingleMark1().getLongitude() + this.getSingleMark2().getLongitude()) / 2;
return (this.getSingleMark1().getLongitude());
} }
} }
+1 -1
View File
@@ -25,7 +25,7 @@ public class EventTest {
Boat boat = new Boat("testBoat"); Boat boat = new Boat("testBoat");
Event event = new Event(1231242.2, boat, new SingleMark("mark1", 142.5, 122.1), new SingleMark("mark2", 121.9,99.2), 0); Event event = new Event(1231242.2, boat, new SingleMark("mark1", 142.5, 122.1), new SingleMark("mark2", 121.9,99.2), 0);
assertEquals(event.getBoatHeading(), 221.9733862944651, 1e-15); assertEquals(event.getBoatHeading(), 318.02661370553494, 1e-15);
} }
@Test @Test
@@ -1,6 +1,5 @@
package seng302.models.parsers; package seng302.models.parsers;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import seng302.models.mark.*; import seng302.models.mark.*;