CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

' Haversine’ formula

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Orcino



Joined: 07 Sep 2003
Posts: 56

View user's profile Send private message

' Haversine’ formula
PostPosted: Wed Oct 18, 2006 8:32 pm     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Thu Oct 19, 2006 4:49 am     Reply with quote

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







PostPosted: Thu Oct 19, 2006 8:07 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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