aboutsummaryrefslogtreecommitdiffstats
path: root/libtellurian_end_point.c
blob: df0046e0676d55aa7e49e3282ba89073f67dea07 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* See LICENSE file for copyright and license details. */
#include "common.h"
#ifndef TEST


void
libtellurian_end_point(double latitude1, double longitude1, double azimuth1, double distance,
                       double *latitude2_out, double *longitude2_out, double *azimuth2_out)
{
	latitude1 = radians(latitude1);
	longitude1 = radians(longitude1);
	azimuth1 = radians(azimuth1);
	libtellurian_end_point_radians(latitude1, longitude1, azimuth1, distance,
	                               latitude2_out, longitude2_out, azimuth2_out);
	if (latitude2_out)
		*latitude2_out = degrees(*latitude2_out);
	if (longitude2_out)
		*longitude2_out = degrees(*longitude2_out);
	if (azimuth2_out)
		*azimuth2_out = degrees(*azimuth2_out);
}


#else


# define PM LIBTELLURIAN_MERIDIONAL_CIRCUMFERENCE
# define PE LIBTELLURIAN_EQUATORIAL_CIRCUMFERENCE

static int
check(double dlat, double dlon, double daz, double rlat, double rlon, double raz, double s)
{
	double lat1, lat2, lon1, lon2, az1, az2;
	libtellurian_end_point_radians(rlat, rlon, raz, s, &lat1, &lon1, &az1);
	lat1 *= 180 / M_PI;
	lon1 *= 180 / M_PI;
	az1 *= 180 / M_PI;
	libtellurian_end_point(dlat, dlon, daz, s, &lat2, &lon2, &az2);
	if (lat2 != lat1 || lon2 != lon1 || az2 != az1)
		return 0;
	libtellurian_end_point(dlat, dlon, daz, s, &lat2, NULL, NULL);
	libtellurian_end_point(dlat, dlon, daz, s, NULL, &lon2, NULL);
	libtellurian_end_point(dlat, dlon, daz, s, NULL, NULL, &az2);
	if (lat2 != lat1 || lon2 != lon1 || az2 != az1)
		return 0;
	libtellurian_end_point(dlat, dlon, daz, s, NULL, &lon2, &az2);
	if (lon2 != lon1 || az2 != az1)
		return 0;
	libtellurian_end_point(dlat, dlon, daz, s, &lat2, NULL, &az2);
	if (lat2 != lat1 || az2 != az1)
		return 0;
	libtellurian_end_point(dlat, dlon, daz, s, &lat2, &lon2, NULL);
	if (lat2 != lat1 || lon2 != lon1)
		return 0;
	libtellurian_end_point(dlat, dlon, daz, s, NULL, NULL, NULL);
	return 1;
}

int
main(void)
{
	ASSERT(check(0, 0, 0,  0, 0, 0,  0));
	ASSERT(check(0, 0, 0,  0, 0, 0,  PM / 4));
	ASSERT(check(0, 0, 0,  0, 0, 0,  PM / 2));
	ASSERT(check(0, 0, 0,  0, 0, 0,  PM));
	ASSERT(check(0, 0, 0,  0, 0, 0,  2 * PM));
	ASSERT(check(0, 0, 0,  0, 0, 0,  3 * PM / 2));
	ASSERT(check(0, 0, 90,  0, 0, D90,  PE));
	ASSERT(check(0, 0, 90,  0, 0, D90,  PE / 8));
	ASSERT(check(0, 0, 90,  0, 0, D90,  PE / 4));
	ASSERT(check(0, 0, 90,  0, 0, D90,  PE / 2));

	ASSERT(check(0, 0, 0,  0, 0, 0,  1000.0));
	ASSERT(check(0, 0, 30,  0, 0, D30,  1000.0));
	ASSERT(check(0, 0, 45,  0, 0, D45,  1000.0));
	ASSERT(check(0, 0, 60,  0, 0, D60,  1000.0));
	ASSERT(check(0, 0, 90,  0, 0, D90,  1000.0));
	ASSERT(check(0, 0, 180,  0, 0, D180,  1000.0));

	ASSERT(check(0, 30, 0,  0, D30, 0,  1000.0));
	ASSERT(check(0, 45, 30,  0, D45, D30,  1000.0));
	ASSERT(check(0, 60, 45,  0, D60, D45,  1000.0));
	ASSERT(check(0, 90, 60,  0, D90, D60,  1000.0));
	ASSERT(check(0, 180, 90,  0, D180, D90,  1000.0));
	ASSERT(check(0, 45, 180,  0, D45, D180,  1000.0));

	ASSERT(check(45, 30, 0,  D45, D30, 0,  1000.0));
	ASSERT(check(60, 45, 30,  D60, D45, D30,  1000.0));
	ASSERT(check(90, 60, 45,  D90, D60, D45,  1000.0));
	ASSERT(check(-45, 90, 60,  -D45, D90, D60,  1000.0));
	ASSERT(check(-60, 180, 90,  -D60, D180, D90,  1000.0));
	ASSERT(check(-90, 45, 180,  -D90, D45, D180,  1000.0));
	return 0;
}


#endif