/* See LICENSE file for copyright and license details. */
#include "common.h"
#define R LIBTELLURIAN_AUTHALIC_RADIUS
#ifndef TEST
const double libtellurian_coarse_distance_radius = R;
double
libtellurian_coarse_distance_radians(double latitude1, double longitude1,
double latitude2, double longitude2)
{
double h = fma(haversin(longitude2 - longitude1),
cos(latitude1) * cos(latitude2),
haversin(latitude2 - latitude1));
return 2.0 * R * asin(sqrt(h));
}
#else
static int
check(double a, double b, double c, double d, double expect)
{
double got = libtellurian_coarse_distance_radians(a, b, c, d);
double rgot = libtellurian_coarse_distance_radians(c, d, a, b);
double err = expect ? fabs(got / (R * expect) - 1.0) : got;
return err <= 1.0e-8 && got == rgot;
}
int
main(void)
{
ASSERT(check(0, 0, 0, 0, 0));
ASSERT(check(0, 0, D90, 0, M_PI / 2.0));
ASSERT(check(0, 0, 0, D90, M_PI / 2.0));
ASSERT(check(0, 0, D180, 0, M_PI));
ASSERT(check(0, 0, 0, D180, M_PI));
ASSERT(check(0, 0, D45, 0, M_PI / 4.0));
ASSERT(check(0, 0, 0, D45, M_PI / 4.0));
ASSERT(check(-D90, 0, D90, 0, M_PI));
ASSERT(check(0, -D90, 0, D90, M_PI));
ASSERT(check(0, 0, D60, D90, M_PI / 2.0));
ASSERT(check(0, 0, D30, D90, M_PI / 2.0));
ASSERT(check(0, 0, D90, D90, M_PI / 2.0));
ASSERT(check(0, 0, D45, D45, M_PI / 3.0));
ASSERT(check(-D45, -D45, D45, D45, M_PI / 1.5));
ASSERT(check(D45, -D45, D45, D45, M_PI / 3.0));
ASSERT(check(-D45, D45, D45, D45, M_PI / 2.0));
ASSERT(libtellurian_coarse_distance_radius == R);
return 0;
}
#endif