mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
Arrows now rendered in correct orientation but rounding arc sometimes inverted.
#implement #story[1118]
This commit is contained in:
@@ -104,10 +104,11 @@ public class MarkOrder {
|
|||||||
List<Corner> corners = data.getMarkSequence();
|
List<Corner> corners = data.getMarkSequence();
|
||||||
Map<Integer, CompoundMark> marks = data.getCompoundMarks();
|
Map<Integer, CompoundMark> marks = data.getCompoundMarks();
|
||||||
List<CompoundMark> course = new ArrayList<>();
|
List<CompoundMark> course = new ArrayList<>();
|
||||||
|
|
||||||
for (Corner corner : corners){
|
for (Corner corner : corners){
|
||||||
CompoundMark compoundMark = marks.get(corner.getCompoundMarkID());
|
CompoundMark compoundMark = marks.get(corner.getCompoundMarkID());
|
||||||
compoundMark.setRoundingSide(RoundingSide.getRoundingSide(corner.getRounding()));
|
compoundMark.setRoundingSide(
|
||||||
|
RoundingSide.getRoundingSide(corner.getRounding())
|
||||||
|
);
|
||||||
course.add(compoundMark);
|
course.add(compoundMark);
|
||||||
allMarks.addAll(compoundMark.getMarks());
|
allMarks.addAll(compoundMark.getMarks());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import java.util.Comparator;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
|
||||||
import javafx.animation.AnimationTimer;
|
import javafx.animation.AnimationTimer;
|
||||||
import javafx.animation.KeyFrame;
|
import javafx.animation.KeyFrame;
|
||||||
import javafx.animation.KeyValue;
|
import javafx.animation.KeyValue;
|
||||||
@@ -25,6 +24,7 @@ import javafx.scene.shape.Circle;
|
|||||||
import javafx.scene.shape.Polygon;
|
import javafx.scene.shape.Polygon;
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
import seng302.gameServer.messages.RoundingSide;
|
||||||
import seng302.model.ClientYacht;
|
import seng302.model.ClientYacht;
|
||||||
import seng302.model.Colors;
|
import seng302.model.Colors;
|
||||||
import seng302.model.GeoPoint;
|
import seng302.model.GeoPoint;
|
||||||
@@ -208,6 +208,7 @@ public class GameView extends Pane {
|
|||||||
mapImage.fitHeightProperty().bind(((AnchorPane) this.getParent()).heightProperty());
|
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
|
* 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.
|
* case the course is added relative ot the border.
|
||||||
@@ -225,10 +226,30 @@ public class GameView extends Pane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int j = 0;
|
// System.out.println("<seq>");
|
||||||
for (CompoundMark cm : course) {
|
// for (Corner corner : sequence) {
|
||||||
System.out.println(cm.getId() + " " + j++);
|
// for (CompoundMark cm : newCourse) {
|
||||||
System.out.println(cm.toString());
|
// if (cm.getId() == corner.getCompoundMarkID()) {
|
||||||
|
// System.out.println(cm);
|
||||||
|
// System.out.println(corner.getSeqID());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// System.out.println("</seq>");
|
||||||
|
//
|
||||||
|
// 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<Gate> gates = new ArrayList<>();
|
final List<Gate> gates = new ArrayList<>();
|
||||||
@@ -245,16 +266,6 @@ public class GameView extends Pane {
|
|||||||
for (Mark mark : cMark.getMarks()) {
|
for (Mark mark : cMark.getMarks()) {
|
||||||
makeAndBindMarker(mark, colour);
|
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
|
//Create gate line
|
||||||
if (cMark.isGate()) {
|
if (cMark.isGate()) {
|
||||||
for (int i = 1; i < cMark.getMarks().size(); i++) {
|
for (int i = 1; i < cMark.getMarks().size(); i++) {
|
||||||
@@ -269,6 +280,83 @@ public class GameView extends Pane {
|
|||||||
}
|
}
|
||||||
colour = Color.BLACK;
|
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.
|
//Scale race to markers if there is no border.
|
||||||
if (borderPoints == null) {
|
if (borderPoints == null) {
|
||||||
rescaleRace(new ArrayList<>(markerObjects.keySet()));
|
rescaleRace(new ArrayList<>(markerObjects.keySet()));
|
||||||
@@ -294,7 +382,7 @@ public class GameView extends Pane {
|
|||||||
*/
|
*/
|
||||||
private void makeAndBindMarker(Mark observableMark, Paint colour) {
|
private void makeAndBindMarker(Mark observableMark, Paint colour) {
|
||||||
Marker marker = new Marker(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);
|
markerObjects.put(observableMark, marker);
|
||||||
observableMark.addPositionListener((mark, lat, lon) -> {
|
observableMark.addPositionListener((mark, lat, lon) -> {
|
||||||
Point2D p2d = findScaledXY(lat, lon);
|
Point2D p2d = findScaledXY(lat, lon);
|
||||||
@@ -649,13 +737,15 @@ public class GameView extends Pane {
|
|||||||
this.playerYacht.toggleSail();
|
this.playerYacht.toggleSail();
|
||||||
boatObjects.get(playerYacht).setAsPlayer();
|
boatObjects.get(playerYacht).setAsPlayer();
|
||||||
CompoundMark currentMark = course.get(playerYacht.getLegNumber());
|
CompoundMark currentMark = course.get(playerYacht.getLegNumber());
|
||||||
|
System.out.println("currentMark = " + currentMark);
|
||||||
for (Mark mark : currentMark.getMarks()) {
|
for (Mark mark : currentMark.getMarks()) {
|
||||||
markerObjects.get(mark).showNextExitArrow();
|
markerObjects.get(mark).showNextExitArrow();
|
||||||
}
|
}
|
||||||
CompoundMark destination = course.get(playerYacht.getLegNumber() + 1);
|
// CompoundMark destination = course.get(playerYacht.getLegNumber() + 1);
|
||||||
for (Mark mark : destination.getMarks()) {
|
// System.out.println("destination = " + destination);
|
||||||
markerObjects.get(mark).showNextEnterArrow();
|
// for (Mark mark : destination.getMarks()) {
|
||||||
}
|
// markerObjects.get(mark).showNextEnterArrow();
|
||||||
|
// }
|
||||||
annotations.get(playerYacht).addAnnotation(
|
annotations.get(playerYacht).addAnnotation(
|
||||||
"velocity",
|
"velocity",
|
||||||
playerYacht.getVelocityProperty(),
|
playerYacht.getVelocityProperty(),
|
||||||
@@ -676,6 +766,7 @@ public class GameView extends Pane {
|
|||||||
markerObjects.get(mark).showNextExitArrow();
|
markerObjects.get(mark).showNextExitArrow();
|
||||||
}
|
}
|
||||||
CompoundMark nextMark = course.get(legNumber);
|
CompoundMark nextMark = course.get(legNumber);
|
||||||
|
System.out.println("nextMark = " + nextMark);
|
||||||
for (Mark mark : nextMark.getMarks()) {
|
for (Mark mark : nextMark.getMarks()) {
|
||||||
markerObjects.get(mark).showNextEnterArrow();
|
markerObjects.get(mark).showNextEnterArrow();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,6 +128,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
gameView.setWindDir(newDirection.doubleValue());
|
gameView.setWindDir(newDirection.doubleValue());
|
||||||
updateWindDirection(newDirection.doubleValue());
|
updateWindDirection(newDirection.doubleValue());
|
||||||
});
|
});
|
||||||
|
updateWindDirection(raceState.windDirectionProperty().doubleValue());
|
||||||
|
gameView.setWindDir(raceState.windDirectionProperty().doubleValue());
|
||||||
for (ClientYacht yacht : participants.values()) {
|
for (ClientYacht yacht : participants.values()) {
|
||||||
yacht.placingProperty().addListener((obs, oldPlacing, newPlacing) -> {
|
yacht.placingProperty().addListener((obs, oldPlacing, newPlacing) -> {
|
||||||
updateOrder();
|
updateOrder();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import javafx.scene.paint.Paint;
|
|||||||
import javafx.scene.shape.*;
|
import javafx.scene.shape.*;
|
||||||
import javafx.scene.transform.Rotate;
|
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.
|
* 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,
|
public static Group constructEntryArrow (RoundingSide roundingSide, double angleOfEntry,
|
||||||
double angleOfExit, Paint colour) {
|
double angleOfExit, Paint colour) {
|
||||||
|
angleOfEntry = 180 - angleOfEntry;
|
||||||
Group arrow = new Group();
|
Group arrow = new Group();
|
||||||
Group exitSection = constructExitArrow(roundingSide, angleOfExit, colour);
|
Group exitSection = constructExitArrow(roundingSide, angleOfExit, colour);
|
||||||
double minAngle = Math.min(angleOfEntry, angleOfExit);
|
angleOfExit = 180 - angleOfExit;
|
||||||
double arcLen = Math.max(angleOfEntry, angleOfExit) - minAngle;
|
// 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(
|
Arc roundSection = new Arc(
|
||||||
0, 0, MARK_ARROW_SEPARATION, MARK_ARROW_SEPARATION,
|
0, 0, MARK_ARROW_SEPARATION, MARK_ARROW_SEPARATION,
|
||||||
angleOfEntry, 180 - (angleOfEntry - angleOfExit)
|
(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.setStrokeWidth(STROKE_WIDTH);
|
||||||
roundSection.setType(ArcType.OPEN);
|
roundSection.setType(ArcType.OPEN);
|
||||||
roundSection.setStroke(colour);
|
roundSection.setStroke(colour);
|
||||||
roundSection.setFill(new Color(0,0,0,0));
|
roundSection.setFill(new Color(0,0,0,0));
|
||||||
Polygon entrySection = constructLineSegment(
|
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);
|
arrow.getChildren().addAll(exitSection, roundSection, entrySection);
|
||||||
return arrow;
|
return arrow;
|
||||||
}
|
}
|
||||||
@@ -62,6 +75,7 @@ public class MarkArrowFactory {
|
|||||||
* @return The group containing all the JavaFX objects.
|
* @return The group containing all the JavaFX objects.
|
||||||
*/
|
*/
|
||||||
public static Group constructExitArrow (RoundingSide roundingSide, double angle, Paint colour) {
|
public static Group constructExitArrow (RoundingSide roundingSide, double angle, Paint colour) {
|
||||||
|
angle = 180 - angle;
|
||||||
Group arrow = new Group();
|
Group arrow = new Group();
|
||||||
Polygon arrowBody = constructLineSegment(roundingSide, angle, colour);
|
Polygon arrowBody = constructLineSegment(roundingSide, angle, colour);
|
||||||
Polyline arrowHead = constructArrowHead(angle, colour);
|
Polyline arrowHead = constructArrowHead(angle, colour);
|
||||||
@@ -74,7 +88,10 @@ public class MarkArrowFactory {
|
|||||||
private static Polygon constructLineSegment (RoundingSide roundingSide, double angle, Paint colour) {
|
private static Polygon constructLineSegment (RoundingSide roundingSide, double angle, Paint colour) {
|
||||||
Polygon lineSegment;
|
Polygon lineSegment;
|
||||||
angle = Math.toRadians(angle);
|
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 xStart = multiplier * MARK_ARROW_SEPARATION * Math.sin(angle + Math.PI / 2);
|
||||||
double yStart = multiplier * MARK_ARROW_SEPARATION * Math.cos(angle + Math.PI / 2);
|
double yStart = multiplier * MARK_ARROW_SEPARATION * Math.cos(angle + Math.PI / 2);
|
||||||
double xEnd = xStart + (ARROW_LENGTH * Math.sin(angle));
|
double xEnd = xStart + (ARROW_LENGTH * Math.sin(angle));
|
||||||
|
|||||||
@@ -38,12 +38,7 @@
|
|||||||
<Corner SeqID="3" CompoundMarkID="3" Rounding="SP" ZoneSize="3" />
|
<Corner SeqID="3" CompoundMarkID="3" Rounding="SP" ZoneSize="3" />
|
||||||
<Corner SeqID="4" CompoundMarkID="4" Rounding="PS" ZoneSize="3" />
|
<Corner SeqID="4" CompoundMarkID="4" Rounding="PS" ZoneSize="3" />
|
||||||
<Corner SeqID="5" CompoundMarkID="3" Rounding="SP" ZoneSize="3" />
|
<Corner SeqID="5" CompoundMarkID="3" Rounding="SP" ZoneSize="3" />
|
||||||
<Corner SeqID="6" CompoundMarkID="4" Rounding="PS" ZoneSize="3" />
|
<Corner SeqID="6" CompoundMarkID="5" Rounding="PS" ZoneSize="3" />
|
||||||
<Corner SeqID="7" CompoundMarkID="3" Rounding="SP" ZoneSize="3" />
|
|
||||||
<Corner SeqID="8" CompoundMarkID="4" Rounding="PS" ZoneSize="3" />
|
|
||||||
<Corner SeqID="9" CompoundMarkID="3" Rounding="SP" ZoneSize="3" />
|
|
||||||
<Corner SeqID="10" CompoundMarkID="4" Rounding="PS" ZoneSize="3" />
|
|
||||||
<Corner SeqID="11" CompoundMarkID="5" Rounding="PS" ZoneSize="3" />
|
|
||||||
</CompoundMarkSequence>
|
</CompoundMarkSequence>
|
||||||
<CourseLimit>
|
<CourseLimit>
|
||||||
<Limit SeqID="1" Lat="57.6739450" Lon="11.8417100" />
|
<Limit SeqID="1" Lat="57.6739450" Lon="11.8417100" />
|
||||||
|
|||||||
Reference in New Issue
Block a user