This is a followup to this question.
I seem to be stuck on this. Basically, I need to be able to convert back and forth to referring to coordinates either in the standard degree system OR by measuring a distance north from the south pole along the international date line, and then a distance east starting from that point on the date line. To do this (as well as some more general distance-measuring stuff), I have one method for determining the distance between two lat/lon points, and another method that takes a lat/lon point, a heading and a distance, and returns the lat/lon point at the end of that course.
Here are the two static methods I've defined:
/* Takes two lon/lat pairs and returns the distance between them in kilometers.
*/
public static double distance (double lat1, double lon1, double lat2, double lon2) {
double theta = toRadians(lon1-lon2);
lat1 = toRadians(lat1);
lon1 = toRadians(lon1);
lat2 = toRadians(lat2);
lon2 = toRadians(lon2);
double dist = sin(lat1)*sin(lat2) + cos(lat1)*cos(lat2)*cos(theta);
dist = toDegrees(acos(dist)) * 60 * 1.1515 * 1.609344 * 1000;
return dist;
}
/* endOfCourse takes a lat/lon pair, a heading (in degrees clockwise from north), and a distance (in kilometers), and returns
* the lat/lon pair that would be reached by traveling that distance in that direction from the given point.
*/
public static double[] endOfCourse (double lat1, double lon1, double tc, double dist) {
double pi = Math.PI;
lat1 = toRadians(lat1);
lon1 = toRadians(lon1);
tc = toRadians(tc);
double dist_radians = toRadians(dist / (60 * 1.1515 * 1.609344 * 1000));
double lat = asin(sin(lat1) * cos(dist_radians) + cos(lat1) * sin(dist_radians) * cos(tc));
double dlon = atan2(sin(tc) * sin(dist_radians) * cos(lat1), cos(dist_radians) - sin(lat1) * sin(lat));
double lon = ((lon1-dlon + pi) % (2*pi)) - pi;
double[] endPoint = new double[2];
endPoint[0] = lat; endPoint[1] = lon;
return endPoint;
}
And here's the function I'm using to test it:
public static void main(String args[]) throws java.io.IOException, java.io.FileNotFoundException {
double distNorth = distance(0.0, 0.0, 72.0, 0.0);
double distEast = distance(72.0, 0.0, 72.0, 31.5);
double lat1 = endOfCourse(0.0, 0.0, 0.0, distNorth)[0];
double lon1 = endOfCourse(lat1, 0.0, 90.0, distEast)[1];
System.out.println("end at: " + lat1 + " / " + lon1);
return;
}
The "end at" values should be appx. 72.0 / 31.5. But instead I'm getting approximately 1.25 / 0.021.
I assume I must be missing something stupid, forgetting to convert units somewhere, or something... Any help would be greatly appreciated!!
UPDATE:
OK, I had (correctly) written the distance function to return meters, but wrote kilometers in the comments by mistake ... which of course confused me when I came back to it today :) Anyway, now that's fixed, and I've fixed the factoring error in the endOfCourse method, and I also realized I'd forgotten to convert back to degrees from radians in that method too. Anyway: while it appears I'm now getting the correct latitude number (71.99...), the longitude number is way off (I get 3.54 instead of 11.5).
UPDATE 2: I had a typo in the test, as mentioned below. It's now fixed in the code. The longitude number is still, however, wrong: I'm now getting -11.34 instead of 11.5. I think there must be something wrong with these lines:
double dlon = atan2(sin(tc) * sin(dist_radians) * cos(lat1), cos(dist_radians) - sin(lat1) * sin(lat));
double lon = ((lon1-dlon + pi) % (2*pi)) - pi;
Thanks, -Dan