Need to calculate location distance between two vectors

I really need your help I started working with C++ for my project and I need to solve a problem . My problem is that I have a program that contains information about patient and Doctors in order to have an idea I ll give you a general structor of the project . So I created 3 classes :

Person : Attributes ( Id , Latitude , longitude ) ( Person.h & Person.cpp) Patient: Attributes ( state) ( Patient.h & Patient.cpp) it inherits from Person Doctor : Attributes (Id_Profession) (Doctor.h & doctor.cpp) it also inherits from class Person

The problem to create a function that calculate the distance between each patient and doctors : so I created the function below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
double Distance (const vector <Patient>& Pat, const vector <Generalist>&  
Gen)
{
double dist;

for (unsigned int i =0 ; i <10; i++)
{
 for (unsigned int j =0; j< 10; j++)
 {
dist= sin((Pat[i].GetLat())/180 * pi) *sin((Gen[j].GetLat())/180 * pi) + 
cos((Pat[i].GetLat())/180 * pi) * cos((Gen[j].GetLat())/180 * pi) * cos( 
(Pat[i].GetLong() - Gen[j].GetLong())/180 * pi);
dist = acos(dist);
dist = 6371 * dist;
//j++;
cout <<dis;
return dist;
 }
}
}
int main()
{
vector <Patient> myPat;
vector <Generalist> myGen;
fillGeneralist(myGen); //Function that fils my vector of doctors already 
defined 
fillPatient(myPat);
Distance (myPat, myGen);
return 0;
}


could someone please help me the program returns all distances but I need to return distance between each patient and all doctors I need to have at the end the following results

The distance between patient 1 and doctor 1 is : ... The distance between patient 1 and doctor 2 is : ... The distance between patient 1 and doctor 3 is : ... .
.
. The distance between patient 10 and doctor 10 is : ...

Thank you for your help
Last edited on
the program returns all distances

The first problem is that it doesn't.
So the problem I see is that you have your return statement within the for loops. This will cause Distance to return in the very first iteration, i = 0 and j = 0.
In other words, Distance function only calculates the distance between Pat[0] and Gen[0].
You need to compare every Pat[i] to every Gen[j], which is Pat.size() * Gen.size() operations.

What I would personally do is reformat your code a bit.
I would create a function that is just called
1
2
3
4
5
6
7
8
9
double Distance(const Patient& pat, const Generalist& gen)
{
    double dist= sin((pat.GetLat())/180 * pi) *sin((gen.GetLat())/180 * pi) + 
        cos((pat.GetLat())/180 * pi) * cos((gen.GetLat())/180 * pi) * cos( 
         (pat.GetLong() - gen.GetLong())/180 * pi);
    dist = acos(dist);
    dist = 6371 * dist;
    return dist;
}


...and then, call the function like this:

1
2
3
4
5
6
7
8
for (int i = 0; i < pat.size(); i++)
{
    for (int j = 0; j < gen.size(); j++)
    {
        double dist = Distance(pat[i], gen[j]);
        std::cout << "The distance between patient" << i+1 << " and doctor " << j+1 << " is : " << dist << std::endl;
    }
}
Last edited on
I'd certainly second @Ganado's recommendation to have a separate function, and call it with a nested loop of doctors and patients. However, it might be nice not to restrict its arguments to Patient and Doctor - you might want the distance between two doctors, for example, or the distance between patient and hospital.

So maybe a distance function that only depends on the (latitude,longitude) pairs:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
double distance( double latA, double longA, double latB, double longB )    // latitude and longitude of arbitrary entities
{
   constexpr double degToRad = 3.14159265358979 / 180.0;      // conversion factor, evaluated at compile time
   const double radEarth = 6371;                              // mean radius of the earth in km

   latA  *= degToRad;                                         // convert to radians (if originally in degrees)
   longA *= degToRad;
   latB  *= degToRad;
   longB *= degToRad;

   double cosAngle = sin( latA ) * sin( latB ) + cos( latA ) * cos( latB ) * cos( longA - longB );
                   // cosine of angle between position vectors, from spherical coordinates and dot product

   return radEarth * acos( cosAngle );                        // great-circle distance ( "r x theta" )
}


then called by
1
2
3
4
5
6
7
8
for ( int i = 0; i < pat.size(); i++ )
{
    for ( int j = 0; j < gen.size(); j++ )
    {
        double dist = distance( pat[i].GetLat(), pat[i].GetLong(), Gen[j].GetLat(), Gen[j].GetLong() );
        cout << "The distance between patient" << i + 1 << " and doctor " << j + 1 << " is " << dist << "km " << endl;
    }
}


Last edited on
+1 much cleaner
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <vector>
#include <map>

struct location
{
    int latitude = 0 ;
    int longitude = 0 ;
};

double distance( location a, location b ) ; // TO DO

struct person { unsigned int id ; location loc ; };
double distance( const person& a, const person& b ) { return distance( a.loc, b.loc ) ; }

struct doctor : person { /* ... */ };
struct patient : person { /* ... */ };

struct distance_info // info about distances from one patient to many doctors
{
    unsigned int patient_id ;

    // key: id of the doctor   mapped value: distance from this patient
    std::map< unsigned int, double > distance_to_docs ;
};

// return distance info for distance from one patient to each doctors
distance_info distances( const patient& p, const std::vector<doctor>& docs )
{
    distance_info di { p.id, {} } ;
    for( const doctor& d : docs ) di.distance_to_docs.emplace( d.id, distance(p,d) ) ;
    return di ;
}

// return distance info for all patients to all doctors
std::map< unsigned int, distance_info > // key: patient id  mapped value: distance info
distances( const std::vector<patient>& patients, const std::vector<doctor>& docs )
{
    std::map< unsigned int, distance_info > di_all ;
    for( const patient& p : patients ) di_all.emplace( p.id, distances( p, docs ) ) ;
    return di_all ;
}
Hello

I want to thank you a lot for your help, I tried @Ganado and @lastchance suggestion and it works well.

@JLBorges thank you also for your help

Last edited on
Registered users can post here. Sign in or register to post.