From 21e6819f16d74f1906de41876f4b88e0c4eceda5 Mon Sep 17 00:00:00 2001 From: Calum Date: Wed, 16 Aug 2017 20:17:25 +1200 Subject: [PATCH] Arrows now rendered in correct orientation but rounding arc sometimes inverted. #implement #story[1118] --- .../java/seng302/model/mark/MarkOrder.java | 5 +- .../java/seng302/visualiser/GameView.java | 131 +++++++++++++++--- .../controllers/RaceViewController.java | 2 + .../fxObjects/MarkArrowFactory.java | 29 +++- .../server_config/xml_templates/race.ftlh | 7 +- 5 files changed, 140 insertions(+), 34 deletions(-) diff --git a/src/main/java/seng302/model/mark/MarkOrder.java b/src/main/java/seng302/model/mark/MarkOrder.java index c093e967..ab3a1848 100644 --- a/src/main/java/seng302/model/mark/MarkOrder.java +++ b/src/main/java/seng302/model/mark/MarkOrder.java @@ -104,10 +104,11 @@ public class MarkOrder { List corners = data.getMarkSequence(); Map marks = data.getCompoundMarks(); List course = new ArrayList<>(); - for (Corner corner : corners){ CompoundMark compoundMark = marks.get(corner.getCompoundMarkID()); - compoundMark.setRoundingSide(RoundingSide.getRoundingSide(corner.getRounding())); + compoundMark.setRoundingSide( + RoundingSide.getRoundingSide(corner.getRounding()) + ); course.add(compoundMark); allMarks.addAll(compoundMark.getMarks()); } diff --git a/src/main/java/seng302/visualiser/GameView.java b/src/main/java/seng302/visualiser/GameView.java index c9e32563..8861d1e5 100644 --- a/src/main/java/seng302/visualiser/GameView.java +++ b/src/main/java/seng302/visualiser/GameView.java @@ -6,7 +6,6 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.ThreadLocalRandom; import javafx.animation.AnimationTimer; import javafx.animation.KeyFrame; import javafx.animation.KeyValue; @@ -25,6 +24,7 @@ import javafx.scene.shape.Circle; import javafx.scene.shape.Polygon; import javafx.scene.text.Text; import javafx.util.Duration; +import seng302.gameServer.messages.RoundingSide; import seng302.model.ClientYacht; import seng302.model.Colors; import seng302.model.GeoPoint; @@ -208,6 +208,7 @@ public class GameView extends Pane { mapImage.fitHeightProperty().bind(((AnchorPane) this.getParent()).heightProperty()); } + // TODO: 16/08/17 Break up this function /** * Adds a course to the GameView. The view is scaled accordingly unless a border is set in which * case the course is added relative ot the border. @@ -225,10 +226,30 @@ public class GameView extends Pane { } } } - int j = 0; - for (CompoundMark cm : course) { - System.out.println(cm.getId() + " " + j++); - System.out.println(cm.toString()); +// System.out.println(""); +// for (Corner corner : sequence) { +// for (CompoundMark cm : newCourse) { +// if (cm.getId() == corner.getCompoundMarkID()) { +// System.out.println(cm); +// System.out.println(corner.getSeqID()); +// } +// } +// } +// System.out.println(""); +// +// for (CompoundMark cm : course) { +// System.out.println(cm); +// } + + // TODO: 16/08/17 Updating mark roundings here. It should not happen here. Nor should it be done this way. + for (Corner corner : sequence){ +// System.out.println("corner.getSeqID() = " + corner.getSeqID()); + CompoundMark compoundMark = course.get(corner.getSeqID() - 1); +// System.out.println(" = " + RoundingSide.getRoundingSide(corner.getRounding())); +// System.out.println("compoundMark = " + compoundMark); + compoundMark.setRoundingSide( + RoundingSide.getRoundingSide(corner.getRounding()) + ); } final List gates = new ArrayList<>(); @@ -245,16 +266,6 @@ public class GameView extends Pane { for (Mark mark : cMark.getMarks()) { makeAndBindMarker(mark, colour); } - - //UNCOMMENT THIS TO HIGHLIGHT SUBMARKS 1 and 2 RED AND GREEN RESPECTIVELY FOR DEBUG - //(instead of above for loop) -// for (Mark mark : cMark.getMarks()) { -// if (mark.getSeqID() == 1) { -// makeAndBindMarker(mark, Color.RED); -// } else { -// makeAndBindMarker(mark, Color.GREEN); -// } -// } //Create gate line if (cMark.isGate()) { for (int i = 1; i < cMark.getMarks().size(); i++) { @@ -269,6 +280,83 @@ public class GameView extends Pane { } colour = Color.BLACK; } + + //Creating mark arrows. + for (int i=1; i < sequence.size()-1; i++) { //General case. + double averageLat = 0; + double averageLng = 0; + int numMarks = 0; + for (Mark mark : course.get(i-1).getMarks()) { + numMarks += 1; + averageLat += mark.getLat(); + averageLng += mark.getLng(); + } + GeoPoint lastMarkAv = new GeoPoint(averageLat / numMarks, averageLng / numMarks); + numMarks = 0; + averageLat = 0; + averageLng = 0; + for (Mark mark : course.get(i+1).getMarks()) { + numMarks += 1; + averageLat += mark.getLat(); + averageLng += mark.getLng(); + } + GeoPoint nextMarkAv = new GeoPoint(averageLat / numMarks, averageLng / numMarks); + // TODO: 16/08/17 This comparison is cancer and deserves to die. + System.out.println("course.get(i).getMarks() = " + course.get(i).getMarks()); + for (Mark mark : course.get(i).getMarks()) { + markerObjects.get(mark).addArrows( + mark.getRoundingSide() == RoundingSide.STARBOARD ? MarkArrowFactory.RoundingSide.STARBOARD : MarkArrowFactory.RoundingSide.PORT, + GeoUtility.getBearing(lastMarkAv, mark), + GeoUtility.getBearing(mark, nextMarkAv) +// GeoUtility.getBearing(mark, nextMarkAv), +// GeoUtility.getBearing(lastMarkAv, mark) + ); +// System.out.println(mark.getName() + " " + GeoUtility.getBearing(lastMarkAv, mark) + " " + GeoUtility.getBearing(mark, nextMarkAv)); + } + System.out.println("end"); + } + + // TODO: 16/08/17 Make this cleaner + //First mark case + double averageLat = 0; + double averageLng = 0; + int numMarks = 0; + for (Mark mark : course.get(1).getMarks()) { + numMarks += 1; + averageLat += mark.getLat(); + averageLng += mark.getLng(); + } + GeoPoint firstMarkAv = new GeoPoint(averageLat / numMarks, averageLng / numMarks); + for (Mark mark : course.get(0).getMarks()) { + System.out.println("thing " + GeoUtility.getBearing(mark, firstMarkAv)); + System.out.println(mark); + System.out.println(mark.getRoundingSide()); + markerObjects.get(mark).addArrows( + mark.getRoundingSide() == RoundingSide.STARBOARD ? MarkArrowFactory.RoundingSide.STARBOARD : MarkArrowFactory.RoundingSide.PORT, + 0d, //90 + GeoUtility.getBearing(mark, firstMarkAv) +// GeoUtility.getBearing(mark, mark), +// GeoUtility.getBearing(mark, firstMarkAv) + ); + } + //Last Mark case + numMarks = 0; + averageLat = 0; + averageLng = 0; + for (Mark mark : course.get(course.size()-2).getMarks()) { + numMarks += 1; + averageLat += mark.getLat(); + averageLng += mark.getLng(); + } + GeoPoint secondToLastMarkAv = new GeoPoint(averageLat / numMarks, averageLng / numMarks); + for (Mark mark : course.get(course.size()-1).getMarks()) { + markerObjects.get(mark).addArrows( + mark.getRoundingSide() == RoundingSide.STARBOARD ? MarkArrowFactory.RoundingSide.STARBOARD : MarkArrowFactory.RoundingSide.PORT, + GeoUtility.getBearing(secondToLastMarkAv, mark), + GeoUtility.getBearing(mark, mark) + ); + } + //Scale race to markers if there is no border. if (borderPoints == null) { rescaleRace(new ArrayList<>(markerObjects.keySet())); @@ -294,7 +382,7 @@ public class GameView extends Pane { */ private void makeAndBindMarker(Mark observableMark, Paint colour) { Marker marker = new Marker(colour); - marker.addArrows(MarkArrowFactory.RoundingSide.PORT, ThreadLocalRandom.current().nextDouble(91, 180), ThreadLocalRandom.current().nextDouble(1, 90)); +// marker.addArrows(MarkArrowFactory.RoundingSide.PORT, ThreadLocalRandom.current().nextDouble(91, 180), ThreadLocalRandom.current().nextDouble(1, 90)); markerObjects.put(observableMark, marker); observableMark.addPositionListener((mark, lat, lon) -> { Point2D p2d = findScaledXY(lat, lon); @@ -649,13 +737,15 @@ public class GameView extends Pane { this.playerYacht.toggleSail(); boatObjects.get(playerYacht).setAsPlayer(); CompoundMark currentMark = course.get(playerYacht.getLegNumber()); + System.out.println("currentMark = " + currentMark); for (Mark mark : currentMark.getMarks()) { markerObjects.get(mark).showNextExitArrow(); } - CompoundMark destination = course.get(playerYacht.getLegNumber() + 1); - for (Mark mark : destination.getMarks()) { - markerObjects.get(mark).showNextEnterArrow(); - } +// CompoundMark destination = course.get(playerYacht.getLegNumber() + 1); +// System.out.println("destination = " + destination); +// for (Mark mark : destination.getMarks()) { +// markerObjects.get(mark).showNextEnterArrow(); +// } annotations.get(playerYacht).addAnnotation( "velocity", playerYacht.getVelocityProperty(), @@ -676,6 +766,7 @@ public class GameView extends Pane { markerObjects.get(mark).showNextExitArrow(); } CompoundMark nextMark = course.get(legNumber); + System.out.println("nextMark = " + nextMark); for (Mark mark : nextMark.getMarks()) { markerObjects.get(mark).showNextEnterArrow(); } diff --git a/src/main/java/seng302/visualiser/controllers/RaceViewController.java b/src/main/java/seng302/visualiser/controllers/RaceViewController.java index e7180fd6..0208a433 100644 --- a/src/main/java/seng302/visualiser/controllers/RaceViewController.java +++ b/src/main/java/seng302/visualiser/controllers/RaceViewController.java @@ -128,6 +128,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel gameView.setWindDir(newDirection.doubleValue()); updateWindDirection(newDirection.doubleValue()); }); + updateWindDirection(raceState.windDirectionProperty().doubleValue()); + gameView.setWindDir(raceState.windDirectionProperty().doubleValue()); for (ClientYacht yacht : participants.values()) { yacht.placingProperty().addListener((obs, oldPlacing, newPlacing) -> { updateOrder(); diff --git a/src/main/java/seng302/visualiser/fxObjects/MarkArrowFactory.java b/src/main/java/seng302/visualiser/fxObjects/MarkArrowFactory.java index e362cca6..37ed3cfd 100644 --- a/src/main/java/seng302/visualiser/fxObjects/MarkArrowFactory.java +++ b/src/main/java/seng302/visualiser/fxObjects/MarkArrowFactory.java @@ -6,6 +6,7 @@ import javafx.scene.paint.Paint; import javafx.scene.shape.*; import javafx.scene.transform.Rotate; +// TODO: 16/08/17 this class used to be well written... FeelsBadMan. Maybe lose the ternary operators. /** * Factory class for making rounding arrows for mark objects out of JavaFX objects. */ @@ -35,21 +36,33 @@ public class MarkArrowFactory { */ public static Group constructEntryArrow (RoundingSide roundingSide, double angleOfEntry, double angleOfExit, Paint colour) { + angleOfEntry = 180 - angleOfEntry; Group arrow = new Group(); Group exitSection = constructExitArrow(roundingSide, angleOfExit, colour); - double minAngle = Math.min(angleOfEntry, angleOfExit); - double arcLen = Math.max(angleOfEntry, angleOfExit) - minAngle; + angleOfExit = 180 - angleOfExit; +// double minAngle = Math.min(angleOfEntry, angleOfExit); +// double arcLen = Math.max(angleOfEntry, angleOfExit) - minAngle; +// Arc roundSection = new Arc( +// 0, 0, MARK_ARROW_SEPARATION, MARK_ARROW_SEPARATION, +// angleOfEntry, 180 - (angleOfEntry - angleOfExit) +// ); + System.out.println(angleOfEntry); + System.out.println(angleOfExit); + System.out.println(angleOfExit - angleOfEntry); Arc roundSection = new Arc( - 0, 0, MARK_ARROW_SEPARATION, MARK_ARROW_SEPARATION, - angleOfEntry, 180 - (angleOfEntry - angleOfExit) + 0, 0, MARK_ARROW_SEPARATION, MARK_ARROW_SEPARATION, + (roundingSide == RoundingSide.PORT ? -180 : 0) + angleOfEntry, +// roundingSide == RoundingSide.PORT ? Math.abs(angleOfExit - angleOfEntry) : angleOfExit - angleOfEntry + roundingSide == RoundingSide.PORT ? angleOfExit- angleOfEntry : angleOfEntry - angleOfExit ); roundSection.setStrokeWidth(STROKE_WIDTH); roundSection.setType(ArcType.OPEN); roundSection.setStroke(colour); roundSection.setFill(new Color(0,0,0,0)); Polygon entrySection = constructLineSegment( - roundingSide == RoundingSide.PORT ? RoundingSide.STARBOARD : RoundingSide.PORT, angleOfEntry, colour + roundingSide == RoundingSide.PORT ? RoundingSide.STARBOARD : RoundingSide.PORT, 180 + angleOfEntry, colour ); +// Polygon entrySection = new Polygon(); arrow.getChildren().addAll(exitSection, roundSection, entrySection); return arrow; } @@ -62,6 +75,7 @@ public class MarkArrowFactory { * @return The group containing all the JavaFX objects. */ public static Group constructExitArrow (RoundingSide roundingSide, double angle, Paint colour) { + angle = 180 - angle; Group arrow = new Group(); Polygon arrowBody = constructLineSegment(roundingSide, angle, colour); Polyline arrowHead = constructArrowHead(angle, colour); @@ -74,7 +88,10 @@ public class MarkArrowFactory { private static Polygon constructLineSegment (RoundingSide roundingSide, double angle, Paint colour) { Polygon lineSegment; angle = Math.toRadians(angle); - int multiplier = roundingSide == RoundingSide.PORT ? -1 : 1; + int multiplier = roundingSide == RoundingSide.STARBOARD ? 1 : -1; +// System.out.println("rounding side " + roundingSide); +// System.out.println("multiplier = " + multiplier); +// int multiplier = 1; double xStart = multiplier * MARK_ARROW_SEPARATION * Math.sin(angle + Math.PI / 2); double yStart = multiplier * MARK_ARROW_SEPARATION * Math.cos(angle + Math.PI / 2); double xEnd = xStart + (ARROW_LENGTH * Math.sin(angle)); diff --git a/src/main/resources/server_config/xml_templates/race.ftlh b/src/main/resources/server_config/xml_templates/race.ftlh index e38bf0b7..c1aa7f03 100644 --- a/src/main/resources/server_config/xml_templates/race.ftlh +++ b/src/main/resources/server_config/xml_templates/race.ftlh @@ -38,12 +38,7 @@ - - - - - - +