diff --git a/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java b/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java index 386468c8..10ff60ec 100644 --- a/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java +++ b/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java @@ -1,7 +1,6 @@ package visualiser.model; -import javafx.collections.ObservableList; import javafx.scene.Node; import javafx.scene.image.Image; import javafx.scene.paint.Color; @@ -9,12 +8,8 @@ import javafx.scene.paint.Paint; import javafx.scene.transform.Rotate; import network.Messages.Enums.BoatStatusEnum; import shared.dataInput.RaceDataSource; -import shared.model.GPSCoordinate; -import shared.model.Leg; -import shared.model.Mark; -import shared.model.RaceClock; +import shared.model.*; -import java.time.Duration; import java.util.List; /** @@ -513,6 +508,9 @@ public class ResizableRaceCanvas extends ResizableCanvas { //Marks. drawMarks(); + //Guiding Line + drawRaceLine(); + //Wind arrow. This rotates the wind arrow node. displayWindArrow(this.visualiserRace.getWindDirection().degrees()); @@ -523,11 +521,67 @@ public class ResizableRaceCanvas extends ResizableCanvas { */ public void drawRaceLine(){ List legs = this.visualiserRace.getLegs(); - - for (Leg leg: legs) { - //todo calculate and draw line around this leg + for (int i = 0; i < legs.size() -1; i++) { + drawLineRounding(legs.get(i)); } + } + + 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); } /**