mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-17 01:31:01 +00:00
I've fixed the computation of the total time of the polyline.
This commit is contained in:
1 parent
91853b77ce
commit
6933c050d1
3 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);
|
||||
|
||||
|
||||
Reference in new issue
Block a user