mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
Boat trials and wakes now work with both fast and slow data sets.
Instead of fixed, hard coded thresholds and scale factors dynamically changing values that scale with the onscreen movement are used to determine how graphical objects are drawn. #implement #story[816]
This commit is contained in:
@@ -26,7 +26,7 @@ public class App extends Application
|
||||
sr = new StreamReceiver("localhost", 8085, "TestThread1");
|
||||
}
|
||||
else{
|
||||
//StreamReceiver sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"TestThread1");
|
||||
// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"TestThread1");
|
||||
sr = new StreamReceiver("livedata.americascup.com", 4941, "TestThread1");
|
||||
}
|
||||
|
||||
|
||||
@@ -125,7 +125,6 @@ public class CanvasController {
|
||||
}
|
||||
// TODO: 1/05/17 cir27 - Make the RaceObjects update on the actual delay.
|
||||
elapsedNanos = 1000 / 60;
|
||||
System.out.println("elapsedNanos = " + elapsedNanos);
|
||||
for (RaceObject raceObject : raceObjects) {
|
||||
raceObject.updatePosition(elapsedNanos);
|
||||
for (int id : raceObject.getRaceIds()) {
|
||||
|
||||
@@ -22,11 +22,11 @@ public class BoatGroup extends RaceObject{
|
||||
private static final double VELOCITY_Y_OFFSET = -5d;
|
||||
private static final double BOAT_HEIGHT = 15d;
|
||||
private static final double BOAT_WIDTH = 10d;
|
||||
private static final int LINE_INTERVAL = 30;
|
||||
private double framesForNewLine = 0;
|
||||
private static double expectedUpdateInterval = 200;
|
||||
private boolean destinationSet;
|
||||
private Point2D lastPoint;
|
||||
private int wakeGenerationDelay;
|
||||
private int wakeGenerationDelay = 10;
|
||||
private double distanceTravelled;
|
||||
|
||||
private Boat boat;
|
||||
private Group lineGroup = new Group();
|
||||
@@ -81,7 +81,6 @@ public class BoatGroup extends RaceObject{
|
||||
destinationSet = false;
|
||||
|
||||
wake = new Wake(0, -BOAT_HEIGHT);
|
||||
wakeGenerationDelay = wake.numWakes;
|
||||
super.getChildren().addAll(teamNameObject, velocityObject, boatPoly);
|
||||
}
|
||||
|
||||
@@ -150,10 +149,11 @@ public class BoatGroup extends RaceObject{
|
||||
double dx = pixelVelocityX * timeInterval;
|
||||
double dy = pixelVelocityY * timeInterval;
|
||||
double rotation = rotationalVelocity * timeInterval;
|
||||
distanceTravelled += Math.abs(dx) + Math.abs(dy);
|
||||
moveGroupBy(dx, dy, rotation);
|
||||
|
||||
if (framesForNewLine-- == 0) {
|
||||
framesForNewLine = LINE_INTERVAL;
|
||||
//Draw a new section of the trail every 20 pixels of movement.
|
||||
if (distanceTravelled > 20) {
|
||||
distanceTravelled = 0;
|
||||
if (lastPoint != null) {
|
||||
Line l = new Line(
|
||||
lastPoint.getX(),
|
||||
@@ -161,19 +161,24 @@ public class BoatGroup extends RaceObject{
|
||||
boatPoly.getLayoutX(),
|
||||
boatPoly.getLayoutY()
|
||||
);
|
||||
l.getStrokeDashArray().setAll(4d, 6d);
|
||||
l.getStrokeDashArray().setAll(3d, 7d);
|
||||
l.setStroke(boatPoly.getFill());
|
||||
lineGroup.getChildren().add(l);
|
||||
}
|
||||
if (destinationSet){
|
||||
if (destinationSet){ //Only begin drawing after the first destination is set
|
||||
lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
|
||||
}
|
||||
if (lineGroup.getChildren().size() > 60)
|
||||
lineGroup.getChildren().remove(0);
|
||||
}
|
||||
wake.updatePosition(timeInterval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the destination of the boat and the headng it should have once it reaches
|
||||
* @param newXValue
|
||||
* @param newYValue
|
||||
* @param rotation Rotation to move graphics to.
|
||||
* @param raceIds RaceID of the object to move.
|
||||
*/
|
||||
public void setDestination (double newXValue, double newYValue, double rotation, int... raceIds) {
|
||||
if (hasRaceId(raceIds)) {
|
||||
destinationSet = true;
|
||||
@@ -187,19 +192,37 @@ public class BoatGroup extends RaceObject{
|
||||
pixelVelocityX = dx / expectedUpdateInterval;
|
||||
}
|
||||
double dy = newYValue - boatPoly.getLayoutY();
|
||||
if ((dy > 0 && pixelVelocityY < 0) || (dy < 0 && pixelVelocityY > 0)) {
|
||||
pixelVelocityY = 0;
|
||||
} else {
|
||||
pixelVelocityY = dy / expectedUpdateInterval;
|
||||
//Check movement is reasonable. Assumes a 1000 * 1000 canvas
|
||||
if (Math.abs(dx) > 50 || Math.abs(dy) > 50) {
|
||||
// System.out.println("dx = " + dx);
|
||||
// System.out.println("dy = " + dy);
|
||||
dx = 0;
|
||||
dy = 0;
|
||||
moveTo(newXValue, newYValue);
|
||||
}
|
||||
//Slight delay on changing X/Y direction that could help jitter. Disabled since there was an issue with
|
||||
//packets that might be causing it.
|
||||
// if ((dx > 0 && pixelVelocityX < 0) || (dx < 0 && pixelVelocityX > 0)) {
|
||||
// pixelVelocityX = 0;
|
||||
// } else {
|
||||
// pixelVelocityX = dx / expectedUpdateInterval;
|
||||
// }
|
||||
// if ((dy > 0 && pixelVelocityY < 0) || (dy < 0 && pixelVelocityY > 0)) {
|
||||
// pixelVelocityY = 0;
|
||||
// } else {
|
||||
// pixelVelocityY = dy / expectedUpdateInterval;
|
||||
// }
|
||||
pixelVelocityX = dx / expectedUpdateInterval;
|
||||
pixelVelocityY = dy / expectedUpdateInterval;
|
||||
rotationalGoal = rotation;
|
||||
calculateRotationalVelocity();
|
||||
if (wakeGenerationDelay > 0) {
|
||||
wake.rotate(rotationalGoal);
|
||||
wakeGenerationDelay--;
|
||||
} else {
|
||||
wake.setRotationalVelocity(rotationalVelocity, currentRotation, pixelVelocityX, pixelVelocityY);
|
||||
wake.setRotationalVelocity(rotationalVelocity, currentRotation, boat.getVelocity());
|
||||
}
|
||||
velocityObject.setText(String.format("%.2f m/s", boat.getVelocity()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,12 +15,13 @@ import javafx.scene.transform.Rotate;
|
||||
*/
|
||||
class Wake extends Group {
|
||||
|
||||
final int numWakes = 5;
|
||||
private int numWakes = 5;
|
||||
private double[] velocities = new double[13];
|
||||
private Arc[] arcs = new Arc[numWakes];
|
||||
private double[] rotations = new double[numWakes];
|
||||
private int[] velocityIndices = new int[numWakes];
|
||||
private double sum = 0;
|
||||
private static double max;
|
||||
|
||||
/**
|
||||
* Create a wake at the given location.
|
||||
@@ -46,15 +47,19 @@ class Wake extends Group {
|
||||
* Sets the rotationalVelocity of each arc. Each arc is 3 velocities behind the next smallest arc. The smallest uses
|
||||
* the latest given velocity.
|
||||
* @param rotationalVelocity The rotationalVelocity the wake should move at.
|
||||
* @param rotationGoal Where the wake will rotate to if the wake is calculated to be on a straight section. This is
|
||||
* used to prevent desynchronisation with the Boat polygon.
|
||||
* @param velocity The real world velocity of the boat in m/s.
|
||||
*/
|
||||
void setRotationalVelocity (double rotationalVelocity, double rotationGoal, double velocityX, double velocityY) {
|
||||
if (Math.abs(rotationalVelocity) > 0.5) {
|
||||
rotationalVelocity = 0;
|
||||
}
|
||||
void setRotationalVelocity (double rotationalVelocity, double rotationGoal, double velocity) {
|
||||
// if (Math.abs(rotationalVelocity) > 0.5) {
|
||||
// rotationalVelocity = 0;
|
||||
// }
|
||||
sum -= Math.abs(velocities[(velocityIndices[0] + 10) % 13]);
|
||||
sum += Math.abs(rotationalVelocity);
|
||||
System.out.println("sum = " + sum);
|
||||
if (sum < 0.9)
|
||||
// System.out.println("sum = " + sum);
|
||||
max = Math.max(max, rotationalVelocity);
|
||||
if (sum < max)
|
||||
rotate (rotationGoal); //In relatively straight segments the wake snaps to match the boats current position.
|
||||
//This stops the wake from eventually becoming out of sync with the boat.
|
||||
|
||||
@@ -65,14 +70,14 @@ class Wake extends Group {
|
||||
for (int i = 1; i < numWakes; i++)
|
||||
velocityIndices[i] = (velocityIndices[0] + 3 * i) % 13;
|
||||
|
||||
//Scale wakes based on velocity. Assumes boats are always moving at a decent pace.
|
||||
double scaleFactor = Math.abs(Math.log10(Math.abs(velocityX) + Math.abs(velocityY)));
|
||||
double baseRad = 25;
|
||||
//Scale wakes based on velocity.
|
||||
double baseRad = 20;
|
||||
double rad;
|
||||
for (Arc arc :arcs) {
|
||||
double rad = Math.min(baseRad + 5 * scaleFactor, baseRad + 15);
|
||||
rad = baseRad + velocity;
|
||||
arc.setRadiusX(rad);
|
||||
arc.setRadiusY(rad);
|
||||
baseRad += 10;
|
||||
baseRad += 5 + (velocity / 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -142,13 +142,13 @@ public class MarkGroup extends RaceObject {
|
||||
if (nodePixelVelocitiesX[0] > 0 && markCircle.getCenterX() > nodeDestinations[0].getX() ||
|
||||
nodePixelVelocitiesX[0] < 0 && markCircle.getCenterX() < nodeDestinations[0].getY())
|
||||
nodePixelVelocitiesX[0] = 0;
|
||||
else
|
||||
else if (nodePixelVelocitiesX[0] != 0)
|
||||
markCircle.setCenterX(markCircle.getCenterX() + nodePixelVelocitiesX[0] * timeInterval);
|
||||
|
||||
if (nodePixelVelocitiesY[0] > 0 && markCircle.getCenterY() > nodeDestinations[0].getY() ||
|
||||
nodePixelVelocitiesY[0] < 0 && markCircle.getCenterY() < nodeDestinations[0].getY())
|
||||
nodePixelVelocitiesY[0] = 0;
|
||||
else
|
||||
else if (nodePixelVelocitiesY[0] != 0)
|
||||
markCircle.setCenterY(markCircle.getCenterY() + nodePixelVelocitiesY[0] * timeInterval);
|
||||
|
||||
if (mainMark.getMarkType() != MarkType.SINGLE_MARK) {
|
||||
@@ -162,13 +162,13 @@ public class MarkGroup extends RaceObject {
|
||||
if (nodePixelVelocitiesX[1] > 0 && markCircle.getCenterX() >= nodeDestinations[1].getX() ||
|
||||
nodePixelVelocitiesX[1] < 0 && markCircle.getCenterX() <= nodeDestinations[1].getX())
|
||||
nodePixelVelocitiesX[1] = 0;
|
||||
else
|
||||
else if (nodePixelVelocitiesX[1] != 0)
|
||||
markCircle.setCenterX(markCircle.getCenterX() + nodePixelVelocitiesX[1] * timeInterval);
|
||||
|
||||
if (nodePixelVelocitiesY[1] > 0 && markCircle.getCenterY() > nodeDestinations[1].getY() ||
|
||||
nodePixelVelocitiesY[1] < 0 && markCircle.getCenterY() < nodeDestinations[1].getY())
|
||||
nodePixelVelocitiesY[1] = 0;
|
||||
else
|
||||
else if (nodePixelVelocitiesY[1] != 0)
|
||||
markCircle.setCenterY(markCircle.getCenterY() + nodePixelVelocitiesY[1] * timeInterval);
|
||||
line.setEndX(markCircle.getCenterX());
|
||||
line.setEndY(markCircle.getCenterY());
|
||||
|
||||
Reference in New Issue
Block a user