I've fixed the computation of the total time of the polyline.

This commit is contained in:
I077899 committed 2012-12-03 14:02:00 +02:00
1 parent 91853b77ce
commit 6933c050d1
3 files changed
+67 -98

No files matched your search

@@ -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);
}
}
@@ -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));
}
}
@@ -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);