|
|
|
@ -1,7 +1,6 @@
|
|
|
|
package visualiser.model;
|
|
|
|
package visualiser.model;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import javafx.collections.ObservableList;
|
|
|
|
|
|
|
|
import javafx.scene.Node;
|
|
|
|
import javafx.scene.Node;
|
|
|
|
import javafx.scene.image.Image;
|
|
|
|
import javafx.scene.image.Image;
|
|
|
|
import javafx.scene.paint.Color;
|
|
|
|
import javafx.scene.paint.Color;
|
|
|
|
@ -9,12 +8,8 @@ import javafx.scene.paint.Paint;
|
|
|
|
import javafx.scene.transform.Rotate;
|
|
|
|
import javafx.scene.transform.Rotate;
|
|
|
|
import network.Messages.Enums.BoatStatusEnum;
|
|
|
|
import network.Messages.Enums.BoatStatusEnum;
|
|
|
|
import shared.dataInput.RaceDataSource;
|
|
|
|
import shared.dataInput.RaceDataSource;
|
|
|
|
import shared.model.GPSCoordinate;
|
|
|
|
import shared.model.*;
|
|
|
|
import shared.model.Leg;
|
|
|
|
|
|
|
|
import shared.model.Mark;
|
|
|
|
|
|
|
|
import shared.model.RaceClock;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.time.Duration;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
@ -513,6 +508,9 @@ public class ResizableRaceCanvas extends ResizableCanvas {
|
|
|
|
//Marks.
|
|
|
|
//Marks.
|
|
|
|
drawMarks();
|
|
|
|
drawMarks();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Guiding Line
|
|
|
|
|
|
|
|
drawRaceLine();
|
|
|
|
|
|
|
|
|
|
|
|
//Wind arrow. This rotates the wind arrow node.
|
|
|
|
//Wind arrow. This rotates the wind arrow node.
|
|
|
|
displayWindArrow(this.visualiserRace.getWindDirection().degrees());
|
|
|
|
displayWindArrow(this.visualiserRace.getWindDirection().degrees());
|
|
|
|
|
|
|
|
|
|
|
|
@ -523,11 +521,67 @@ public class ResizableRaceCanvas extends ResizableCanvas {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void drawRaceLine(){
|
|
|
|
public void drawRaceLine(){
|
|
|
|
List<Leg> legs = this.visualiserRace.getLegs();
|
|
|
|
List<Leg> legs = this.visualiserRace.getLegs();
|
|
|
|
|
|
|
|
for (int i = 0; i < legs.size() -1; i++) {
|
|
|
|
for (Leg leg: legs) {
|
|
|
|
drawLineRounding(legs.get(i));
|
|
|
|
//todo calculate and draw line around this leg
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void drawLineRounding(Leg leg){
|
|
|
|
|
|
|
|
//finds the direction of the leg as a bearing
|
|
|
|
|
|
|
|
GPSCoordinate startDirectionLinePoint = leg.getStartCompoundMark().getAverageGPSCoordinate();
|
|
|
|
|
|
|
|
GPSCoordinate endDirectionLinePoint = leg.getEndCompoundMark().getAverageGPSCoordinate();
|
|
|
|
|
|
|
|
Bearing bearingOfDirectionLine = GPSCoordinate.calculateBearing(startDirectionLinePoint, endDirectionLinePoint);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//use the direction line to find a point parallel to it by the mark
|
|
|
|
|
|
|
|
GPSCoordinate pointToStartCurve = GPSCoordinate.calculateNewPosition(endDirectionLinePoint,
|
|
|
|
|
|
|
|
150, Azimuth.fromDegrees(bearingOfDirectionLine.degrees()+90));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//use the direction line to find a point to curve too
|
|
|
|
|
|
|
|
GPSCoordinate pointToEndCurve = GPSCoordinate.calculateNewPosition(endDirectionLinePoint,
|
|
|
|
|
|
|
|
150, Azimuth.fromDegrees(bearingOfDirectionLine.degrees()));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//use the curve points to find the two control points for the bezier curve
|
|
|
|
|
|
|
|
Bearing bearingOfCurveLine = GPSCoordinate.calculateBearing(pointToStartCurve, pointToEndCurve);
|
|
|
|
|
|
|
|
GPSCoordinate controlPoint1 = GPSCoordinate.calculateNewPosition(pointToStartCurve,
|
|
|
|
|
|
|
|
150, Azimuth.fromDegrees(bearingOfCurveLine.degrees()+ 50));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//change all gps into graph coordinate
|
|
|
|
|
|
|
|
GraphCoordinate startPath = this.map.convertGPS(startDirectionLinePoint);
|
|
|
|
|
|
|
|
GraphCoordinate curvePoint = this.map.convertGPS(pointToStartCurve);
|
|
|
|
|
|
|
|
GraphCoordinate curvePointEnd = this.map.convertGPS(pointToEndCurve);
|
|
|
|
|
|
|
|
GraphCoordinate c1 = this.map.convertGPS(controlPoint1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gc.setStroke(Color.RED);
|
|
|
|
|
|
|
|
gc.setLineWidth(1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gc.beginPath();
|
|
|
|
|
|
|
|
gc.moveTo(startPath.getX(), startPath.getY());
|
|
|
|
|
|
|
|
gc.lineTo(curvePoint.getX(), curvePoint.getY());
|
|
|
|
|
|
|
|
gc.bezierCurveTo(c1.getX(), c1.getY(), c1.getX(), c1.getY(), curvePointEnd.getX(), curvePointEnd.getY());
|
|
|
|
|
|
|
|
gc.stroke();
|
|
|
|
|
|
|
|
gc.closePath();
|
|
|
|
|
|
|
|
gc.save();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
drawArrowHead(controlPoint1, pointToEndCurve);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void drawArrowHead(GPSCoordinate start, GPSCoordinate end){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GraphCoordinate lineStart = this.map.convertGPS(start);
|
|
|
|
|
|
|
|
GraphCoordinate lineEnd = this.map.convertGPS(end);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double arrowAngle = Math.toRadians(45.0);
|
|
|
|
|
|
|
|
double arrowLength = 10.0;
|
|
|
|
|
|
|
|
double dx = lineStart.getX() - lineEnd.getX();
|
|
|
|
|
|
|
|
double dy = lineStart.getY() - lineEnd.getY();
|
|
|
|
|
|
|
|
double angle = Math.atan2(dy, dx);
|
|
|
|
|
|
|
|
double x1 = Math.cos(angle + arrowAngle) * arrowLength + lineEnd.getX();
|
|
|
|
|
|
|
|
double y1 = Math.sin(angle + arrowAngle) * arrowLength + lineEnd.getY();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double x2 = Math.cos(angle - arrowAngle) * arrowLength + lineEnd.getX();
|
|
|
|
|
|
|
|
double y2 = Math.sin(angle - arrowAngle) * arrowLength + lineEnd.getY();
|
|
|
|
|
|
|
|
gc.strokeLine(lineEnd.getX(), lineEnd.getY(), x1, y1);
|
|
|
|
|
|
|
|
gc.strokeLine(lineEnd.getX(), lineEnd.getY(), x2, y2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
|