Merge branch 'master' into new_issue#19

This commit is contained in:
David Wu
2017-08-17 13:52:04 +12:00
29 changed files with 537 additions and 325 deletions
@@ -1,6 +1,5 @@
package mock.model;
import shared.model.*;
@@ -74,7 +73,7 @@ public class MockBoat extends Boat {
public Bearing calculateBearingToNextMarker() {
//Get the start and end points.
GPSCoordinate currentPosition = this.getCurrentPosition();
GPSCoordinate currentPosition = this.getPosition();
GPSCoordinate nextMarkerPosition;
// if boat is at the finish
@@ -87,7 +86,6 @@ public class MockBoat extends Boat {
//Calculate bearing.
Bearing bearing = GPSCoordinate.calculateBearing(currentPosition, nextMarkerPosition);
return bearing;
}
@@ -100,7 +98,7 @@ public class MockBoat extends Boat {
public double calculateDistanceToNextMarker() {
//Get start and end markers.
GPSCoordinate startPosition = this.getCurrentPosition();
GPSCoordinate startPosition = this.getPosition();
//When boats finish, their "current leg" doesn't have an end marker.
if (this.getCurrentLeg().getEndCompoundMark() == null) {
@@ -111,9 +109,7 @@ public class MockBoat extends Boat {
//Calculate distance.
double distanceNauticalMiles = GPSCoordinate.calculateDistanceNauticalMiles(startPosition, endMarker);
return distanceNauticalMiles;
return GPSCoordinate.calculateDistanceNauticalMiles(startPosition, endMarker);
}
@@ -160,8 +156,8 @@ public class MockBoat extends Boat {
*/
public void moveForwards(double meters) {
//Updates the current position of the boat.
GPSCoordinate newPosition = GPSCoordinate.calculateNewPosition(this.getCurrentPosition(), meters, Azimuth.fromBearing(this.getBearing()));
this.setCurrentPosition(newPosition);
GPSCoordinate newPosition = GPSCoordinate.calculateNewPosition(this.getPosition(), meters, Azimuth.fromBearing(this.getBearing()));
this.setPosition(newPosition);
}
@@ -219,7 +215,7 @@ public class MockBoat extends Boat {
* @return true if mark is on port side
*/
public boolean isPortSide(Mark mark){
Bearing towardsMark = GPSCoordinate.calculateBearing(this.getCurrentPosition(), mark.getPosition());
Bearing towardsMark = GPSCoordinate.calculateBearing(this.getPosition(), mark.getPosition());
if (towardsMark.degrees() > 315 || towardsMark.degrees() <= 45){
//south quadrant
return this.getBearing().degrees() <= 180;
@@ -245,7 +241,7 @@ public class MockBoat extends Boat {
*/
public boolean isStarboardSide(Mark mark){
//if this boat is lower than the mark check which way it is facing
Bearing towardsMark = GPSCoordinate.calculateBearing(this.getCurrentPosition(), mark.getPosition());
Bearing towardsMark = GPSCoordinate.calculateBearing(this.getPosition(), mark.getPosition());
if (towardsMark.degrees() > 315 || towardsMark.degrees() <= 45){
//south quadrant
return !(this.getBearing().degrees() <= 180);
@@ -297,12 +293,11 @@ public class MockBoat extends Boat {
this.roundingStatus = 0;
}
public boolean getAutoVMG(){
return autoVMG;
}
public void setAutoVMG(boolean autoVMG) {
this.autoVMG = autoVMG;
}
public boolean getAutoVMG(){
return autoVMG;
}
}
@@ -2,7 +2,6 @@ package mock.model;
import network.Messages.Enums.BoatStatusEnum;
import network.Messages.Enums.RaceStatusEnum;
import network.Messages.LatestMessages;
import shared.dataInput.BoatDataSource;
import shared.dataInput.RaceDataSource;
import shared.dataInput.RegattaDataSource;
@@ -29,8 +28,6 @@ public class MockRace extends Race {
*/
private List<MockBoat> boats;
/**
* A copy of the boundary list, except "shrunk" inwards by 50m.
*/
@@ -72,6 +69,8 @@ public class MockRace extends Race {
//Wind.
this.setWind(windGenerator.generateBaselineWind());
this.colliderRegistry.addAllColliders(boats);
}
/**
@@ -195,7 +194,7 @@ public class MockRace extends Race {
boat.setCurrentSpeed(0d);
//Place the boat at its starting position.
boat.setCurrentPosition(startPosition);
boat.setPosition(startPosition);
//Boats start facing their next marker.
boat.setBearing(boat.calculateBearingToNextMarker());
@@ -400,7 +399,7 @@ public class MockRace extends Race {
Bearing bearing = Bearing.fromDegrees(angle);
//Check that if it is acceptable.
boolean bearingIsGood = this.checkBearingInsideCourse(bearing, boat.getCurrentPosition());
boolean bearingIsGood = this.checkBearingInsideCourse(bearing, boat.getPosition());
if (lastAngle != -1) {
@@ -475,7 +474,7 @@ public class MockRace extends Race {
case 0://hasn't started rounding
if (boat.isPortSide(roundingMark) &&
GPSCoordinate.passesLine(roundingMark.getPosition(),
roundingChecks.get(0), boat.getCurrentPosition(), legBearing) &&
roundingChecks.get(0), boat.getPosition(), legBearing) &&
gateCheck && boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(0)))) {
boat.increaseRoundingStatus();
if (boat.getCurrentLeg().getLegNumber() + 2 >= legs.size()){
@@ -487,7 +486,7 @@ public class MockRace extends Race {
case 1://has been parallel to the mark;
if (boat.isPortSide(roundingMark) &&
GPSCoordinate.passesLine(roundingMark.getPosition(),
roundingChecks.get(1), boat.getCurrentPosition(),
roundingChecks.get(1), boat.getPosition(),
Bearing.fromDegrees(legBearing.degrees() - 90)) &&//negative 90 from bearing because of port rounding
boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(1)))) {
boat.increaseRoundingStatus();
@@ -519,7 +518,7 @@ public class MockRace extends Race {
case 0://hasn't started rounding
if (boat.isStarboardSide(roundingMark) &&
GPSCoordinate.passesLine(roundingMark.getPosition(),
roundingChecks.get(0), boat.getCurrentPosition(), legBearing) &&
roundingChecks.get(0), boat.getPosition(), legBearing) &&
gateCheck &&
boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(0)))) {
boat.increaseRoundingStatus();
@@ -532,7 +531,7 @@ public class MockRace extends Race {
case 1://has been parallel to the mark
if (boat.isStarboardSide(roundingMark) &&
GPSCoordinate.passesLine(roundingMark.getPosition(),
roundingChecks.get(1), boat.getCurrentPosition(), Bearing.fromDegrees(legBearing.degrees() + 90)) && //positive 90 from bearing because of starboard rounding
roundingChecks.get(1), boat.getPosition(), Bearing.fromDegrees(legBearing.degrees() + 90)) && //positive 90 from bearing because of starboard rounding
boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(1)))) {
boat.increaseRoundingStatus();
}
@@ -1,6 +1,8 @@
package mock.model;
import javafx.animation.AnimationTimer;
import mock.model.collider.Collision;
import mock.model.commandFactory.Command;
import mock.model.commandFactory.CompositeCommand;
import mock.model.commandFactory.CommandFactory;
import network.Messages.Enums.BoatActionEnum;
@@ -9,8 +11,11 @@ import network.Messages.Enums.RaceStatusEnum;
import network.Messages.LatestMessages;
import shared.model.RunnableWithFramePeriod;
import java.util.Observable;
import java.util.Observer;
public class RaceLogic implements RunnableWithFramePeriod {
public class RaceLogic implements RunnableWithFramePeriod, Observer {
/**
* State of current race modified by this object
*/
@@ -34,6 +39,8 @@ public class RaceLogic implements RunnableWithFramePeriod {
this.race = race;
this.server = new RaceServer(race, messages);
this.commands = compositeCommand;
race.getColliderRegistry().addObserver(this);
}
/**
@@ -130,7 +137,7 @@ public class RaceLogic implements RunnableWithFramePeriod {
//If it is still racing, update its position.
if (boat.getStatus() == BoatStatusEnum.RACING) {
race.updatePosition(boat, framePeriod, race.getRaceClock().getDurationMilli());
race.getColliderRegistry().rayCast(boat);
}
}
@@ -182,4 +189,14 @@ public class RaceLogic implements RunnableWithFramePeriod {
public MockRace getRace() {
return race;
}
@Override
public void update(Observable o, Object arg) {
Collision e = (Collision)arg;
if(e.getBearing().degrees() == 0) System.out.println("Ahead");
else if(e.getBearing().degrees() < 90) System.out.println("Starboard");
else if(e.getBearing().degrees() > 270) System.out.println("Port");
else System.out.println("Behind");
}
}
@@ -2,10 +2,8 @@ package mock.model;
import network.Messages.*;
import network.Messages.Enums.BoatLocationDeviceEnum;
import network.Utils.AC35UnitConverter;
import shared.model.Bearing;
import shared.model.CompoundMark;
import shared.model.Constants;
import shared.model.Mark;
import java.util.ArrayList;
@@ -30,7 +28,6 @@ public class RaceServer {
this.latestMessages = latestMessages;
}
/**
* Parses the race to create a snapshot, and places it in latestMessages.
*/
@@ -127,8 +124,8 @@ public class RaceServer {
BoatLocation boatLocation = new BoatLocation(
boat.getSourceID(),
boat.getCurrentPosition().getLatitude(),
boat.getCurrentPosition().getLongitude(),
boat.getPosition().getLatitude(),
boat.getPosition().getLongitude(),
this.boatLocationSequenceNumber,
BoatLocationDeviceEnum.RacingYacht,
boat.getBearing(),
@@ -0,0 +1,52 @@
package mock.model.collider;
import shared.model.Bearing;
import shared.model.Boat;
import shared.model.GPSCoordinate;
import shared.model.Locatable;
import java.util.Observable;
/**
* Interface for all objects sensitive to collision in a race.
*/
public abstract class Collider extends Observable implements Locatable {
/**
* Indicates whether a ray cast from a boat to a target collider is within the specified length.
* @param boat potentially colliding with target
* @param distance distance for valid collision
* @return whether or not a collision has occurred
*/
public boolean rayCast(Boat boat, double distance) {
double actualDistance = GPSCoordinate.calculateDistanceMeters(boat.getPosition(), this.getPosition());
// Compass direction of collider
Bearing absolute = Bearing.fromAzimuth(GPSCoordinate.calculateAzimuth(boat.getPosition(), this.getPosition()));
// Direction of collider from heading
Bearing relative = Bearing.fromDegrees(absolute.degrees() - boat.getBearing().degrees());
if(actualDistance <= distance) {
Collision collision = new Collision(relative, distance);
// Notify object of collision
onCollisionEnter(boat, collision);
// Notify observers of collision
notifyObservers(collision);
this.setChanged();
return true;
} else return false;
}
/**
* Indicates whether a ray cast from a boat to a target collider triggers a collision. Distance is set by the object.
* @param boat potentially colliding with target
* @return whether or not a collision has occurred
*/
public abstract boolean rayCast(Boat boat);
/**
* Handle a collision event
* @param collider Boat that is colliding
* @param e details of collision
*/
public abstract void onCollisionEnter(Boat collider, Collision e);
}
@@ -0,0 +1,66 @@
package mock.model.collider;
import shared.model.Boat;
import shared.model.GPSCoordinate;
import java.util.*;
/**
* Registry for all Collider objects in a MockRace. Wraps the Collider interface as part of a Composite Pattern.
*/
public class ColliderRegistry extends Collider implements Observer {
/**
* List of all registered Colliders
*/
private List<Collider> colliders;
/**
* Default constructor for ColliderRegistry
*/
public ColliderRegistry() {
this.colliders = new ArrayList<>();
}
public void addCollider(Collider collider) {
collider.addObserver(this);
colliders.add(collider);
}
public void addAllColliders(Collection<? extends Collider> colliders) {
for(Collider collider: colliders) addCollider(collider);
}
@Override
public boolean rayCast(Boat boat) {
for(Collider collider: colliders) {
if(collider.rayCast(boat)) return true;
}
return false;
}
@Override
public void onCollisionEnter(Boat collider, Collision e) {}
@Override
public GPSCoordinate getPosition() {
return null;
}
@Override
public void setPosition(GPSCoordinate position) {
}
/**
* Fire onCollisionEnter when collision bubbles up from registered colliders.
* @param o object collided with
* @param arg parameters of the collision
*/
@Override
public void update(Observable o, Object arg) {
Collision collision = (Collision)arg;
notifyObservers(collision);
this.setChanged();
}
}
@@ -0,0 +1,35 @@
package mock.model.collider;
import shared.model.Bearing;
/**
* Data structure for holding collision details for ray casting and event handling.
*/
public class Collision {
/**
* Bearing from boat heading to target
*/
private Bearing bearing;
/**
* Distance from boat centre to target centre
*/
private double distance;
/**
* Constructor for Collision structure
* @param bearing from boat heading to target
* @param distance from boat centre to target centre
*/
public Collision(Bearing bearing, double distance) {
this.bearing = bearing;
this.distance = distance;
}
public Bearing getBearing() {
return bearing;
}
public double getDistance() {
return distance;
}
}