mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Implemented a factory class that creates mark arrows as needed. Needs to integrated with the real world data and tested to work. Works with all test data so far.
#implement #story[1118]
This commit is contained in:
@@ -6,6 +6,8 @@ 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.application.Platform;
|
||||
import javafx.collections.ObservableList;
|
||||
@@ -27,11 +29,7 @@ import seng302.model.mark.CompoundMark;
|
||||
import seng302.model.mark.Corner;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.utilities.GeoUtility;
|
||||
import seng302.visualiser.fxObjects.AnnotationBox;
|
||||
import seng302.visualiser.fxObjects.BoatObject;
|
||||
import seng302.visualiser.fxObjects.CourseBoundary;
|
||||
import seng302.visualiser.fxObjects.Gate;
|
||||
import seng302.visualiser.fxObjects.Marker;
|
||||
import seng302.visualiser.fxObjects.*;
|
||||
import seng302.visualiser.map.Boundary;
|
||||
import seng302.visualiser.map.CanvasMap;
|
||||
|
||||
@@ -222,8 +220,8 @@ public class GameView extends Pane {
|
||||
//Move the Markers to initial position.
|
||||
markerObjects.forEach(((mark, marker) -> {
|
||||
Point2D p2d = findScaledXY(mark.getLat(), mark.getLng());
|
||||
marker.setCenterX(p2d.getX());
|
||||
marker.setCenterY(p2d.getY());
|
||||
marker.setLayoutX(p2d.getX());
|
||||
marker.setLayoutY(p2d.getY());
|
||||
}));
|
||||
Platform.runLater(() -> {
|
||||
markers.getChildren().clear();
|
||||
@@ -240,11 +238,12 @@ public class GameView extends Pane {
|
||||
*/
|
||||
private void makeAndBindMarker(Mark observableMark, Paint colour) {
|
||||
Marker marker = new Marker(colour);
|
||||
marker.constructArrows(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);
|
||||
markerObjects.get(mark).setCenterX(p2d.getX());
|
||||
markerObjects.get(mark).setCenterY(p2d.getY());
|
||||
markerObjects.get(mark).setLayoutX(p2d.getX());
|
||||
markerObjects.get(mark).setLayoutY(p2d.getY());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -259,16 +258,16 @@ public class GameView extends Pane {
|
||||
private Gate makeAndBindGate(Marker m1, Marker m2, Paint colour) {
|
||||
Gate gate = new Gate(colour);
|
||||
gate.startXProperty().bind(
|
||||
m1.centerXProperty()
|
||||
m1.layoutXProperty()
|
||||
);
|
||||
gate.startYProperty().bind(
|
||||
m1.centerYProperty()
|
||||
m1.layoutYProperty()
|
||||
);
|
||||
gate.endXProperty().bind(
|
||||
m2.centerXProperty()
|
||||
m2.layoutXProperty()
|
||||
);
|
||||
gate.endYProperty().bind(
|
||||
m2.centerYProperty()
|
||||
m2.layoutYProperty()
|
||||
);
|
||||
return gate;
|
||||
}
|
||||
|
||||
@@ -1,56 +1,105 @@
|
||||
package seng302.visualiser.fxObjects;
|
||||
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.Line;
|
||||
import javafx.scene.shape.Polyline;
|
||||
import javafx.scene.shape.*;
|
||||
import javafx.scene.transform.Rotate;
|
||||
|
||||
/**
|
||||
* Created by cir27 on 9/08/17.
|
||||
* Factory class for making rounding arrows for mark objects out of JavaFX objects.
|
||||
*/
|
||||
public class MarkArrowFactory {
|
||||
|
||||
public enum RoundingType {
|
||||
/**
|
||||
* The side of the boat that will be closest to the mark.
|
||||
*/
|
||||
public enum RoundingSide {
|
||||
PORT,
|
||||
STARBOARD,
|
||||
}
|
||||
|
||||
public static Group constructEntryArrow (RoundingType roundingSide, double angleOfEntry,
|
||||
double angleOfExit, Paint colour) {
|
||||
public static final double MARK_ARROW_SEPARATION = 15;
|
||||
public static final double ARROW_LENGTH = 75;
|
||||
public static final double ARROW_HEAD_DEPTH = 10;
|
||||
public static final double ARROW_HEAD_WIDTH = 6;
|
||||
public static final double STROKE_WIDTH = 3;
|
||||
|
||||
/**
|
||||
* Creates an entry arrow group showing an arrow into and out of the rounding area. It is centered on (0, 0).
|
||||
* @param roundingSide The side of the boat that will be closest to the mark.
|
||||
* @param angleOfEntry The angle between this mark and the last one as a heading from north in degrees.
|
||||
* @param angleOfExit The angle between this mark and the next one as a heading from north in degrees.
|
||||
* @param colour The desired colour of the arrows.
|
||||
* @return The group containing all JavaFX objects.
|
||||
*/
|
||||
public static Group constructEntryArrow (RoundingSide roundingSide, double angleOfEntry,
|
||||
double angleOfExit, Paint colour) {
|
||||
Group arrow = new Group();
|
||||
Group exitSection = constructExitArrow(roundingSide, angleOfExit, colour);
|
||||
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)
|
||||
);
|
||||
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
|
||||
);
|
||||
arrow.getChildren().addAll(exitSection, roundSection, entrySection);
|
||||
return arrow;
|
||||
}
|
||||
|
||||
public static Group constructExitArrow (RoundingType roundingSide, double angleOfEntry, Paint colour) {
|
||||
/**
|
||||
* Creates an exit arrow group pointing towards the next mark.
|
||||
* @param roundingSide The side of the boat that will be closest to the mark.
|
||||
* @param angle The angle to the next mark as a heading from north in degrees.
|
||||
* @param colour The colour of the arrow.
|
||||
* @return The group containing all the JavaFX objects.
|
||||
*/
|
||||
public static Group constructExitArrow (RoundingSide roundingSide, double angle, Paint colour) {
|
||||
Group arrow = new Group();
|
||||
Line arrowBody;
|
||||
Polyline arrowHead = constructArrowHead();
|
||||
if (roundingSide == RoundingType.PORT) {
|
||||
arrowBody = new Line(
|
||||
-10, -10,
|
||||
-10, -30
|
||||
);
|
||||
arrowHead.setLayoutX(-10);
|
||||
arrowHead.setLayoutY(-10);
|
||||
} else {
|
||||
arrowBody = new Line(
|
||||
10, -10,
|
||||
10, -30
|
||||
);
|
||||
arrowHead.setLayoutX(10);
|
||||
arrowHead.setLayoutY(-10);
|
||||
}
|
||||
arrowBody.setFill(colour);
|
||||
arrowHead.setFill(colour);
|
||||
Polygon arrowBody = constructLineSegment(roundingSide, angle, colour);
|
||||
Polyline arrowHead = constructArrowHead(angle, colour);
|
||||
arrowHead.setLayoutX(arrowBody.getPoints().get(2));
|
||||
arrowHead.setLayoutY(arrowBody.getPoints().get(3));
|
||||
arrow.getChildren().addAll(arrowBody, arrowHead);
|
||||
return arrow;
|
||||
}
|
||||
|
||||
private static Polyline constructArrowHead () {
|
||||
return new Polyline(
|
||||
-5, -5,
|
||||
0, 0,
|
||||
5, -5
|
||||
private static Polygon constructLineSegment (RoundingSide roundingSide, double angle, Paint colour) {
|
||||
Polygon lineSegment;
|
||||
angle = Math.toRadians(angle);
|
||||
int multiplier = roundingSide == RoundingSide.PORT ? -1 : 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));
|
||||
double yEnd = yStart + (ARROW_LENGTH * Math.cos(angle));
|
||||
lineSegment = new Polygon(
|
||||
xStart, yStart,
|
||||
xEnd, yEnd
|
||||
);
|
||||
lineSegment.setStroke(colour);
|
||||
lineSegment.setFill(Color.BLUE);
|
||||
lineSegment.setStrokeWidth(STROKE_WIDTH);
|
||||
lineSegment.setStrokeLineCap(StrokeLineCap.ROUND);
|
||||
return lineSegment;
|
||||
}
|
||||
|
||||
private static Polyline constructArrowHead (double rotation, Paint colour) {
|
||||
Polyline arrow = new Polyline(
|
||||
-ARROW_HEAD_WIDTH, -ARROW_HEAD_DEPTH,
|
||||
0, 0,
|
||||
ARROW_HEAD_WIDTH, -ARROW_HEAD_DEPTH
|
||||
);
|
||||
arrow.getTransforms().add(new Rotate(-rotation));
|
||||
arrow.setStrokeLineCap(StrokeLineCap.ROUND);
|
||||
arrow.setStroke(colour);
|
||||
arrow.setStrokeWidth(STROKE_WIDTH);
|
||||
return arrow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package seng302.visualiser.fxObjects;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.Circle;
|
||||
|
||||
@@ -11,18 +12,30 @@ import javafx.scene.shape.Circle;
|
||||
public class Marker extends Group {
|
||||
|
||||
Circle mark = new Circle();
|
||||
Paint colour = Color.BLACK;
|
||||
Group enterArrow;
|
||||
Group exitArrow;
|
||||
|
||||
public Marker() {
|
||||
mark.setRadius(5);
|
||||
mark.setCenterX(0);
|
||||
mark.setCenterY(0);
|
||||
Platform.runLater(() -> this.getChildren().add(mark));
|
||||
}
|
||||
|
||||
public Marker(Paint colour) {
|
||||
this();
|
||||
this.colour = colour;
|
||||
mark.setFill(colour);
|
||||
}
|
||||
|
||||
public void constructArrows(MarkArrowFactory.RoundingSide roundingSide, double entryAngle, double exitAngle) {
|
||||
enterArrow = MarkArrowFactory.constructEntryArrow(roundingSide, entryAngle, exitAngle, colour);
|
||||
exitArrow = MarkArrowFactory.constructExitArrow(roundingSide, exitAngle, colour);
|
||||
Platform.runLater(() -> this.getChildren().add(enterArrow));
|
||||
// Platform.runLater(() -> this.getChildren().add(exitArrow));
|
||||
}
|
||||
|
||||
public void showEnterArrow () {
|
||||
Platform.runLater(() -> this.getChildren().setAll(enterArrow));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user