What's Wrong with My Haversine Formula Calculation in C++?

  • Context: C/C++ 
  • Thread starter Thread starter perplexabot
  • Start date Start date
  • Tags Tags
    C++ Formula
Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
6 replies · 8K views
perplexabot
Gold Member
Messages
328
Reaction score
5
Hello all. So i am trying to calculate the distance between two points on the Earth's surface. Here is what I have:

Code:
                //calculate distance here
		dlat = abs(startLoc.lat - tarList[i].lat);
		dlon = abs(startLoc.lon - tarList[i].lon);
		a = pow(sin(dlat/2),2) + ( cos(startLoc.lat)*cos(tarList[i].lat)*pow(sin(dlon/2),2) );
		c = 2*atan2(sqrt(a),sqrt(1-a));
		tarList[i].distance = R * c;
Where tarList and startLoc are the two locations.

Also, the program takes user input in the form of:
LATITUDEVALUE/(NorS) LONGITUDEVALUE(WorE) NAME
e.g: 2341/N 41355/W Random City

I have a part of the code that changes the sign of the latitude or longitude according to (N or S and W or E), here it is:

Code:
		//adjust sign of latitude according to N/S
		if(tarList[i].noSo == 'N'){
			tarList[i].lat = getLat(aString);
		}else{
			tarList[i].lat = -getLat(aString);
			cout<<"MINUS USED!"<<endl;
		}

		//adjust sign of longitude according to W/E
		if(tarList[i].weEa == 'E'){
			tarList[i].lon = getLon(aString);
		}else{
			tarList[i].lon = -getLon(aString);
			cout<<"MINUS USED!"<<endl;
		}

I am not getting errors but I am not achieving correct answers. Does anyone know what the problem may be? Thank you physics forums as usual!
 
Physics news on Phys.org
Okay so here's the haversine formula:

http://en.wikipedia.org/wiki/Haversine_formula

are you using radian measure or degrees? It looks like you're using degrees so the question really is what are the args to the sin and cos in C++?

Next, the wiki article doesn't mention inverting the lat / lon values.

What I would do to determine what's going on is to print all intermediate results and compare them to what you calculate manually to see that they make sense. As an exmaple does the sin() give you what you expect...

http://www.cplusplus.com/reference/cmath/sin/

and here's a website that you can compare your results to:

http://www.movable-type.co.uk/scripts/latlong.html
 
jedishrfu said:
Okay so here's the haversine formula:

http://en.wikipedia.org/wiki/Haversine_formula

are you using radian measure or degrees? It looks like you're using degrees so the question really is what are the args to the sin and cos in C++?

Next, the wiki article doesn't mention inverting the lat / lon values.

What I would do to determine what's going on is to print all intermediate results and compare them to what you calculate manually to see that they make sense. As an exmaple does the sin() give you what you expect...

http://www.cplusplus.com/reference/cmath/sin/

and here's a website that you can compare your results to:

http://www.movable-type.co.uk/scripts/latlong.html
Hey, thank you for your reply. I will compare to my own calculations now and see what is happening. Thanks for the suggestion. I will update you on what happens.
I don't understand what you mean by:
"Next, the wiki article doesn't mention inverting the lat / lon values."
 
D H said:
The arguments to the C++ trigonometric functions are angles in radians, not degrees. If you aren't converting your latitude and longitude to radians that explains your incorrect results.

OK that definitely fixed the problem. Thank you.

I am wondering if jedishrfu knew this but was trying to have me find out. Either way thank you too.

The answers are very close but not quite. I will try to figure out why.
 
What value are you using for the radius of the Earth? The equatorial radius is 6378.137 km (the distance from the Earth's center to the equator at sea level), while the polar radius is 6,356.752 km. For the purposes of this calculation, it's best to use a mean value of 6371 km.

The haversine formula is an approximation that assumes a spherical Earth. From the above, this is a good but not great model. There's a 21 km difference between the equatorial and polar radii. A much better model is an oblate ellipsoid. This model is correct to within 100 meters or so. This means the haversine formula isn't quite correct. There is no simple closed formula for the length of the shortest path (i.e., "distance") between two points on an oblate spheroid. You'll need to use elliptical integrals.

Or you could just use the haversine formula. The error isn't all that much except for extreme cases.
 
D H said:
What value are you using for the radius of the Earth? The equatorial radius is 6378.137 km (the distance from the Earth's center to the equator at sea level), while the polar radius is 6,356.752 km. For the purposes of this calculation, it's best to use a mean value of 6371 km.

The haversine formula is an approximation that assumes a spherical Earth. From the above, this is a good but not great model. There's a 21 km difference between the equatorial and polar radii. A much better model is an oblate ellipsoid. This model is correct to within 100 meters or so. This means the haversine formula isn't quite correct. There is no simple closed formula for the length of the shortest path (i.e., "distance") between two points on an oblate spheroid. You'll need to use elliptical integrals.

Or you could just use the haversine formula. The error isn't all that much except for extreme cases.

Interesting. I will be sticking to the haversine formula. By "not accurate," I mean I am comparing my answer to an "ultimate output," and they are close but not the same. By ultimate output, I mean an output of a program that is known to output the "correct results."