mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-17 01:31:01 +00:00
Merge remote-tracking branch 'origin/simulator_dev' into simulator_dev
This commit is contained in:
commit
5d3b039820
11 files changed
+67
-98
No files matched your search
+18
-38
@@ -20,9 +20,9 @@ import com.sap.sailing.gwt.ui.shared.PathDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.PositionDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.ReceivePolarDiagramDataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RequestPolarDiagramDataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SimulatorWindDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SpeedBearingPositionDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SpeedWithBearingDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SimulatorWindDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.racemap.TwoDPoint;
|
||||
import com.sap.sailing.gwt.ui.shared.racemap.TwoDSegment;
|
||||
import com.sap.sailing.gwt.ui.shared.racemap.TwoDVector;
|
||||
@@ -43,8 +43,8 @@ public class PathPolyline {
|
||||
private static final String DEFAULT_DASHLINE_BISECTOR_COLOR = "Green";
|
||||
private static final String DEFAULT_DASHLINE_VERTICAL_COLOR = "Blue";
|
||||
|
||||
private static final double STEP_DURATION_MILLISECONDS = 1000;
|
||||
private static final boolean USE_DAMPENED_VALUES = false;
|
||||
// private static final double STEP_DURATION_MILLISECONDS = 1000;
|
||||
private static final double STEP_SIZE_METERS = 5.0;
|
||||
private static final boolean USE_ONLY_TURN_POINTS = false;
|
||||
|
||||
private Polyline polyline;
|
||||
@@ -68,7 +68,8 @@ public class PathPolyline {
|
||||
private boolean warningAlreadyShown = false;
|
||||
|
||||
private boolean firstTime = true;
|
||||
private double stepSizeMeters = 0.0;
|
||||
|
||||
// private double stepSizeMeters = 5.0;
|
||||
|
||||
// private static Logger logger = Logger.getLogger(PathPolyline.class.getName());
|
||||
|
||||
@@ -190,7 +191,8 @@ public class PathPolyline {
|
||||
if (this.firstTime) {
|
||||
|
||||
this.averageWindSpeed = this.getAverageWindSpeed();
|
||||
this.stepSizeMeters = PathPolylineUtils.convertFromKnotsToMPS(this.averageWindSpeed.speedInKnots) * (STEP_DURATION_MILLISECONDS / 1000);
|
||||
// this.stepSizeMeters = PathPolylineUtils.knotsToMetersPerSecond(this.averageWindSpeed.speedInKnots) *
|
||||
// (STEP_DURATION_MILLISECONDS / 1000);
|
||||
this.firstTime = false;
|
||||
}
|
||||
|
||||
@@ -357,24 +359,13 @@ public class PathPolyline {
|
||||
warningAlreadyShown = true;
|
||||
}
|
||||
|
||||
// final List<PositionDTO> positions = requestData.getPositions();
|
||||
final List<SpeedBearingPositionDTO> speeds = receiveData.getSpeedsBearingsPositions();
|
||||
|
||||
// int counter = 0;
|
||||
// for (final SpeedBearingPositionDTO speed : speeds) {
|
||||
// counter++;
|
||||
// System.err.println("Position " + counter + ": " + speed.getPosition().latDeg + "," +
|
||||
// speed.getPosition().lngDeg + " and speed = "
|
||||
// + PathPolylineUtils.convertFromKnotsToMPS(speed.getSpeedWithBearing().speedInKnots));
|
||||
// }
|
||||
|
||||
final int noOfSpeeds = speeds.size();
|
||||
|
||||
SpeedBearingPositionDTO startSpeedAndPosition = null;
|
||||
SpeedBearingPositionDTO endSpeedAndPosition = null;
|
||||
LatLng startPoint = null;
|
||||
LatLng endPoint = null;
|
||||
double startSpeed = 0.0;
|
||||
double endSpeed = 0.0;
|
||||
double totalTime = 0.0;
|
||||
|
||||
@@ -389,20 +380,18 @@ public class PathPolyline {
|
||||
|
||||
startPoint = convertToLatLng(startSpeedAndPosition.getPosition());
|
||||
endPoint = convertToLatLng(endSpeedAndPosition.getPosition());
|
||||
endSpeed = PathPolylineUtils.knotsToMetersPerSecond(endSpeedAndPosition.getSpeedWithBearing().speedInKnots);
|
||||
|
||||
startSpeed = PathPolylineUtils.convertFromKnotsToMPS(startSpeedAndPosition.getSpeedWithBearing().speedInKnots);
|
||||
endSpeed = PathPolylineUtils.convertFromKnotsToMPS(endSpeedAndPosition.getSpeedWithBearing().speedInKnots);
|
||||
|
||||
//
|
||||
|
||||
final double time = PathPolylineUtils.getTime(startPoint, startSpeed, endPoint, endSpeed);
|
||||
final double distance = PathPolylineUtils.getDistanceBetween(startPoint, endPoint);
|
||||
System.err.println("ZZZ: Segment no " + index + " distance=" + distance + " time=" + time);
|
||||
totalTime += PathPolylineUtils.getTime(startPoint, startSpeed, endPoint, endSpeed);
|
||||
totalTime += PathPolylineUtils.getTime(startPoint, endPoint, endSpeed);
|
||||
}
|
||||
|
||||
System.err.println("==================================================");
|
||||
System.err.println("Total time of the path polyline is " + totalTime + " seconds!");
|
||||
System.err.println("total distance = " + PathPolylineUtils.getTotalDistanceMeters(points) + " meters");
|
||||
System.err.println("step size = " + STEP_SIZE_METERS + " meters");
|
||||
System.err.println("average wind speed = " + PathPolylineUtils.knotsToMetersPerSecond(averageWindSpeed.speedInKnots) + " meters/second");
|
||||
System.err.println("total time = " + totalTime + " seconds!");
|
||||
System.err.println("==================================================");
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -410,8 +399,8 @@ public class PathPolyline {
|
||||
private SpeedWithBearingDTO getAverageWindSpeed() {
|
||||
|
||||
final List<SimulatorWindDTO> windDTOs = this.pathDTO.getMatrix();
|
||||
// PathPolylineUtils.computeMinMaxAverageWindSpeed(windDTOs, USE_DAMPENED_VALUES)
|
||||
return PathPolylineUtils.computeAverageWindSpeed(windDTOs, USE_DAMPENED_VALUES);
|
||||
// PathPolylineUtils.computeMinMaxAverageWindSpeed(windDTOs)
|
||||
return PathPolylineUtils.computeAverageWindSpeed(windDTOs);
|
||||
}
|
||||
|
||||
private RequestPolarDiagramDataDTO createRequestPolarDiagramDataDTO() {
|
||||
@@ -423,20 +412,11 @@ public class PathPolyline {
|
||||
positions.add(new PositionDTO(point.getLatitude(), point.getLongitude()));
|
||||
}
|
||||
} else {
|
||||
for (final LatLng point : PathPolylineUtils.getIntermediatePoints(this.points, this.stepSizeMeters)) {
|
||||
for (final LatLng point : PathPolylineUtils.getIntermediatePoints(this.points, STEP_SIZE_METERS)) {
|
||||
positions.add(new PositionDTO(point.getLatitude(), point.getLongitude()));
|
||||
}
|
||||
}
|
||||
|
||||
System.err.println("==================================================");
|
||||
System.err.println("total distance of path = " + PathPolylineUtils.getTotalDistanceMeters(this.points) + " meters");
|
||||
System.err.println("step size = " + stepSizeMeters + " meters");
|
||||
System.err.println("average wind speed = " + PathPolylineUtils.convertFromKnotsToMPS(this.averageWindSpeed.speedInKnots) + " meters/second");
|
||||
System.err.println("total points = " + positions.size());
|
||||
System.err.println("==================================================");
|
||||
|
||||
this.averageWindSpeed = new SpeedWithBearingDTO(4, this.averageWindSpeed.bearingInDegrees);
|
||||
|
||||
return new RequestPolarDiagramDataDTO(this.boatClassID, positions, this.averageWindSpeed);
|
||||
}
|
||||
}
|
||||
+47
-58
@@ -4,62 +4,68 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.maps.client.geom.LatLng;
|
||||
import com.sap.sailing.gwt.ui.shared.SpeedWithBearingDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SimulatorWindDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SpeedWithBearingDTO;
|
||||
|
||||
public class PathPolylineUtils {
|
||||
|
||||
public static final double EARTH_RADIUS_METERS = 6378137;
|
||||
public static final double factor_kn2mps = 0.514444;
|
||||
public static final double FACTOR_DEG2RAD = 0.0174532925;
|
||||
public static final double FACTOR_RAD2DEG = 57.2957795;
|
||||
public static final double FACTOR_KN2MPS = 0.514444;
|
||||
public static final double FACTOR_MPS2KN = 1.94384;
|
||||
|
||||
public static double convertFromDegToRad(final double noOfDegrees) {
|
||||
return (noOfDegrees * 0.0174532925);
|
||||
|
||||
public static double degreesToRadians(final double noOfDegrees) {
|
||||
return (noOfDegrees * FACTOR_DEG2RAD);
|
||||
}
|
||||
|
||||
public static double convertFromRadToDeg(final double noOfRadians) {
|
||||
return (noOfRadians * 57.2957795);
|
||||
public static double radiansToDegrees(final double noOfRadians) {
|
||||
return (noOfRadians * FACTOR_RAD2DEG);
|
||||
}
|
||||
|
||||
public static double convertFromKnotsToMPS(final double knots) {
|
||||
return knots * factor_kn2mps;
|
||||
public static double knotsToMetersPerSecond(final double knots) {
|
||||
return knots * FACTOR_KN2MPS;
|
||||
}
|
||||
|
||||
public static double convertFromMPSToKnots(final double mps) {
|
||||
return mps / factor_kn2mps;
|
||||
public static double metersPerSecondKnots(final double mps) {
|
||||
return mps * FACTOR_MPS2KN;
|
||||
}
|
||||
|
||||
public static SpeedWithBearingDTO computeAverageWindSpeed(final List<SimulatorWindDTO> windDTOs, final boolean useDampenedValues) {
|
||||
public static SpeedWithBearingDTO computeAverageWindSpeed(final List<SimulatorWindDTO> windDTOs) {
|
||||
|
||||
final int count = windDTOs.size();
|
||||
|
||||
double sumOfProductOfSpeedAndCosBearing = 0.0;
|
||||
double sumOfProductOfSpeedAndSinBearing = 0.0;
|
||||
double windSpeedKnots = 0.0;
|
||||
double windBearingDegrees = 0.0;
|
||||
double windBearingRadians = 0.0;
|
||||
|
||||
for (final SimulatorWindDTO windDTO : windDTOs) {
|
||||
|
||||
windSpeedKnots = windDTO.trueWindSpeedInKnots; //useDampenedValues ? windDTO.dampenedTrueWindSpeedInKnots : windDTO.trueWindSpeedInKnots;
|
||||
windBearingDegrees = windDTO.trueWindBearingDeg; //useDampenedValues ? windDTO.dampenedTrueWindBearingDeg : windDTO.trueWindBearingDeg;
|
||||
windBearingRadians = PathPolylineUtils.convertFromDegToRad(windBearingDegrees);
|
||||
windBearingRadians = degreesToRadians(windDTO.trueWindBearingDeg);
|
||||
|
||||
sumOfProductOfSpeedAndCosBearing += (windSpeedKnots * Math.cos(windBearingRadians));
|
||||
sumOfProductOfSpeedAndSinBearing += (windSpeedKnots * Math.sin(windBearingRadians));
|
||||
sumOfProductOfSpeedAndCosBearing += (windDTO.trueWindSpeedInKnots * Math.cos(windBearingRadians));
|
||||
sumOfProductOfSpeedAndSinBearing += (windDTO.trueWindSpeedInKnots * Math.sin(windBearingRadians));
|
||||
}
|
||||
|
||||
final double a = sumOfProductOfSpeedAndCosBearing / count;
|
||||
final double b = sumOfProductOfSpeedAndSinBearing / count;
|
||||
final double c = Math.atan(b / a);
|
||||
final double a = sumOfProductOfSpeedAndSinBearing / count;
|
||||
final double b = sumOfProductOfSpeedAndCosBearing / count;
|
||||
final double c = radiansToDegrees(Math.atan(Math.abs(b / a)));
|
||||
|
||||
double averageBearing = 0.0;
|
||||
|
||||
if (a == 0) {
|
||||
averageBearing = (b >= 0) ? 90 : 270;
|
||||
} else if (a < 0) { // 2nd Q : 3rd Q
|
||||
averageBearing = 180 + c;
|
||||
} else if (a > 0) {
|
||||
averageBearing = (b >= 0) ? c : 360 + c; // 1st Q : 4th Q
|
||||
if (a > 0) {
|
||||
averageBearing = c;
|
||||
} else if (a < 0) {
|
||||
averageBearing = c - 180;
|
||||
} else if (a == 0) {
|
||||
if (b > 0) {
|
||||
averageBearing = 180;
|
||||
} else if (b < 0) {
|
||||
averageBearing = -180;
|
||||
} else {
|
||||
// undefined
|
||||
}
|
||||
}
|
||||
|
||||
final double averageSpeed = Math.sqrt(a * a + b * b);
|
||||
@@ -67,7 +73,7 @@ public class PathPolylineUtils {
|
||||
return new SpeedWithBearingDTO(averageSpeed, averageBearing);
|
||||
}
|
||||
|
||||
public static SpeedWithBearingDTO computeMinMaxAverageWindSpeed(final List<SimulatorWindDTO> windDTOs, final boolean useDampenedValues) {
|
||||
public static SpeedWithBearingDTO computeMinMaxAverageWindSpeed(final List<SimulatorWindDTO> windDTOs) {
|
||||
|
||||
SimulatorWindDTO minWindDTO = windDTOs.get(0);
|
||||
SimulatorWindDTO maxWindDTO = windDTOs.get(0);
|
||||
@@ -78,31 +84,17 @@ public class PathPolylineUtils {
|
||||
|
||||
currentWindDTO = windDTOs.get(index);
|
||||
|
||||
/* if (useDampenedValues) {
|
||||
if (currentWindDTO.dampenedTrueWindSpeedInKnots < minWindDTO.dampenedTrueWindSpeedInKnots) {
|
||||
minWindDTO = currentWindDTO;
|
||||
}
|
||||
if (currentWindDTO.trueWindSpeedInKnots < minWindDTO.trueWindSpeedInKnots) {
|
||||
minWindDTO = currentWindDTO;
|
||||
}
|
||||
|
||||
if (currentWindDTO.dampenedTrueWindSpeedInKnots > maxWindDTO.dampenedTrueWindSpeedInKnots) {
|
||||
maxWindDTO = currentWindDTO;
|
||||
}
|
||||
} else {*/
|
||||
if (currentWindDTO.trueWindSpeedInKnots < minWindDTO.trueWindSpeedInKnots) {
|
||||
minWindDTO = currentWindDTO;
|
||||
}
|
||||
|
||||
if (currentWindDTO.trueWindSpeedInKnots > maxWindDTO.trueWindSpeedInKnots) {
|
||||
maxWindDTO = currentWindDTO;
|
||||
}
|
||||
//}
|
||||
if (currentWindDTO.trueWindSpeedInKnots > maxWindDTO.trueWindSpeedInKnots) {
|
||||
maxWindDTO = currentWindDTO;
|
||||
}
|
||||
}
|
||||
|
||||
final double speedInKnots = ((minWindDTO.trueWindSpeedInKnots + maxWindDTO.trueWindSpeedInKnots) / 2);
|
||||
//useDampenedValues ? ((minWindDTO.dampenedTrueWindSpeedInKnots + maxWindDTO.dampenedTrueWindSpeedInKnots) / 2)
|
||||
// : ((minWindDTO.trueWindSpeedInKnots + maxWindDTO.trueWindSpeedInKnots) / 2);
|
||||
final double bearingInDegrees = ((minWindDTO.trueWindBearingDeg + maxWindDTO.trueWindBearingDeg) / 2);
|
||||
//useDampenedValues ? ((minWindDTO.dampenedTrueWindBearingDeg + maxWindDTO.dampenedTrueWindBearingDeg) / 2)
|
||||
// : ((minWindDTO.trueWindBearingDeg + maxWindDTO.trueWindBearingDeg) / 2);
|
||||
final double bearingInDegrees = ((minWindDTO.trueWindBearingDeg + maxWindDTO.trueWindBearingDeg) / 2);
|
||||
|
||||
return new SpeedWithBearingDTO(speedInKnots, bearingInDegrees);
|
||||
}
|
||||
@@ -167,8 +159,7 @@ public class PathPolylineUtils {
|
||||
|
||||
}
|
||||
|
||||
public static double getTime(final LatLng startPoint, final double startSpeedMetersPerSecond, final LatLng endPoint,
|
||||
final double endSpeedMetersPerSecond) {
|
||||
public static double getTime(final LatLng startPoint, final LatLng endPoint, final double endSpeedMetersPerSecond) {
|
||||
|
||||
final double distance = getDistanceBetween(startPoint, endPoint);
|
||||
|
||||
@@ -176,9 +167,7 @@ public class PathPolylineUtils {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 2 * distance / (startSpeedMetersPerSecond + endSpeedMetersPerSecond);
|
||||
return distance / endSpeedMetersPerSecond;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,7 +230,7 @@ public class PathPolylineUtils {
|
||||
final double x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
|
||||
final double bearing = Math.atan2(y, x);
|
||||
|
||||
return (convertFromRadToDeg(bearing) + 360) % 360;
|
||||
return (radiansToDegrees(bearing) + 360) % 360;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,7 +248,7 @@ public class PathPolylineUtils {
|
||||
final double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
|
||||
final double bearing = Math.atan2(y, x);
|
||||
|
||||
return (convertFromRadToDeg(bearing) + 180) % 360;
|
||||
return (radiansToDegrees(bearing) + 180) % 360;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -290,7 +279,7 @@ public class PathPolylineUtils {
|
||||
public static LatLng getDestinationPoint(final LatLng startPoint, final double bearingDegrees, final double distanceMeters) {
|
||||
|
||||
final double distance = distanceMeters / EARTH_RADIUS_METERS;
|
||||
final double bearing = convertFromDegToRad(bearingDegrees);
|
||||
final double bearing = degreesToRadians(bearingDegrees);
|
||||
final double lat1 = startPoint.getLatitudeRadians();
|
||||
final double lon1 = startPoint.getLongitudeRadians();
|
||||
|
||||
@@ -298,6 +287,6 @@ public class PathPolylineUtils {
|
||||
double lon2 = lon1 + Math.atan2(Math.sin(bearing) * Math.sin(distance) * Math.cos(lat1), Math.cos(distance) - Math.sin(lat1) * Math.sin(lat2));
|
||||
lon2 = (lon2 + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
|
||||
|
||||
return LatLng.newInstance(convertFromRadToDeg(lat2), convertFromRadToDeg(lon2));
|
||||
return LatLng.newInstance(radiansToDegrees(lat2), radiansToDegrees(lon2));
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -153,8 +153,8 @@ public class WindFieldCanvasOverlay extends FullCanvasOverlay implements TimeLis
|
||||
|
||||
protected void drawScaledArrow(SimulatorWindDTO windDTO, double angle, int index, boolean drawHead) {
|
||||
|
||||
double aWidth = Math.max(1., (PathPolylineUtils.convertFromKnotsToMPS(windDTO.trueWindSpeedInKnots)/2.));
|
||||
double aLength = Math.max(10., (4.*PathPolylineUtils.convertFromKnotsToMPS(windDTO.trueWindSpeedInKnots)));
|
||||
double aWidth = Math.max(1., (PathPolylineUtils.knotsToMetersPerSecond(windDTO.trueWindSpeedInKnots)/2.));
|
||||
double aLength = Math.max(10., (4.*PathPolylineUtils.knotsToMetersPerSecond(windDTO.trueWindSpeedInKnots)));
|
||||
//System.out.println("arrow speed: "+windDTO.trueWindSpeedInMetersPerSecond+" angle:"+angle+" aWidth: "+aWidth+" aLength: "+aLength);
|
||||
drawArrow(windDTO, angle, aLength, aWidth, index, drawHead);
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in new issue
Block a user