mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
Implemented wake lines
- Changed heading calculation in event class - The boats now go to the marker, rather than the center of a gate Tags: #story[466]
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
generateTimelines();
|
try{
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public abstract class Mark {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MarkType getMarkType() {
|
public MarkType getMarkType() {
|
||||||
|
|||||||
Reference in New Issue
Block a user