CB100

Notas, resueltos y tps de la materia Algoritmos y Estructuras de Datos
Index Commits Files Refs README
commit 728427929a8070a4693b3fc11c6b4ad57361c4ef
parent f742889bc29a6c6e66d89f37eeb4e66f871a6925
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date:   Sun, 23 Jun 2024 13:26:47 -0300

add function `getDistanciaEnKilometros`

this function calculates the distance in km between two points given its
coordinates (latitude, longitude) using the lambert's formula

Diffstat:
Mmenu.cpp | 67++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 56 insertions(+), 11 deletions(-)
diff --git a/menu.cpp b/menu.cpp
@@ -261,6 +261,33 @@ Barrio *Menu::getBarrioPorNombre(std::string nombre) {
     return res;
 }
 
+double gradosARadianes(double grados) {
+    return grados * M_PI / 180.0;
+}
+
+// lat -> y; lon -> x;
+// calcula la distancia en km entre dos coordenadas usando la formula de Lambert
+double getDistanciaEnKilometros(double x1, double y1, double x2, double y2) {
+    const double R = 6371.0;  // Radius of the Earth in kilometers
+
+    // Convert latitude and longitude from degrees to radians
+    double x1Rad = gradosARadianes(x1);
+    double y1Rad = gradosARadianes(y1);
+    double x2Rad = gradosARadianes(x2);
+    double y2Rad = gradosARadianes(y2);
+
+    // Calculate differences in radians
+    double dLon = x2Rad - x1Rad;
+    double dLat = y2Rad - y1Rad;
+
+    // Apply Lambert's formula
+    double a = sin(dLat / 2) * sin(dLat / 2) + cos(y1Rad) * cos(y2Rad) * sin(dLon / 2) * sin(dLon / 2);
+    double c = 2 * atan2(sqrt(a), sqrt(1 - a));
+    double distancia = R * c;
+
+    return distancia;
+}
+
 double getDistancia(double x1, double y1, double x2, double y2) {
     double dX = (x2 - x1);
     double dY = (y2 - y1);
@@ -394,7 +421,8 @@ void Menu::mostrarMenu() {
     std::string opcion;
     int linea;
     double lat, lon; // lat -> Y; lon -> X;
-    std::string barrio, barrioNombre, lineaAImprimir;
+    double distanciaEnKm;
+    std::string barrio, barrioNombre, lineaAImprimir, distanciaUnidad;
 
     while(!terminarPrograma) {
         std::cout << "`1` Cantidad de paradas por barrio\n";
@@ -424,6 +452,7 @@ void Menu::mostrarMenu() {
                 imprimirCantidadDeParadasPorBarrio();
                 break;
             case '2':
+                // TODO: verificar que `latitud` y `longitud` sean validas
                 do {
                     std::cin.clear();
                     std::string line;
@@ -449,8 +478,19 @@ void Menu::mostrarMenu() {
                     break;
                 }
 
-                std::cout << "La parada mas cercana esta en: `" << parada->getDireccion()
-                        << "` (" << parada->getCoordX() << ", " << parada->getCoordY() << ")\n";
+                distanciaEnKm = getDistanciaEnKilometros(lon, lat, parada->getCoordY(), parada->getCoordX());
+
+                if(distanciaEnKm < 1) {
+                    distanciaEnKm *= 1000.0f;
+                    distanciaUnidad.assign("metros");
+                } else {
+                    distanciaUnidad.assign("kilometros");
+                }
+
+                std::cout << "Parada mas cercana: `" << parada->getDireccion()
+                        << "` (" << parada->getCoordX() << ", " << parada->getCoordY()
+                        << ") a " << std::fixed << std::setprecision(2) << distanciaEnKm
+                        << " " << distanciaUnidad << "\n";
                 break;
             case '3':
                 List<Parada*> *paradas;
@@ -528,15 +568,15 @@ void Menu::mostrarMenu() {
 
                 // std::cout<<"Indique la Linea: ";
                 // std::cin >> this->linea;
-                this->linea = 154;
+                this->linea = 12;
 
                 // std::cout<<"Indique la coordenada en X: ";
                 // std::cin >> lon;
-                lon = 0.0f;
+                lon = -58.0f;
 
                 // std::cout<<"Indique la coordenada en Y: ";
                 // std::cin >> lat;
-                lat = 0.0f;
+                lat = -34.0f;
 
                 Barrio *barrio;
                 List<Parada*> *paradasDeLaLinea;
@@ -548,24 +588,29 @@ void Menu::mostrarMenu() {
                 // ordenar de mayor a menor `paradasDeLaLinea`
                 ordenarParadasPorDistanciaACoordenada(paradasDeLaLinea, lon, lat);
 
-                double distancia;
                 Parada *actual;
 
                 paradasDeLaLinea->startCursor();
                 while(paradasDeLaLinea->forwardCursor()) {
                     actual = paradasDeLaLinea->getCursorData();
-                    distancia = getDistancia(actual->getCoordX(), actual->getCoordY(), lon, lat);
-                    std::cout << actual->getDireccion() << " (distancia: `" << distancia << " `)" << std::endl;
+                    // distancia = getDistancia(actual->getCoordX(), actual->getCoordY(), lon, lat);
+                    distanciaEnKm = getDistanciaEnKilometros(lon, lat, actual->getCoordY(), actual->getCoordX());
+
+                    std::cout.fill('.');
+                    std::cout << std::left << std::setw(25) << actual->getDireccion()
+                                << std::right << std::setw(20)
+                                << std::fixed << std::setprecision(2)
+                                << distanciaEnKm << "  (" << actual->getCoordX() << ", " << actual->getCoordY()
+                                << ")" << std::endl;
                 }
 
-                // delete paradasDeLaLinea;
-
                 // imprimir paradasDeLaLineaOrdenada
 
                 // delete paradasDeLaLineaOrdenada;
 
                 // paradasMasCercanasPorBarrio(barrio,this->linea,this->coordX,this->coordY);
                 // imprimirParadasPorLinea(this->listaDeParadasCercanasOrdenadas);
+                delete paradasDeLaLinea;
                 break;
             case 'q':
                 terminarPrograma = true;