Merge pull request #233 from GaryBlackbourne/prerelease/latlon-update
Some checks failed
Mirror to Codeberg / mirror-to-codeberg (push) Has been cancelled

Prerelease/latlon update
This commit is contained in:
aclist 2025-10-31 10:06:13 +09:00 committed by GitHub
commit cc35b2cd85
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 102 additions and 36 deletions

View File

@ -1,36 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define R 6371
#define TO_RAD (3.1415926536 / 180)
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);
dx = cos(ph1) * cos(th1) - cos(th2);
dy = sin(ph1) * cos(th1);
return asin(sqrt(dx * dx + dy * dy + dz * dz) / 2) * 2 * R;
}
int main(int argc, const char * argv[])
{
if(argc < 5 || argc > 5){
return 1;
}
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);
return 0;
}

1
helpers/tools/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
latlon

24
helpers/tools/Makefile Normal file
View File

@ -0,0 +1,24 @@
bin := latlon
CC = gcc
CFLAGS += -Wall
CFLAGS += -Wextra
CFLAGS += -Wpedantic
CFLAGS += -std=c23
CFLAGS += -O3
LDFLAGS += -lm
PREFIX ?= $(HOME)/.local/share/dzgui
all: $(bin)
install: $(bin)
install -Dm 755 $(bin) $(PREFIX)
$(bin): latlon.c
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
clean:
rm -f $(bin)

77
helpers/tools/latlon.c Normal file
View File

@ -0,0 +1,77 @@
// This small program computes the distance between two points on the Earths
// 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 <stdlib.h>
#include <stdio.h>
// Earth's radius in meters.
#define RADIUS ((12756L / 2.0L) * 1000L)
// PI natural constant
#define PI 3.1415926536L
// 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;
}
/**
* @brief Calculate the haversine function from an angle in radian
*/
double haversine(const double angle) { return ((1.0L - cos(angle)) / 2); }
/**
* @brief Calculate the distance between two coordinates
*/
double great_circle_distance(const struct Coordinate a,
const struct Coordinate b) {
// 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])),
};
// Returns the distance in meters.
// To pretty-print the result in a consumer of this module, it is
// recommended to divide the result by 1,000 and round it.
printf("%.1f\n", great_circle_distance(a, b));
return 0;
}