mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Merge remote-tracking branch 'origin/develop' into Story62_Reading_Keystrokes
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
package seng302.server.simulator;
|
||||
|
||||
import seng302.server.simulator.mark.Corner;
|
||||
import seng302.server.simulator.mark.Position;
|
||||
import seng302.utilities.GeoPoint;
|
||||
import seng302.utilities.GeoUtility;
|
||||
|
||||
public class Boat {
|
||||
|
||||
@@ -29,8 +30,8 @@ public class Boat {
|
||||
*/
|
||||
public void move(double heading, double duration) {
|
||||
Double distance = speed * duration / 1000000; // convert mm to meter
|
||||
Position originPos = new Position(lat, lng);
|
||||
Position newPos = GeoUtility.getGeoCoordinate(originPos, heading, distance);
|
||||
GeoPoint originPos = new GeoPoint(lat, lng);
|
||||
GeoPoint newPos = GeoUtility.getGeoCoordinate(originPos, heading, distance);
|
||||
this.lat = newPos.getLat();
|
||||
this.lng = newPos.getLng();
|
||||
}
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
package seng302.server.simulator;
|
||||
|
||||
import seng302.server.simulator.mark.Position;
|
||||
|
||||
public class GeoUtility {
|
||||
|
||||
private static double EARTH_RADIUS = 6378.137;
|
||||
|
||||
/**
|
||||
* Calculates the euclidean distance between two markers on the canvas using xy coordinates
|
||||
*
|
||||
* @param p1 first geographical position
|
||||
* @param p2 second geographical position
|
||||
* @return the distance in meter between two points in meters
|
||||
*/
|
||||
public static Double getDistance(Position p1, Position p2) {
|
||||
|
||||
double dLat = Math.toRadians(p2.getLat() - p1.getLat());
|
||||
double dLon = Math.toRadians(p2.getLng() - p1.getLng());
|
||||
|
||||
double a = Math.pow(Math.sin(dLat / 2), 2.0)
|
||||
+ Math.cos(Math.toRadians(p1.getLat())) * Math.cos(Math.toRadians(p2.getLat()))
|
||||
* Math.pow(Math.sin(dLon / 2), 2.0);
|
||||
|
||||
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||||
double d = EARTH_RADIUS * c;
|
||||
|
||||
return d * 1000; // distance from km to meter
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the angle between to angular co-ordinates on a sphere.
|
||||
*
|
||||
* @param p1 the first geographical position, start point
|
||||
* @param p2 the second geographical position, end point
|
||||
* @return the initial bearing in degree from p1 to p2, value range (0 ~ 360 deg.).
|
||||
* vertical up is 0 deg. horizontal right is 90 deg.
|
||||
*
|
||||
* NOTE:
|
||||
* The final bearing will differ from the initial bearing by varying degrees
|
||||
* according to distance and latitude (if you were to go from say 35°N,45°E
|
||||
* (≈ Baghdad) to 35°N,135°E (≈ Osaka), you would start on a heading of 60°
|
||||
* and end up on a heading of 120°
|
||||
*/
|
||||
public static Double getBearing(Position p1, Position p2) {
|
||||
|
||||
double dLon = Math.toRadians(p2.getLng() - p1.getLng());
|
||||
|
||||
double y = Math.sin(dLon) * Math.cos(Math.toRadians(p2.getLat()));
|
||||
double x = Math.cos(Math.toRadians(p1.getLat())) * Math.sin(Math.toRadians(p2.getLat()))
|
||||
- Math.sin(Math.toRadians(p1.getLat())) * Math.cos(Math.toRadians(p2.getLat())) * Math.cos(dLon);
|
||||
|
||||
double bearing = Math.toDegrees(Math.atan2(y, x));
|
||||
|
||||
return (bearing + 360.0) % 360.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an existing point in lat/lng, distance in (in meter) and bearing
|
||||
* (in degrees), calculates the new lat/lng.
|
||||
*
|
||||
* @param origin the original position within lat / lng
|
||||
* @param bearing the bearing in degree, from original position to the new position
|
||||
* @param distance the distance in meter, from original position to the new position
|
||||
* @return the new position
|
||||
*/
|
||||
public static Position getGeoCoordinate(Position origin, Double bearing, Double distance) {
|
||||
double b = Math.toRadians(bearing); // bearing to radians
|
||||
double d = distance / 1000.0; // distance to km
|
||||
|
||||
double originLat = Math.toRadians(origin.getLat());
|
||||
double originLng = Math.toRadians(origin.getLng());
|
||||
|
||||
double endLat = Math.asin(Math.sin(originLat) * Math.cos(d / EARTH_RADIUS)
|
||||
+ Math.cos(originLat) * Math.sin(d / EARTH_RADIUS) * Math.cos(b));
|
||||
double endLng = originLng
|
||||
+ Math.atan2(Math.sin(b) * Math.sin(d / EARTH_RADIUS) * Math.cos(originLat),
|
||||
Math.cos(d / EARTH_RADIUS) - Math.sin(originLat) * Math.sin(endLat));
|
||||
|
||||
return new Position(Math.toDegrees(endLat), Math.toDegrees(endLng));
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,9 @@ package seng302.server.simulator;
|
||||
|
||||
import seng302.server.simulator.mark.Corner;
|
||||
import seng302.server.simulator.mark.Mark;
|
||||
import seng302.server.simulator.mark.Position;
|
||||
import seng302.server.simulator.parsers.RaceParser;
|
||||
import seng302.utilities.GeoPoint;
|
||||
import seng302.utilities.GeoUtility;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
@@ -77,8 +78,8 @@ public class Simulator extends Observable implements Runnable {
|
||||
|
||||
boat.move(boat.getLastPassedCorner().getBearingToNextCorner(), duration);
|
||||
|
||||
Position boatPos = new Position(boat.getLat(), boat.getLng());
|
||||
Position lastMarkPos = boat.getLastPassedCorner().getCompoundMark().getMark1();
|
||||
GeoPoint boatPos = new GeoPoint(boat.getLat(), boat.getLng());
|
||||
GeoPoint lastMarkPos = boat.getLastPassedCorner().getCompoundMark().getMark1();
|
||||
|
||||
double distanceFromLastMark = GeoUtility.getDistance(boatPos, lastMarkPos);
|
||||
// if a boat passes its heading mark
|
||||
@@ -94,13 +95,13 @@ public class Simulator extends Observable implements Runnable {
|
||||
}
|
||||
|
||||
// move compensate distance for the mark just passed
|
||||
Position pos = GeoUtility.getGeoCoordinate(
|
||||
GeoPoint pos = GeoUtility.getGeoCoordinate(
|
||||
boat.getLastPassedCorner().getCompoundMark().getMark1(),
|
||||
boat.getLastPassedCorner().getBearingToNextCorner(),
|
||||
compensateDistance);
|
||||
boat.setLat(pos.getLat());
|
||||
boat.setLng(pos.getLng());
|
||||
distanceFromLastMark = GeoUtility.getDistance(new Position(boat.getLat(), boat.getLng()),
|
||||
distanceFromLastMark = GeoUtility.getDistance(new GeoPoint(boat.getLat(), boat.getLng()),
|
||||
boat.getLastPassedCorner().getCompoundMark().getMark1());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package seng302.server.simulator.mark;
|
||||
|
||||
import seng302.utilities.GeoPoint;
|
||||
|
||||
/**
|
||||
* An abstract class to represent general marks
|
||||
* Created by Haoming Yin (hyi25) on 17/3/17.
|
||||
*/
|
||||
public class Mark extends Position {
|
||||
public class Mark extends GeoPoint {
|
||||
|
||||
private int seqID;
|
||||
private String name;
|
||||
@@ -22,7 +24,7 @@ public class Mark extends Position {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Mark%d: %s, source: %d, lat: %f, lng: %f", seqID, name, sourceID, lat, lng);
|
||||
return String.format("Mark%d: %s, source: %d, lat: %f, lng: %f", seqID, name, sourceID, getLat(), getLng());
|
||||
}
|
||||
|
||||
public int getSeqID() {
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package seng302.server.simulator.mark;
|
||||
|
||||
public class Position {
|
||||
|
||||
double lat, lng;
|
||||
|
||||
public Position(double lat, double lng) {
|
||||
this.lat = lat;
|
||||
this.lng = lng;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format("Position at lat:%f lng:%f.", lat, lng);
|
||||
}
|
||||
|
||||
public double getLat() {
|
||||
return lat;
|
||||
}
|
||||
|
||||
public void setLat(double lat) {
|
||||
this.lat = lat;
|
||||
}
|
||||
|
||||
public double getLng() {
|
||||
return lng;
|
||||
}
|
||||
|
||||
public void setLng(double lng) {
|
||||
this.lng = lng;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user