mirror of
https://github.com/aclist/dztui.git
synced 2026-08-29 11:17:12 +02:00
Rewrite and document latlon tool source
- incorrect argument count has been fixed - The code has been split up into smaller units to be more understandable - sources were put in comments to help find resources for the algorithm - output is now in meters
This commit is contained in:
parent
23fb10f48e
commit
dfe65aacd4
@ -1,36 +1,74 @@
|
|||||||
#include <stdio.h>
|
// This small program computes the distance between two points on the Earths
|
||||||
#include <stdlib.h>
|
// surface. The algorithm used for computing is called haversine formula.
|
||||||
|
// Source for the algorithm can be found here:
|
||||||
|
// https://en.wikipedia.org/wiki/Haversine_formula
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define R 6371
|
// Earths radius in meters
|
||||||
#define TO_RAD (3.1415926536 / 180)
|
#define RADIUS ((12756L / 2.0L) * 1000L)
|
||||||
double dist(double th1, double ph1, double th2, double ph2)
|
|
||||||
{
|
|
||||||
double dx, dy, dz;
|
|
||||||
ph1 -= ph2;
|
|
||||||
ph1 *= TO_RAD, th1 *= TO_RAD, th2 *= TO_RAD;
|
|
||||||
|
|
||||||
dz = sin(th1) - sin(th2);
|
// PI natural constant
|
||||||
dx = cos(ph1) * cos(th1) - cos(th2);
|
#define PI 3.1415926536L
|
||||||
dy = sin(ph1) * cos(th1);
|
|
||||||
return asin(sqrt(dx * dx + dy * dy + dz * dz) / 2) * 2 * R;
|
// coordinates struct for storing points
|
||||||
|
struct Coordinate {
|
||||||
|
double latitude;
|
||||||
|
double longitude;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calculates a radian value from an angle
|
||||||
|
*/
|
||||||
|
double radian_from(const double angle) {
|
||||||
|
return (angle * PI) / 180;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char * argv[])
|
/**
|
||||||
{
|
* @brief Calculate the haversine function from an angle in radian
|
||||||
if(argc < 5 || argc > 5){
|
*/
|
||||||
return 1;
|
double haversine(const double angle) { return ((1.0L - cos(angle)) / 2); }
|
||||||
}
|
|
||||||
float coords[4];
|
|
||||||
for(int i=1;i<5;i++){
|
|
||||||
if(atof(argv[i]) == 0){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
coords[i] = atof(argv[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
double d = dist(coords[1], coords[2], coords[3], coords[4]);
|
/**
|
||||||
printf("%.1f\n", d);
|
* @brief Calculate the distance between two coordinates
|
||||||
|
*/
|
||||||
|
double great_circle_distance(const struct Coordinate a,
|
||||||
|
const struct Coordinate b) {
|
||||||
|
|
||||||
return 0;
|
// calculate longitude and latitude differences
|
||||||
|
struct Coordinate diff_coord = {
|
||||||
|
.longitude = a.longitude - b.longitude,
|
||||||
|
.latitude = a.latitude - b.latitude,
|
||||||
|
};
|
||||||
|
|
||||||
|
// calculate haversine(theta) value, where theta is the angle between the
|
||||||
|
// two coordinates
|
||||||
|
double hav_theta = haversine(diff_coord.latitude)
|
||||||
|
+ cos(a.latitude) * cos(b.latitude) * haversine(diff_coord.longitude);
|
||||||
|
|
||||||
|
// calculate distance from radius, and haversine(theta) values
|
||||||
|
double distance = 2 * RADIUS * asin(sqrt(hav_theta));
|
||||||
|
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char* argv[]) {
|
||||||
|
if (argc < 5 || argc > 5) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct Coordinate a = {
|
||||||
|
.latitude = radian_from(atof(argv[1])),
|
||||||
|
.longitude = radian_from(atof(argv[2])),
|
||||||
|
};
|
||||||
|
const struct Coordinate b = {
|
||||||
|
.latitude = radian_from(atof(argv[3])),
|
||||||
|
.longitude = radian_from(atof(argv[4])),
|
||||||
|
};
|
||||||
|
|
||||||
|
printf("%.1f\n", great_circle_distance(a, b));
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user