From e2b868d815988813d6b78778ccaec4ebc6eaf64e Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Sun, 10 Sep 2017 14:49:16 +1200 Subject: [PATCH] Added boundaries to the map, which are drawn by the race #story[1261] --- .../Controllers/RaceController.java | 10 ++- .../java/visualiser/layout/Boundary3D.java | 89 +++++++++++++++++++ .../java/visualiser/utils/GPSConverter.java | 7 ++ 3 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 racevisionGame/src/main/java/visualiser/layout/Boundary3D.java diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java index affb155f..195b373a 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java @@ -27,10 +27,7 @@ import visualiser.app.App; import visualiser.gameController.ControllerClient; import visualiser.gameController.Keys.ControlKey; import visualiser.gameController.Keys.KeyFactory; -import visualiser.layout.BoatArrow; -import visualiser.layout.MarkRadius; -import visualiser.layout.Subject3D; -import visualiser.layout.View3D; +import visualiser.layout.*; import visualiser.model.*; import visualiser.utils.GPSConverter; @@ -206,6 +203,11 @@ public class RaceController extends Controller { final GPSConverter gpsConverter = new GPSConverter(raceData, 450, 450); view3D.setItems(viewSubjects); + + Boundary3D boundary3D = new Boundary3D(visualiserRace.getVisualiserRaceState().getRaceDataSource().getBoundary(), gpsConverter); + for (Subject3D subject3D: boundary3D.getBoundaryNodes()){ + viewSubjects.add(subject3D); + } // Position and add each mark to view for(Mark mark: race.getVisualiserRaceState().getMarks()) { MeshView mesh = new MeshView(importerMark.getImport()); diff --git a/racevisionGame/src/main/java/visualiser/layout/Boundary3D.java b/racevisionGame/src/main/java/visualiser/layout/Boundary3D.java new file mode 100644 index 00000000..beb59914 --- /dev/null +++ b/racevisionGame/src/main/java/visualiser/layout/Boundary3D.java @@ -0,0 +1,89 @@ +package visualiser.layout; + +import com.sun.corba.se.impl.orbutil.graph.Graph; +import javafx.scene.shape.Box; +import javafx.scene.shape.MeshView; +import javafx.scene.shape.Rectangle; +import javafx.scene.shape.Sphere; +import shared.model.GPSCoordinate; +import visualiser.model.GraphCoordinate; +import visualiser.utils.GPSConverter; + +import java.util.ArrayList; +import java.util.List; + +/** + * Class that creates a 3d boundary based on gps coordinates + */ +public class Boundary3D { + + public static double thickness = 1; + private List boundaryNodes = new ArrayList<>(); + private List boundaryConnectors = new ArrayList<>(); + private GPSConverter gpsConverter; + + public Boundary3D(List points, GPSConverter gpsConverter){ + this.gpsConverter = gpsConverter; + setBoundaryNodes(points); + } + + /** + * Splits up the list so that it generates a edge of the boundary + * @param points boundary gpscoordinate + */ + private void setBoundaryNodes(List points){ + if (points.size() < 2){ + return; + } + System.out.println(points.size()); + for (int i = 0; i < points.size(); i++){ + if (i + 1 != points.size()){ + addBound(points.get(i), points.get(i + 1)); + } else { + addBound(points.get(i), points.get(0)); + } + } + } + + /** + * Add a two point boundary this will create a sphere at coord1 and a line to coord 2 + * this is to reduce double up (2 spheres in one point). + * @param coord1 point to make sphere and start the line. + * @param coord2 point to end the line. + */ + private void addBound(GPSCoordinate coord1, GPSCoordinate coord2){ + GraphCoordinate graphCoord1 = gpsConverter.convertGPS(coord1); + GraphCoordinate graphCoord2 = gpsConverter.convertGPS(coord2); + GraphCoordinate avgCoord = new GraphCoordinate((graphCoord1.getX() + graphCoord2.getX()) / 2, + (graphCoord1.getY() + graphCoord2.getY()) / 2); + + double a = (graphCoord1.getX() - graphCoord2.getX()); + double b = (graphCoord1.getY() - graphCoord2.getY()); + double c = Math.sqrt(a * a + b * b); + + + Subject3D bound1 = new Subject3D(new Sphere(thickness * 2)); + bound1.setX(graphCoord1.getX()); + bound1.setZ(graphCoord1.getY()); + boundaryNodes.add(bound1); + + Subject3D connector = new Subject3D(new Box(c, thickness, thickness)); + connector.setX(avgCoord.getX()); + connector.setZ(avgCoord.getY()); + double angle = 90 + Math.toDegrees(GPSConverter.getAngle(graphCoord2, graphCoord1)); + connector.setHeading(angle); + + boundaryConnectors.add(connector); + } + + /** + * get the 3d objects to draw + * @return 3d boundary to draw + */ + public List getBoundaryNodes(){ + //these two must be concatenated with nodes after connectors else the spheres will not overlap the lines + ArrayList result = new ArrayList<>(boundaryConnectors); + result.addAll(boundaryNodes); + return result; + } +} diff --git a/racevisionGame/src/main/java/visualiser/utils/GPSConverter.java b/racevisionGame/src/main/java/visualiser/utils/GPSConverter.java index 22dd937f..a166b3cb 100644 --- a/racevisionGame/src/main/java/visualiser/utils/GPSConverter.java +++ b/racevisionGame/src/main/java/visualiser/utils/GPSConverter.java @@ -101,4 +101,11 @@ public class GPSConverter { return convertGPS(coordinate.getLatitude(), coordinate.getLongitude()); } + /** + * Get angle between two GraphCoordinates + */ + public static double getAngle(GraphCoordinate coord1, GraphCoordinate coord2){ + return Math.atan2(coord2.getX() - coord1.getX(), coord2.getY() - coord1.getY()); + } + }