Mark drawing moved to MarkGroup class. RaceObject and it's sub classes now describe

all functionality required for a on screen object. Improved wakes. Branch currently
untested.

#story[812, 820] #refactor #implement.
This commit is contained in:
cir27
2017-04-27 02:44:25 +12:00
parent eaff4c5aac
commit 245bd184b4
7 changed files with 392 additions and 259 deletions
@@ -6,6 +6,7 @@ import javafx.fxml.FXML;
import javafx.geometry.Point2D; import javafx.geometry.Point2D;
import javafx.geometry.Point3D; import javafx.geometry.Point3D;
import javafx.scene.Group; import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.canvas.Canvas; import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext; import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
@@ -15,10 +16,8 @@ import javafx.util.Pair;
import seng302.models.Boat; import seng302.models.Boat;
import seng302.models.BoatGroup; import seng302.models.BoatGroup;
import seng302.models.Colors; import seng302.models.Colors;
import seng302.models.mark.GateMark; import seng302.models.RaceObject;
import seng302.models.mark.Mark; import seng302.models.mark.*;
import seng302.models.mark.MarkType;
import seng302.models.mark.SingleMark;
import seng302.models.parsers.StreamParser; import seng302.models.parsers.StreamParser;
import seng302.models.parsers.StreamReceiver; import seng302.models.parsers.StreamReceiver;
@@ -59,6 +58,7 @@ public class CanvasController {
private double referencePointX; private double referencePointX;
private double referencePointY; private double referencePointY;
private double metersToPixels; private double metersToPixels;
private List<RaceObject> raceObjects = new ArrayList<>();
public AnimationTimer timer; public AnimationTimer timer;
@@ -154,39 +154,51 @@ public class CanvasController {
Mark nextMark; Mark nextMark;
//if (countdown == 0) { //if (countdown == 0) {
for (BoatGroup boatGroup : boatGroups) { for (RaceObject raceObject : raceObjects) {
//if (currentRaceMarker[boatIndex] < marks.size()) { //if (currentRaceMarker[boatIndex] < marks.size()) {
//if (currentRaceMarker[boatIndex] == 6) { //if (currentRaceMarker[boatIndex] == 6) {
// int debugLine = 4; // int debugLine = 4;
//} //}
double xb4 = boatGroup.getLayoutX(); //double xb4 = boatGroup.getLayoutX();
double yb4 = boatGroup.getLayoutY(); //double yb4 = boatGroup.getLayoutY();
nextMark = marks.get(currentRaceMarker[boatIndex]); //nextMark = marks.get(currentRaceMarker[boatIndex]);
//descending = nextMark.getY() > boatGroup.getLayoutY(); //descending = nextMark.getY() > boatGroup.getLayoutY();
//leftToRight = nextMark.getX() < boatGroup.getLayoutX(); //leftToRight = nextMark.getX() < boatGroup.getLayoutX();
boatGroup.updatePosition(1000 / 60); raceObject.updatePosition(1000 / 60);
Point3D p = StreamParser.boatPositions.get((long)boatGroup.getBoat().getId()); for (int id : raceObject.getRaceIds()) {
if (StreamParser.boatPositions.containsKey(id)) {
Point3D p = StreamParser.boatPositions.get((long) id);
Point2D p2d = latLonToXY(p.getX(), p.getY());
//System.out.println("p2d = " + p2d);
//System.out.println("p.toString() = " + p.toString());
double heading = 360.0 / 0xffff * p.getZ();
//System.out.println("heading = " + heading);
raceObject.setDestination(p2d.getX(), p2d.getY(), heading, id);
}
StreamParser.boatPositions.remove((long) id);
}
//Point3D p = StreamParser.boatPositions.get((long) raceObject.getRaceIds()[0]);
//System.out.println("boatGroup = " + boatGroup.getBoat().getId()); //System.out.println("boatGroup = " + boatGroup.getBoat().getId());
//System.out.println("StreamParser.boatPositions.toString() = " + StreamParser.boatPositions.toString()); //System.out.println("StreamParser.boatPositions.toString() = " + StreamParser.boatPositions.toString());
if (p != null) { // if (p != null) {
Point2D p2d = latLonToXY(p.getX(), p.getY()); // Point2D p2d = latLonToXY(p.getX(), p.getY());
//System.out.println("p2d = " + p2d); // //System.out.println("p2d = " + p2d);
if (!boatGroup.isSamePos(p2d)) { // if (!boatGroup.isSamePos(p2d)) {
//System.out.println("p.toString() = " + p.toString()); // //System.out.println("p.toString() = " + p.toString());
double heading = 360.0 / 0xffff * p.getZ(); // double heading = 360.0 / 0xffff * p.getZ();
//System.out.println("heading = " + heading); // //System.out.println("heading = " + heading);
//
//
//
boatGroup.setDestination(p2d.getX(), p2d.getY(), heading); // boatGroup.setDestination(p2d.getX(), p2d.getY(), heading, boatGroup.getRaceIds()[0]);
//boatGroup.setDestination(p2d.getX(), p2d.getY()); //boatGroup.setDestination(p2d.getX(), p2d.getY());
} // }
} //}
// if (descending && nextMark.getY() < boatGroup.getLayoutY()) { // if (descending && nextMark.getY() < boatGroup.getLayoutY()) {
// currentRaceMarker[boatIndex]++; // currentRaceMarker[boatIndex]++;
@@ -208,14 +220,14 @@ public class CanvasController {
// boatGroup.setDestination( // boatGroup.setDestination(
// marks.get(currentRaceMarker[boatIndex]).getX(), marks.get(currentRaceMarker[boatIndex]).getY() // marks.get(currentRaceMarker[boatIndex]).getX(), marks.get(currentRaceMarker[boatIndex]).getY()
// ); // );
// }
double xnew = boatGroup.getLayoutX();
double ynew = boatGroup.getLayoutY(); // double xnew = boatGroup.getLayoutX();
double dx = xnew - xb4; // double ynew = boatGroup.getLayoutY();
double dy = ynew -yb4; // double dx = xnew - xb4;
raceFinished = false; // double dy = ynew -yb4;
boatIndex++; // raceFinished = false;
// boatIndex++;
} }
//} //}
//if (raceFinished) { //if (raceFinished) {
@@ -280,11 +292,10 @@ public class CanvasController {
private void drawBoats() { private void drawBoats() {
// Map<Boat, TimelineInfo> timelineInfos = raceViewController.getTimelineInfos(); // Map<Boat, TimelineInfo> timelineInfos = raceViewController.getTimelineInfos();
List<Boat> boats = raceViewController.getStartingBoats(); List<Boat> boats = raceViewController.getStartingBoats();
List<Mark> marks = raceViewController.getRace().getCourse(); Double startingX = group.getChildren().get(0).getLayoutX();
Double startingX = (double) marks.get(0).getX(); Double startingY = group.getChildren().get(0).getLayoutY();
Double startingY = (double) marks.get(0).getY(); Double firstMarkX = group.getChildren().get(1).getLayoutX();
Double firstMarkX = (double) marks.get(1).getX(); Double firstMarkY = group.getChildren().get(1).getLayoutY();
Double firstMarkY = (double) marks.get(1).getY();
for (Boat boat : boats) { for (Boat boat : boats) {
BoatGroup boatGroup = new BoatGroup(boat, Colors.getColor()); BoatGroup boatGroup = new BoatGroup(boat, Colors.getColor());
@@ -324,67 +335,67 @@ public class CanvasController {
*/ */
private void drawCourse() { private void drawCourse() {
fitToCanvas(); fitToCanvas();
for (Mark mark : raceViewController.getRace().getCourse()) { // for (Mark mark : raceViewController.getRace().getCourse()) {
if (mark.getMarkType() == MarkType.SINGLE_MARK) { // if (mark.getMarkType() == MarkType.SINGLE_MARK) {
drawSingleMark((SingleMark) mark, Color.BLACK); // drawSingleMark((SingleMark) mark, Color.BLACK);
} else { // } else {
drawGateMark((GateMark) mark); // drawGateMark((GateMark) mark);
} // }
} // }
System.out.println("MIN/MAX POINTS"); // System.out.println("MIN/MAX POINTS");
System.out.println(minLatPoint.getName() + " " + minLatPoint.getX() + " " + minLatPoint.getY()); // System.out.println(minLatPoint.getName() + " " + minLatPoint.getX() + " " + minLatPoint.getY());
System.out.println(maxLatPoint.getName() + " " + maxLatPoint.getX() + " " + maxLatPoint.getY()); // System.out.println(maxLatPoint.getName() + " " + maxLatPoint.getX() + " " + maxLatPoint.getY());
System.out.println(minLonPoint.getName() + " " + minLonPoint.getX() + " " + minLonPoint.getY()); // System.out.println(minLonPoint.getName() + " " + minLonPoint.getX() + " " + minLonPoint.getY());
System.out.println(maxLonPoint.getName() + " " + maxLonPoint.getX() + " " + maxLonPoint.getY()); // System.out.println(maxLonPoint.getName() + " " + maxLonPoint.getX() + " " + maxLonPoint.getY());
System.out.println(referencePointX); // System.out.println(referencePointX);
System.out.println(referencePointY); // System.out.println(referencePointY);
} }
/** // /**
* Draw a given mark on canvas // * Draw a given mark on canvas
* // *
* @param singleMark // * @param singleMark
*/ // */
private void drawSingleMark(SingleMark singleMark, Color color) { // private void drawSingleMark(SingleMark singleMark, Color color) {
gc.setFill(color); // gc.setFill(color);
System.out.println("DRAWING " + singleMark.getName() + " at " + singleMark.getX() + ", " + singleMark.getY()); // System.out.println("DRAWING " + singleMark.getName() + " at " + singleMark.getX() + ", " + singleMark.getY());
gc.fillOval(singleMark.getX(), singleMark.getY(),MARK_SIZE,MARK_SIZE); // gc.fillOval(singleMark.getX(), singleMark.getY(),MARK_SIZE,MARK_SIZE);
} // }
//
/** // /**
* Draw a gate mark which contains two single marks // * Draw a gate mark which contains two single marks
* // *
* @param gateMark // * @param gateMark
*/ // */
private void drawGateMark(GateMark gateMark) { // private void drawGateMark(GateMark gateMark) {
Color color = Color.BLUE; // Color color = Color.BLUE;
//
if (gateMark.getName().equals("Start")){ // if (gateMark.getName().equals("Start")){
color = Color.GREEN; // color = Color.GREEN;
} // }
//
if (gateMark.getName().equals("Finish")){ // if (gateMark.getName().equals("Finish")){
color = Color.RED; // color = Color.RED;
} // }
//
drawSingleMark(gateMark.getSingleMark1(), color); // drawSingleMark(gateMark.getSingleMark1(), color);
drawSingleMark(gateMark.getSingleMark2(), color); // drawSingleMark(gateMark.getSingleMark2(), color);
//
GraphicsContext gc = canvas.getGraphicsContext2D(); // GraphicsContext gc = canvas.getGraphicsContext2D();
gc.save(); // gc.save();
gc.setStroke(color); // gc.setStroke(color);
if (gateMark.getMarkType() == MarkType.OPEN_GATE) // if (gateMark.getMarkType() == MarkType.OPEN_GATE)
gc.setLineDashes(3, 5); // gc.setLineDashes(3, 5);
//
gc.setLineWidth(2); // gc.setLineWidth(2);
gc.strokeLine( // gc.strokeLine(
gateMark.getSingleMark1().getX() + MARK_SIZE / 2, // gateMark.getSingleMark1().getX() + MARK_SIZE / 2,
gateMark.getSingleMark1().getY() + MARK_SIZE / 2, // gateMark.getSingleMark1().getY() + MARK_SIZE / 2,
gateMark.getSingleMark2().getX() + MARK_SIZE / 2, // gateMark.getSingleMark2().getX() + MARK_SIZE / 2,
gateMark.getSingleMark2().getY() + MARK_SIZE / 2 // gateMark.getSingleMark2().getY() + MARK_SIZE / 2
); // );
gc.restore(); // gc.restore();
} // }
/** /**
* Calculates x and y location for every marker that fits it to the canvas the race will be drawn on. * Calculates x and y location for every marker that fits it to the canvas the race will be drawn on.
@@ -478,8 +489,8 @@ public class CanvasController {
} }
referencePointX = Math.round(referencePointX); referencePointX = Math.round(referencePointX);
referencePointY = Math.round(referencePointY); referencePointY = Math.round(referencePointY);
referencePoint.setX((int) referencePointX); // referencePoint.setX((int) referencePointX);
referencePoint.setY((int) referencePointY); // referencePoint.setY((int) referencePointY);
} }
/** /**
@@ -517,27 +528,31 @@ public class CanvasController {
* are scaled according to the distanceScaleFactor variable. * are scaled according to the distanceScaleFactor variable.
*/ */
private void givePointsXY() { private void givePointsXY() {
Point2D canvasLocation; //Point2D canvasLocation;
List<Mark> allPoints = new ArrayList<>(raceViewController.getRace().getCourse()); // List<Mark> allPoints = new ArrayList<>(raceViewController.getRace().getCourse());
Set<Mark> unqiuePoints = new HashSet<>(raceViewController.getRace().getCourse());
System.out.println("unqiuePoints = " + unqiuePoints);
RaceObject markGroup;
for (Mark mark : allPoints) { for (Mark mark : unqiuePoints) {
if (mark.getMarkType() != MarkType.SINGLE_MARK) { if (mark.getMarkType() != MarkType.SINGLE_MARK) {
GateMark gateMark = (GateMark) mark; GateMark gateMark = (GateMark) mark;
// canvasLocation = findScaledXY(gateMark.getSingleMark1());
// gateMark.getSingleMark1().setX((int) canvasLocation.getX());
// gateMark.getSingleMark1().setY((int) canvasLocation.getY());
//
// canvasLocation = findScaledXY(gateMark.getSingleMark2());
// gateMark.getSingleMark2().setX((int) canvasLocation.getX());
// gateMark.getSingleMark2().setY((int) canvasLocation.getY());
canvasLocation = findScaledXY(gateMark.getSingleMark1()); markGroup = new MarkGroup(mark, findScaledXY(gateMark.getSingleMark1()), findScaledXY(gateMark.getSingleMark2()));
gateMark.getSingleMark1().setX((int) canvasLocation.getX()); group.getChildren().add(markGroup);
gateMark.getSingleMark1().setY((int) canvasLocation.getY());
canvasLocation = findScaledXY(gateMark.getSingleMark2());
gateMark.getSingleMark2().setX((int) canvasLocation.getX());
gateMark.getSingleMark2().setY((int) canvasLocation.getY());
} }
if (mark.getMarkType() == MarkType.CLOSED_GATE)
((GateMark) mark).assignXYCentered();
else { else {
canvasLocation = findScaledXY(mark); // canvasLocation = findScaledXY(mark);
mark.setX((int) canvasLocation.getX()); // mark.setX((int) canvasLocation.getX());
mark.setY((int) canvasLocation.getY()); // mark.setY((int) canvasLocation.getY());
markGroup = new MarkGroup(mark, findScaledXY(mark));
} }
} }
} }
+63 -83
View File
@@ -20,9 +20,11 @@ public class BoatGroup extends RaceObject{
private static final double BOAT_HEIGHT = 15d; private static final double BOAT_HEIGHT = 15d;
private static final double BOAT_WIDTH = 10d; private static final double BOAT_WIDTH = 10d;
//Time between sections of race - Should be changed to 200 for actual program. //Time between sections of race - Should be changed to 200 for actual program.
private static double expectedUpdateInterval = 2000; private static double expectedUpdateInterval = 200;
private static int WAKE_FRAME_INTERVAL = 40;
private Boat boat; private Boat boat;
private int wakeCounter = WAKE_FRAME_INTERVAL;
public BoatGroup (Boat boat, Color color){ public BoatGroup (Boat boat, Color color){
this.boat = boat; this.boat = boat;
@@ -60,11 +62,7 @@ public class BoatGroup extends RaceObject{
velocityObject.setY(VELOCITY_Y_OFFSET); velocityObject.setY(VELOCITY_Y_OFFSET);
velocityObject.relocate(velocityObject.getX(), velocityObject.getY()); velocityObject.relocate(velocityObject.getX(), velocityObject.getY());
wake.setLayoutX(0); super.getChildren().addAll(boatPoly, teamNameObject, velocityObject);
wake.setLayoutY(0);
wake.relocate(wake.getLayoutX(), wake.getLayoutY());
super.getChildren().addAll(boatPoly, wake, teamNameObject, velocityObject);
} }
private void initChildren (Color color) { private void initChildren (Color color) {
@@ -78,10 +76,10 @@ public class BoatGroup extends RaceObject{
* @param dx The amount to move the X coordinate by * @param dx The amount to move the X coordinate by
* @param dy The amount to move the Y coordinate by * @param dy The amount to move the Y coordinate by
*/ */
void moveBy(double dx, double dy, double rotation) { public void moveGroupBy(double dx, double dy, double rotation) {
super.setLayoutX(super.getLayoutX() + dx); super.setLayoutX(super.getLayoutX() + dx);
super.setLayoutY(super.getLayoutY() + dy); super.setLayoutY(super.getLayoutY() + dy);
rotateBoat(rotation); rotateTo(currentRotation + rotation);
} }
/** /**
@@ -90,8 +88,7 @@ public class BoatGroup extends RaceObject{
* @param y The Y coordinate to move the boat to * @param y The Y coordinate to move the boat to
*/ */
public void moveTo (double x, double y, double rotation) { public void moveTo (double x, double y, double rotation) {
super.currentRotation = 0; rotateTo(rotation);
rotateBoat(rotation);
moveTo(x, y); moveTo(x, y);
} }
@@ -109,98 +106,77 @@ public class BoatGroup extends RaceObject{
} else if (rotationalGoal < currentRotation && rotationalVelocity < 0) { } else if (rotationalGoal < currentRotation && rotationalVelocity < 0) {
rotation = rotationalVelocity * timeInterval; rotation = rotationalVelocity * timeInterval;
} }
moveBy(dx, dy, rotation); moveGroupBy(dx, dy, rotation);
} for (Node wake : super.getChildren().subList(4, super.getChildren().size())) {
if (!((Wake) wake).updatePosition(timeInterval))
public void setDestination (double newXValue, double newYValue, double rotation) { super.getChildren().remove(wake);
this.pixelVelocityX = (newXValue - super.getLayoutX()) / expectedUpdateInterval; }
this.pixelVelocityY = (newYValue - super.getLayoutY()) / expectedUpdateInterval; if (wakeCounter-- == 0) {
//this.destinationX = newXValue; wakeCounter = WAKE_FRAME_INTERVAL;
//this.destinationY = newYValue; super.getChildren().add(
this.rotationalGoal = rotation; new Wake(
// if (super.getLayoutY() >= newYValue && super.getLayoutX() <= newXValue) super.getLayoutX(), super.getLayoutY(), pixelVelocityX, pixelVelocityY
// rotationalGoal = 90 - rotationalGoal; )
// else if (super.getLayoutY() < newYValue && super.getLayoutX() <= newXValue) );
// rotationalGoal = 90 + rotationalGoal;
// else if (super.getLayoutY() >= newYValue && super.getLayoutX() > newXValue)
// rotationalGoal = 270 + rotationalGoal;
// else
// rotationalGoal = 270 - rotationalGoal;
// if (Math.abs(360 - rotationalGoal + currentRotation) < Math.abs(rotationalGoal - currentRotation)) {
// System.out.println("ROTATE");
// this.rotationalVelocity = (360 - rotationalGoal + currentRotation) / expectedUpdateInterval;
// } else {
// this.rotationalVelocity = (rotationalGoal - currentRotation) / expectedUpdateInterval;
// }
if (Math.abs(rotationalGoal - currentRotation) > 180) {
if (rotationalGoal - currentRotation >= 0) {
this.rotationalVelocity = ((rotationalGoal - currentRotation) - 360) / expectedUpdateInterval;
} else {
this.rotationalVelocity = (360 + (rotationalGoal - currentRotation)) / expectedUpdateInterval;
}
} else {
this.rotationalVelocity = (rotationalGoal - currentRotation) / expectedUpdateInterval;
} }
} }
public void setDestination (double newXValue, double newYValue) { public void setDestination (double newXValue, double newYValue, double rotation, int... raceIds) {
this.pixelVelocityX = (newXValue - super.getLayoutX()) / expectedUpdateInterval; if (hasRaceId(raceIds)) {
this.pixelVelocityY = (newYValue - super.getLayoutY()) / expectedUpdateInterval; this.pixelVelocityX = (newXValue - super.getLayoutX()) / expectedUpdateInterval;
//this.destinationX = newXValue; this.pixelVelocityY = (newYValue - super.getLayoutY()) / expectedUpdateInterval;
//this.destinationY = newYValue; this.rotationalGoal = rotation;
this.rotationalGoal = Math.abs( if (Math.abs(rotationalGoal - currentRotation) > 180) {
Math.toDegrees( if (rotationalGoal - currentRotation >= 0) {
Math.atan( this.rotationalVelocity = ((rotationalGoal - currentRotation) - 360) / expectedUpdateInterval;
(newYValue - super.getLayoutY()) / (newXValue - super.getLayoutX()) } else {
) this.rotationalVelocity = (360 + (rotationalGoal - currentRotation)) / expectedUpdateInterval;
) }
);
if (super.getLayoutY() >= newYValue && super.getLayoutX() <= newXValue)
rotationalGoal = 90 - rotationalGoal;
else if (super.getLayoutY() < newYValue && super.getLayoutX() <= newXValue)
rotationalGoal = 90 + rotationalGoal;
else if (super.getLayoutY() >= newYValue && super.getLayoutX() > newXValue)
rotationalGoal = 270 + rotationalGoal;
else
rotationalGoal = 270 - rotationalGoal;
if (Math.abs(rotationalGoal - currentRotation) > 180) {
if (rotationalGoal - currentRotation >= 0) {
this.rotationalVelocity = ((rotationalGoal - currentRotation) - 360) / expectedUpdateInterval;
} else { } else {
this.rotationalVelocity = (360 + (rotationalGoal - currentRotation)) / expectedUpdateInterval; this.rotationalVelocity = (rotationalGoal - currentRotation) / expectedUpdateInterval;
} }
} else {
this.rotationalVelocity = (rotationalGoal - currentRotation) / expectedUpdateInterval;
} }
} }
public void rotateBoat (double rotationDeg) { public void setDestination (double newXValue, double newYValue, int... raceIDs) {
currentRotation += rotationDeg; if (hasRaceId(raceIDs)) {
double rotation = Math.abs(
Math.toDegrees(
Math.atan(
(newYValue - super.getLayoutY()) / (newXValue - super.getLayoutX())
)
)
);
if (super.getLayoutY() >= newYValue && super.getLayoutX() <= newXValue)
rotation = 90 - rotation;
else if (super.getLayoutY() < newYValue && super.getLayoutX() <= newXValue)
rotation = 90 + rotation;
else if (super.getLayoutY() >= newYValue && super.getLayoutX() > newXValue)
rotation = 270 + rotation;
else
rotation = 270 - rotation;
setDestination(newXValue, newYValue, rotation, raceIDs);
}
}
public void rotateTo (double rotation) {
Node boatPoly = super.getChildren().get(0); Node boatPoly = super.getChildren().get(0);
boatPoly.getTransforms().clear(); boatPoly.getTransforms().clear();
boatPoly.getTransforms().add(new Rotate(currentRotation, BOAT_WIDTH/2, 0)); boatPoly.getTransforms().add(new Rotate(rotation, BOAT_WIDTH/2, 0));
Node wake = super.getChildren().get(1); Node wake = super.getChildren().get(1);
wake.getTransforms().clear(); wake.getTransforms().clear();
wake.getTransforms().add(new Translate(0, BOAT_HEIGHT)); wake.getTransforms().add(new Translate(0, BOAT_HEIGHT));
wake.getTransforms().add(new Rotate(currentRotation, BOAT_WIDTH/2, -BOAT_HEIGHT)); wake.getTransforms().add(new Rotate(rotation, BOAT_WIDTH/2, -BOAT_HEIGHT));
}
public static double getExpectedUpdateInterval() {
return expectedUpdateInterval;
}
public static void setExpectedUpdateInterval(double expectedUpdateInterval) {
BoatGroup.expectedUpdateInterval = expectedUpdateInterval;
} }
public void forceRotation () { public void forceRotation () {
rotateBoat (rotationalGoal - currentRotation); rotateTo (rotationalGoal);
} }
public void toggleAnnotations () { public void toggleAnnotations () {
super.getChildren().get(1).setVisible(false); for (Node node : super.getChildren().subList(1, super.getChildren().size())) {
super.getChildren().get(2).setVisible(false); node.setVisible(false);
super.getChildren().get(3).setVisible(false); }
} }
public Boat getBoat() { public Boat getBoat() {
@@ -214,4 +190,8 @@ public class BoatGroup extends RaceObject{
} }
return false; return false;
} }
public int[] getRaceIds () {
return new int[] {boat.getId()};
}
} }
+31 -7
View File
@@ -8,11 +8,14 @@ import javafx.scene.Group;
*/ */
public abstract class RaceObject extends Group { public abstract class RaceObject extends Group {
double rotationalGoal; //Time between sections of race - Should be changed to 200 for actual program.
double currentRotation; protected static double expectedUpdateInterval = 2000;
double rotationalVelocity;
double pixelVelocityX; protected double rotationalGoal;
double pixelVelocityY; protected double currentRotation;
protected double rotationalVelocity;
protected double pixelVelocityX;
protected double pixelVelocityY;
public boolean isSamePos (Point2D point) { public boolean isSamePos (Point2D point) {
return point.getX() == super.getLayoutX() && point.getY() == super.getLayoutY(); return point.getX() == super.getLayoutX() && point.getY() == super.getLayoutY();
@@ -21,12 +24,33 @@ public abstract class RaceObject extends Group {
public Point2D getPosition () { public Point2D getPosition () {
return new Point2D(super.getLayoutX(), getLayoutY()); return new Point2D(super.getLayoutX(), getLayoutY());
} }
public abstract void setDestination (double x, double y, double rotation);
public abstract void setDestination (double x, double y); public static double getExpectedUpdateInterval() {
return expectedUpdateInterval;
}
public static void setExpectedUpdateInterval(double expectedUpdateInterval) {
RaceObject.expectedUpdateInterval = expectedUpdateInterval;
}
public abstract void setDestination (double x, double y, double rotation, int... raceIds);
public abstract void setDestination (double x, double y, int... raceIds);
public abstract void updatePosition (double timeInterval); public abstract void updatePosition (double timeInterval);
public abstract void moveTo (double x, double y, double rotation); public abstract void moveTo (double x, double y, double rotation);
public abstract void moveTo (double x, double y); public abstract void moveTo (double x, double y);
public abstract void moveGroupBy(double x, double y, double rotation);
public abstract void rotateTo (double rotation);
public abstract boolean hasRaceId (int... raceIds); public abstract boolean hasRaceId (int... raceIds);
public abstract int[] getRaceIds ();
public abstract void toggleAnnotations (); public abstract void toggleAnnotations ();
} }
+37
View File
@@ -0,0 +1,37 @@
package seng302.models;
import javafx.scene.paint.Color;
import javafx.scene.shape.Arc;
import javafx.scene.shape.ArcType;
/**
* Created by CJIRWIN on 27/04/2017.
*/
class Wake extends Arc {
private static int VELOCITY_SCALE_FACTOR = 3;
private static int MAX_LIFESPAN = 180;
private static double LIFESPAN_PER_FRAME = 1.0 / MAX_LIFESPAN;
private double velocityX;
private double velocityY;
private int lifespan = MAX_LIFESPAN;
Wake (double startingX, double startingY, double velocityX, double velocityY) {
super(startingX, startingY, 25, 15, 160, 40);
super.setFill(Color.BLUE);
super.setType(ArcType.OPEN);
super.setStrokeWidth(2.0);
this.velocityX = -velocityX;
this.velocityY = -velocityY;
}
boolean updatePosition (double timeInterval) {
lifespan--;
super.setLayoutX(super.getLayoutX() + velocityX * timeInterval);
super.setLayoutX(super.getLayoutX() + velocityX * timeInterval);
super.setOpacity(LIFESPAN_PER_FRAME * lifespan * super.getOpacity());
return lifespan == 0;
}
}
@@ -48,15 +48,4 @@ public class GateMark extends Mark {
return (this.getSingleMark1().getLongitude()); return (this.getSingleMark1().getLongitude());
} }
public void assignXYCentered () {
System.out.println("POSSIBLE GOOF " + xValue + " " + yValue);
System.out.println(singleMark1.getX() + " " + singleMark1.getY());
System.out.println(singleMark2.getX() + " " + singleMark2.getY());
double dx = singleMark2.getX() - singleMark1.getX();
System.out.println("dx + " + dx);
double dy = singleMark2.getY() - singleMark1.getY();
xValue = (int) Math.round(singleMark1.getX() + dx / 2);
yValue = (int) Math.round(singleMark1.getY() + dy / 2);
System.out.println("PROBABLE GAAF " + xValue + " " + yValue);
}
} }
@@ -11,8 +11,6 @@ public abstract class Mark {
private double latitude; private double latitude;
private double longitude; private double longitude;
private int id; private int id;
Integer xValue;
Integer yValue;
/** /**
* Create a mark instance by passing its name and type * Create a mark instance by passing its name and type
@@ -127,22 +125,6 @@ public abstract class Mark {
return longitude; return longitude;
} }
public int getX () {
return xValue;
}
public int getY () {
return yValue;
}
public void setX (int x) {
this.xValue = x;
}
public void setY (int y) {
this.yValue = y;
}
public int getId() { public int getId() {
return id; return id;
} }
+135 -29
View File
@@ -1,27 +1,35 @@
package seng302.models.mark; package seng302.models.mark;
import javafx.geometry.Point2D; import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.shape.Circle; import javafx.scene.shape.Circle;
import javafx.scene.shape.Line; import javafx.scene.shape.Line;
import javafx.scene.transform.Rotate; import javafx.scene.transform.Rotate;
import seng302.models.RaceObject; import seng302.models.RaceObject;
import java.util.ArrayList;
import java.util.List;
/** /**
* Created by CJIRWIN on 26/04/2017. * Created by CJIRWIN on 26/04/2017.
*/ */
public class MarkGroup extends RaceObject { public class MarkGroup extends RaceObject {
private static int MARK_RADIUS = 5; private static int MARK_RADIUS = 5;
private static int LINE_THICKNESS = 2;
private Mark mark; private static double DASHED_GAP_LEN = 2d;
private double pixelVelocityXM1; private static double DASHED_LINE_LEN = 5d;
private double pixelVelocityYM1;
private double pixelVelocityXM2;
private double pixelVelocityYM3;
private List<Mark> marks = new ArrayList<>();
private Mark mainMark;
private double[] nodePixelVelocitiesX;
private double[] nodePixelVelocitiesY;
private Point2D[] nodeDestinations;
public MarkGroup (Mark mark, Point2D... points) { public MarkGroup (Mark mark, Point2D... points) {
marks.add(mark);
mainMark = mark;
Color color = Color.BLACK; Color color = Color.BLACK;
if (mark.getName().equals("Start")){ if (mark.getName().equals("Start")){
color = Color.GREEN; color = Color.GREEN;
@@ -31,11 +39,20 @@ public class MarkGroup extends RaceObject {
if (mark.getMarkType() == MarkType.SINGLE_MARK) { if (mark.getMarkType() == MarkType.SINGLE_MARK) {
super.getChildren().add(new Circle(0, 0, MARK_RADIUS, color)); super.getChildren().add(new Circle(0, 0, MARK_RADIUS, color));
} else { } else {
super.getChildren().add(new Circle(0, 0, MARK_RADIUS, color)); marks.add(((GateMark) mark).getSingleMark1());
marks.add(((GateMark) mark).getSingleMark2());
super.getChildren().add( super.getChildren().add(
new Circle( new Circle(
points[1].getX() - points[0].getX(), (points[1].getX() - points[0].getX() / 2),
points[1].getY() - points[0].getY(), (points[1].getY() - points[0].getY() / 2),
MARK_RADIUS,
color
)
);
super.getChildren().add(
new Circle(
-(points[1].getX() - points[0].getX() / 2),
-(points[1].getY() - points[0].getY() / 2),
MARK_RADIUS, MARK_RADIUS,
color color
) )
@@ -46,33 +63,60 @@ public class MarkGroup extends RaceObject {
points[1].getX() - points[0].getX(), points[1].getX() - points[0].getX(),
points[1].getY() - points[0].getY() points[1].getY() - points[0].getY()
); );
line.setStrokeWidth(2); line.setStrokeWidth(LINE_THICKNESS);
if (mark.getMarkType() == MarkType.OPEN_GATE) { if (mark.getMarkType() == MarkType.OPEN_GATE) {
line.getStrokeDashArray().addAll(3d, 5d); line.getStrokeDashArray().addAll(DASHED_GAP_LEN, DASHED_LINE_LEN);
} }
super.getChildren().add(line); super.getChildren().add(line);
nodePixelVelocitiesX = new double[2];
nodePixelVelocitiesY = new double[2];
nodeDestinations = new Point2D[2];
} }
this.mark = mark;
moveTo(points[0].getX(), points[0].getY()); moveTo(points[0].getX(), points[0].getY());
} }
public void setDestination (double x, double y, double rotation) { public void setDestination (double x, double y, double rotation, int... raceIds) {
setDestination(x, y, raceIds);
this.rotationalGoal = rotation;
if (Math.abs(rotationalGoal - currentRotation) > 180) {
if (rotationalGoal - currentRotation >= 0) {
this.rotationalVelocity = ((rotationalGoal - currentRotation) - 360) / expectedUpdateInterval;
} else {
this.rotationalVelocity = (360 + (rotationalGoal - currentRotation)) / expectedUpdateInterval;
}
} else {
this.rotationalVelocity = (rotationalGoal - currentRotation) / expectedUpdateInterval;
}
} }
public void setDestination (double x, double y) { public void setDestination (double x, double y, int... raceIds) {
int childrenIndex = -1;
for (Mark mark : marks) {
for (int id : raceIds)
if (id == mark.getId() && childrenIndex != -1)
setDestinationChild(x, y, childrenIndex);
else if (id == mark.getId())
setDestinationGroup(x, y);
childrenIndex++;
}
} }
public void setMarkDestination (int markId, double x, double y) {
}
public void updatePosition (double timeInterval) {
private void setDestinationChild (double x, double y, int childIndex) {
double relativeX = x - super.getLayoutX();
double relativeY = y - super.getLayoutY();
this.nodeDestinations[childIndex] = new Point2D(relativeX, relativeY);
this.nodePixelVelocitiesX[childIndex] = (relativeX - super.getChildren().get(childIndex).getLayoutX()) / expectedUpdateInterval;
this.nodePixelVelocitiesY[childIndex] = (relativeY - super.getChildren().get(childIndex).getLayoutY()) / expectedUpdateInterval;
} }
public void moveTo (double x, double y, double rotation) { private void setDestinationGroup (double x, double y) {
moveTo(x, y); pixelVelocityX = (x - super.getLayoutX()) / expectedUpdateInterval;
pixelVelocityY = (y - super.getLayoutY()) / expectedUpdateInterval;
}
public void rotateTo (double rotation) {
super.getTransforms().clear(); super.getTransforms().clear();
super.getTransforms().add( super.getTransforms().add(
new Rotate( new Rotate(
@@ -83,20 +127,74 @@ public class MarkGroup extends RaceObject {
); );
} }
public void updatePosition (double timeInterval) {
double x = pixelVelocityX * timeInterval;
double y = pixelVelocityY * timeInterval;
double rotation = rotationalVelocity * timeInterval;
moveGroupBy(x, y, rotation);
updateChildren(timeInterval);
}
public void moveGroupBy (double x, double y, double rotation) {
super.setLayoutX(super.getLayoutX() + x);
super.setLayoutY(super.getOpacity() + y);
rotateTo(rotation + currentRotation);
}
private void updateChildren (double timeInterval) {
if (mainMark.getMarkType() != MarkType.SINGLE_MARK) {
Circle mark = (Circle) super.getChildren().get(0);
if (nodePixelVelocitiesX[0] > 0 && mark.getLayoutX() >= nodeDestinations[0].getX()) {
nodePixelVelocitiesX[0] = 0;
} else if (nodePixelVelocitiesX[0] < 0 && mark.getLayoutX() <= nodeDestinations[0].getX()) {
nodePixelVelocitiesX[0] = 0;
} else {
mark.setLayoutX(mark.getLayoutX() + nodePixelVelocitiesX[0] * timeInterval);
mark.setLayoutY(mark.getLayoutY() + nodePixelVelocitiesY[0] * timeInterval);
}
if (nodePixelVelocitiesY[0] >= 0 && mark.getLayoutY() > nodeDestinations[0].getY()) {
nodePixelVelocitiesY[0] = 0;
} else if (nodePixelVelocitiesY[0] < 0 && mark.getLayoutY() <= nodeDestinations[0].getY()) {
nodePixelVelocitiesY[0] = 0;
} else {
mark.setLayoutX(mark.getLayoutX() + nodePixelVelocitiesX[0] * timeInterval);
mark.setLayoutY(mark.getLayoutY() + nodePixelVelocitiesY[0] * timeInterval);
}
mark = (Circle) super.getChildren().get(1);
if (nodePixelVelocitiesX[1] > 0 && mark.getLayoutX() >= nodeDestinations[1].getX()) {
nodePixelVelocitiesX[1] = 0;
} else if (nodePixelVelocitiesX[1] < 0 && mark.getLayoutX() <= nodeDestinations[1].getX()) {
nodePixelVelocitiesX[1] = 0;
} else {
mark.setLayoutX(mark.getLayoutX() + nodePixelVelocitiesX[1] * timeInterval);
mark.setLayoutY(mark.getLayoutY() + nodePixelVelocitiesY[1] * timeInterval);
}
if (nodePixelVelocitiesY[1] >= 0 && mark.getLayoutY() > nodeDestinations[1].getY()) {
nodePixelVelocitiesY[1] = 0;
} else if (nodePixelVelocitiesY[1] < 0 && mark.getLayoutY() <= nodeDestinations[1].getY()) {
nodePixelVelocitiesY[1] = 0;
} else {
mark.setLayoutX(mark.getLayoutX() + nodePixelVelocitiesX[1] * timeInterval);
mark.setLayoutY(mark.getLayoutY() + nodePixelVelocitiesY[1] * timeInterval);
}
}
}
public void moveTo (double x, double y, double rotation) {
moveTo(x, y);
rotateTo(rotation);
}
public void moveTo (double x, double y) { public void moveTo (double x, double y) {
super.setLayoutX(x); super.setLayoutX(x);
super.setLayoutY(y); super.setLayoutY(y);
} }
public boolean hasRaceId (int... raceIds) { public boolean hasRaceId (int... raceIds) {
for (int id : raceIds) { for (int id : raceIds)
for (Mark mark : marks)
if (id == mark.getId()) if (id == mark.getId())
return true; return true;
if (mark.getMarkType() != MarkType.SINGLE_MARK) {
if (id == ((GateMark) mark).getSingleMark1().getId() || id == ((GateMark) mark).getSingleMark2().getId())
return true;
}
}
return false; return false;
} }
public void toggleAnnotations () { public void toggleAnnotations () {
@@ -111,4 +209,12 @@ public class MarkGroup extends RaceObject {
MARK_RADIUS = markRadius; MARK_RADIUS = markRadius;
} }
public int[] getRaceIds () {
int[] idArray = new int[marks.size()];
int i = 0;
for (Mark mark : marks)
idArray[i++] = mark.getId();
return idArray;
}
} }