|
|
View previous topic :: View next topic |
Author |
Message |
Orcino
Joined: 07 Sep 2003 Posts: 56
|
' Haversine’ formula |
Posted: Wed Oct 18, 2006 8:32 pm |
|
|
Hi, in the code below, with coord. 1 the result is 18.8 Km this is correct, but in coord. 2 the result is 31.08 Km,when the correct is 0.399 km.
Somebody can help?
Thanks
Orcino
void calcula_dist(void)
{
// float lat1=19.508016; // Coord. 1
// float lat2=19.674716; //
// float lon1=99.234144; //
// float lon2=99.234000; //
float lat1 = 18.38490; // Coord. 2
float lat2 = 18.64784; //
float lon1 = 48.11596; //
float lon2 = 48.20348; //
float distancia;
float delta_lati, delta_longe;
float a, c;
lat1 = lat1 * 0.017453; // Converte p/ radianos
lat2 = lat2 * 0.017453;
lon1 = lon1 * 0.017453;
lon2 = lon2 * 0.017453;
delta_lati = lat2 - lat1;
delta_longe= lon2 - lon1;
a = (sin(delta_lati/2) * sin(delta_lati/2)) + cos(lat1) * cos(lat2) * (sin(delta_longe/2) * sin(delta_longe/2));
c = 2 * atan2(sqrt(a),sqrt(1-a));
distancia = EARTH * c; // earth is 6371
fprintf(HOSTPC,"\nA Distancia é %f Km", distancia);
} |
|
|
sjbaxter
Joined: 26 Jan 2006 Posts: 141 Location: Cheshire, UK
|
|
Posted: Thu Oct 19, 2006 4:49 am |
|
|
You can start by explicitly defining numbers in the calculations to be 'float'. Some compilers do weird things during optimization (like converting all values in calculations to the lowest type like an int, so you'll get strange rounding errors creaping in.)
Code: |
#define EARTH 6371.0f
void calcula_dist(void)
{
// float lat1=19.508016f; // Coord. 1
// float lat2=19.674716f; //
// float lon1=99.234144f; //
// float lon2=99.234000f; //
float lat1 = 18.38490f; // Coord. 2
float lat2 = 18.64784f; //
float lon1 = 48.11596f; //
float lon2 = 48.20348f; //
float distancia;
float delta_lati, delta_longe;
float a, c;
lat1 = lat1 * 0.017453f; // Converte p/ radianos
lat2 = lat2 * 0.017453f;
lon1 = lon1 * 0.017453f;
lon2 = lon2 * 0.017453f;
delta_lati = lat2 - lat1;
delta_longe = lon2 - lon1;
a = (sin(delta_lati/2.0f) * sin(delta_lati/2.0f)) + cos(lat1) * cos(lat2) * (sin(delta_longe/2.0f) * sin(delta_longe/2.0f));
c = 2.0f * atan2(sqrt(a), sqrt(1.0f - a));
distancia = EARTH * c;
fprintf(HOSTPC,"\nA Distancia é %f Km", distancia);
}
|
You will also get rounding errors due to the way the PIC stores floating point numbers.
You can also speed up this calculation by doing some calcs once (especially the sin/cos stuff):
Code: |
float sin_half_delta_lati, sin_half_delta_longe;
...
...
sin_half_delta_lati = sin(delta_lati/2.0f);
sin_half_delta_longe = sin(delta_longe/2.0f);
a = (sin_half_delta_lati * sin_half_delta_lati) + cos(lat1) * cos(lat2) * (sin_half_delta_longe * sin_half_delta_longe);
|
This only does 4 sin/cos calcs not 6 !
Not sure if the formula is correct or not, although a few extra brackets around some operations may clarify things as you have an Add and a few Multiplications in there ... the order of which will dramatically influence the result.
Do a search on this forum as this topic was covered about a month ago !! _________________ Regards,
Simon. |
|
|
Ttelmah Guest
|
|
Posted: Thu Oct 19, 2006 8:07 am |
|
|
Er.
31km, is correct for the figures you have put in for 2.
Even a quick rule of thumb test, gives a result that must be larger than the first example. If you look at the first example, there is almost no distance in longitude, and 0.1667 degrees in latitude. The second example, has 0.262884 degrees in lat, and 0.0874 degrees in long.
A quick calculation for the second figures, gives about 30.5km.
Given that 1 degree in lat, is about 112km, anywhere on the Earth, the result cannot be below 29km (0.262*112).
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|