WillyWeb
08/06/15, 22:48:50
Comenté en este tema (http://www.htcmania.com/showthread.php?t=1021127) lo de medir la distancia entre dos coordenadas geodésicas y luego se me pasó explicar cuál era la forma menos incorrecta de hacerlo ... mil disculpas :oh:
Vamos al tema ... :palomitas:
Calcular la distancia en línea recta ente dos puntos es relativamente sencillo ...
Se aplica el "Teorema de Pitágoras (http://es.wikipedia.org/wiki/Teorema_de_Pitágoras)" (aquello de H^2=A^2+B^2) teniendo en cuenta lo siguiente:
H es la distancia que nos interesa
A es la diferencia entre las coordenadas X de los puntos (o las Y)
B es la diferencia entre las coordenadas Y de los puntos (o las X)
Creo que la siguiente imagen lo explica visualmente bastante bien ...
http://www.htcmania.com/attachment.php?attachmentid=731050&stc=1&d=1433842363
Y se considera como buena la equivalencia entre grados y kilómetros de 111,12 km/gr (http://es.wikipedia.org/wiki/Grado_de_latitud).
Una vez calculado el valor de H se multiplica por 111,12 y tenemos la distancia en Km ... lo dicho, sencillo. X-D
Pues resulta que esto, tan fácil de entender y trasladar a Tasker, no nos vale para calcular la distancia entre dos puntos "sobre la superficie de la tierra" porque no tiene en cuenta que la tierra es "casi" redonda (http://es.wikipedia.org/wiki/Forma_de_la_Tierra) :cry:
A muy cortas distancias el error no será demasiado significativo, pero a medida que nos alejemos del ecuador y/o la distancia entre los puntos aumente, el error puede llegar a ser considerable.
Para calcular la distancia más corta ente dos puntos de la superficie de un cuerpo esférico (la ortodrómica (http://es.wikipedia.org/wiki/Ortodrómica)) se tiene que usar la "Trigonometría Esférica (http://es.wikipedia.org/wiki/Trigonometría_esférica)", considerablemente más farragosa de manejar que el Teorema de Pitágoras.
http://www.htcmania.com/attachment.php?attachmentid=731051&stc=1&d=1433842363
Existen varios procedimientos para calcular esa distancia ortodrómica, cada uno con precisiones y complejidades diferentes. Parece ser que los tres más utilizados son: "Teorema del Coseno (http://es.wikipedia.org/wiki/Teorema_del_coseno)", "Fórmula de Haversine (http://es.wikipedia.org/wiki/Fórmula_del_Haversine)" y "Fórmulas de Vincenty (http://es.wikipedia.org/wiki/Fórmulas_de_Vincenty)" (este es para caerse de culo :risitas:).
Después de dar unas pocas vueltas al tema he descartado el sistema de Vincenty por su complejidad y la poca diferencia de precisión con el de Haversine. Y he dejado aparcado el de Haversine un poco forzado también por una pequeña limitación que me he encontrado en Tasker a la hora de hacer cálculos con muchos decimales. Aunque la librería de soporte matemático que usa Tasker (http://softwaremonkey.org/Code/MathEval) parece que puede manejar con soltura número grandes y pequeños los resultados que Tasker proporciona al usuario siempre tienen un máximo de tres decimales, y eso es una faena en este caso porque los sistemas más precisos necesitan varios pasos intermedios en los que perder decimales afecta al resultado. :rolleyes:
El sistema de los cosenos es relativamente fácil de implementar en una única fórmula de manera que no sea necesario hacer pasos intermedios y de esa forma evitar las limitaciones matemáticas de Tasker. Creo que también sería posible hacerlo en una única fórmula con el sistema de Haversine, pero no me he entretenido en ello. ;-)
En definitiva, y como no se trata de colar un ICBM por la ventana de nadie, me parece que la relación dificultad/precisión del teorema del coseno es muy buena (a pesar de ser el sistema menos preciso de los tres estudiados) y algo mejor que con el teorema de pitágoras.
Esta es la fórmula resultante después de desarrollar el teorema del coseno ...
Distancia (A, B) = R * arccos (sen (LatA) * sen (LatB) + cos (LatA) * cos (LatB) * cos (LonA-LonB))
A y B son los dos puntos en cuestión definidos por sus coordenadas geodésicas (latitud/longitud) que son justo del tipo de las que nos proporciona Android. LatA y LatB son las latitudes. LonA y LonB son las longitudes. Las funciones trigonométricas* no tienen misterio. Y el valor R es el radio de la tierra ... y aquí viene otro dolor de cabeza :-(
* Las funciones trigonométricas de Tasker necesitan los ángulos en radianes (http://es.wikipedia.org/wiki/Radián). Eso no es un problema porque la librería matemática de Tasker dispone de todo lo necesario para hacer una conversión precisa.
Resulta que aunque la tierra es "casi" redonda no es una esfera, es un geoide (http://es.wikipedia.org/wiki/Geoide). Tomar este detalle en cuenta añade un nivel de complejidad del que todo el mundo escapa como de la peste, así que se toma como aproximación un esferoide oblato (http://es.wikipedia.org/wiki/Esferoide) (achatado en el eje vertical), que como todo esferoide que se precie tiene un radio menor y otro mayor.
Vale ... ¿y cuánto miden esos radios en el caso de la tierra? ... pues resulta que nuestro sistema de coordenadas usa como DATUM (http://es.wikipedia.org/wiki/Datum) (el modelo matemático de la superficie de la tierra) el WGS84 (http://es.wikipedia.org/wiki/WGS84) (el del GPS (http://es.wikipedia.org/wiki/Sistema_de_posicionamiento_global)), y en ese modelo el esferoide que define la tierra tiene un radio mayor de 6.378,137 Km y un radio menor de 6.356,752 Km.
Vale ... ¿y cuál cogemos? ... pues la media, pero no cualquier media, lo correcto es coger la media cuadrática (http://es.wikipedia.org/wiki/Media_cuadrática) que es la que mejor tiene en cuenta la forma exacta de ese dichoso esferoide.
En definitiva, el radio medio cuadrático de la tierra es de 6.372,795477598 Km ... toma ya. :oh:
Y llegados a este punto (para qué me meteré yo en estos charcos :() ya podemos escribir una tarea en Tasker que nos haga el cálculo de la distancia entre dos coordenadas geodésicas con una precisión, que sin ser digna de la NASA, es más que aceptable.
Esta tarea espera las coordenadas en %par1 y %par2 y nos devolverá un resultado en metros en la variable que le pongamos.
Aquí está la tarea ...
DistLatLon (666)
A1: Devolver [ Valor:ERROR Detener:Encendido ] Si (if) [ %par1 No ajust. | %par2 No ajust. ]
A2: Establecer variable [ Nombre:%radio A:6372795.477598 ]
A3: Separar variable [ Nombre:%par1 Separador:, ]
A4: Separar variable [ Nombre:%par2 Separador:, ]
A5: Establecer variable [ Nombre:%dist A:%radio * acos( sin(torad(%par11)) * sin(torad(%par21)) + cos(torad(%par11)) * cos(torad(%par21)) * cos(torad(%par12-%par22)) ) Calcular:Encendido ]
A6: Devolver [ Valor:%dist Detener:Encendido ]
Hasta la próxima ... :cucu:
Vamos al tema ... :palomitas:
Calcular la distancia en línea recta ente dos puntos es relativamente sencillo ...
Se aplica el "Teorema de Pitágoras (http://es.wikipedia.org/wiki/Teorema_de_Pitágoras)" (aquello de H^2=A^2+B^2) teniendo en cuenta lo siguiente:
H es la distancia que nos interesa
A es la diferencia entre las coordenadas X de los puntos (o las Y)
B es la diferencia entre las coordenadas Y de los puntos (o las X)
Creo que la siguiente imagen lo explica visualmente bastante bien ...
http://www.htcmania.com/attachment.php?attachmentid=731050&stc=1&d=1433842363
Y se considera como buena la equivalencia entre grados y kilómetros de 111,12 km/gr (http://es.wikipedia.org/wiki/Grado_de_latitud).
Una vez calculado el valor de H se multiplica por 111,12 y tenemos la distancia en Km ... lo dicho, sencillo. X-D
Pues resulta que esto, tan fácil de entender y trasladar a Tasker, no nos vale para calcular la distancia entre dos puntos "sobre la superficie de la tierra" porque no tiene en cuenta que la tierra es "casi" redonda (http://es.wikipedia.org/wiki/Forma_de_la_Tierra) :cry:
A muy cortas distancias el error no será demasiado significativo, pero a medida que nos alejemos del ecuador y/o la distancia entre los puntos aumente, el error puede llegar a ser considerable.
Para calcular la distancia más corta ente dos puntos de la superficie de un cuerpo esférico (la ortodrómica (http://es.wikipedia.org/wiki/Ortodrómica)) se tiene que usar la "Trigonometría Esférica (http://es.wikipedia.org/wiki/Trigonometría_esférica)", considerablemente más farragosa de manejar que el Teorema de Pitágoras.
http://www.htcmania.com/attachment.php?attachmentid=731051&stc=1&d=1433842363
Existen varios procedimientos para calcular esa distancia ortodrómica, cada uno con precisiones y complejidades diferentes. Parece ser que los tres más utilizados son: "Teorema del Coseno (http://es.wikipedia.org/wiki/Teorema_del_coseno)", "Fórmula de Haversine (http://es.wikipedia.org/wiki/Fórmula_del_Haversine)" y "Fórmulas de Vincenty (http://es.wikipedia.org/wiki/Fórmulas_de_Vincenty)" (este es para caerse de culo :risitas:).
Después de dar unas pocas vueltas al tema he descartado el sistema de Vincenty por su complejidad y la poca diferencia de precisión con el de Haversine. Y he dejado aparcado el de Haversine un poco forzado también por una pequeña limitación que me he encontrado en Tasker a la hora de hacer cálculos con muchos decimales. Aunque la librería de soporte matemático que usa Tasker (http://softwaremonkey.org/Code/MathEval) parece que puede manejar con soltura número grandes y pequeños los resultados que Tasker proporciona al usuario siempre tienen un máximo de tres decimales, y eso es una faena en este caso porque los sistemas más precisos necesitan varios pasos intermedios en los que perder decimales afecta al resultado. :rolleyes:
El sistema de los cosenos es relativamente fácil de implementar en una única fórmula de manera que no sea necesario hacer pasos intermedios y de esa forma evitar las limitaciones matemáticas de Tasker. Creo que también sería posible hacerlo en una única fórmula con el sistema de Haversine, pero no me he entretenido en ello. ;-)
En definitiva, y como no se trata de colar un ICBM por la ventana de nadie, me parece que la relación dificultad/precisión del teorema del coseno es muy buena (a pesar de ser el sistema menos preciso de los tres estudiados) y algo mejor que con el teorema de pitágoras.
Esta es la fórmula resultante después de desarrollar el teorema del coseno ...
Distancia (A, B) = R * arccos (sen (LatA) * sen (LatB) + cos (LatA) * cos (LatB) * cos (LonA-LonB))
A y B son los dos puntos en cuestión definidos por sus coordenadas geodésicas (latitud/longitud) que son justo del tipo de las que nos proporciona Android. LatA y LatB son las latitudes. LonA y LonB son las longitudes. Las funciones trigonométricas* no tienen misterio. Y el valor R es el radio de la tierra ... y aquí viene otro dolor de cabeza :-(
* Las funciones trigonométricas de Tasker necesitan los ángulos en radianes (http://es.wikipedia.org/wiki/Radián). Eso no es un problema porque la librería matemática de Tasker dispone de todo lo necesario para hacer una conversión precisa.
Resulta que aunque la tierra es "casi" redonda no es una esfera, es un geoide (http://es.wikipedia.org/wiki/Geoide). Tomar este detalle en cuenta añade un nivel de complejidad del que todo el mundo escapa como de la peste, así que se toma como aproximación un esferoide oblato (http://es.wikipedia.org/wiki/Esferoide) (achatado en el eje vertical), que como todo esferoide que se precie tiene un radio menor y otro mayor.
Vale ... ¿y cuánto miden esos radios en el caso de la tierra? ... pues resulta que nuestro sistema de coordenadas usa como DATUM (http://es.wikipedia.org/wiki/Datum) (el modelo matemático de la superficie de la tierra) el WGS84 (http://es.wikipedia.org/wiki/WGS84) (el del GPS (http://es.wikipedia.org/wiki/Sistema_de_posicionamiento_global)), y en ese modelo el esferoide que define la tierra tiene un radio mayor de 6.378,137 Km y un radio menor de 6.356,752 Km.
Vale ... ¿y cuál cogemos? ... pues la media, pero no cualquier media, lo correcto es coger la media cuadrática (http://es.wikipedia.org/wiki/Media_cuadrática) que es la que mejor tiene en cuenta la forma exacta de ese dichoso esferoide.
En definitiva, el radio medio cuadrático de la tierra es de 6.372,795477598 Km ... toma ya. :oh:
Y llegados a este punto (para qué me meteré yo en estos charcos :() ya podemos escribir una tarea en Tasker que nos haga el cálculo de la distancia entre dos coordenadas geodésicas con una precisión, que sin ser digna de la NASA, es más que aceptable.
Esta tarea espera las coordenadas en %par1 y %par2 y nos devolverá un resultado en metros en la variable que le pongamos.
Aquí está la tarea ...
DistLatLon (666)
A1: Devolver [ Valor:ERROR Detener:Encendido ] Si (if) [ %par1 No ajust. | %par2 No ajust. ]
A2: Establecer variable [ Nombre:%radio A:6372795.477598 ]
A3: Separar variable [ Nombre:%par1 Separador:, ]
A4: Separar variable [ Nombre:%par2 Separador:, ]
A5: Establecer variable [ Nombre:%dist A:%radio * acos( sin(torad(%par11)) * sin(torad(%par21)) + cos(torad(%par11)) * cos(torad(%par21)) * cos(torad(%par12-%par22)) ) Calcular:Encendido ]
A6: Devolver [ Valor:%dist Detener:Encendido ]
Hasta la próxima ... :cucu: