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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Determine time and position of closest approach for two vessels traveling
// along geodesics. Thanks to
// Jorge D. Taramona
// Inspector de Navegación Aérea
// Dirección General de Aviación Civil del Perú
// for suggesting this problem. See discussion entry from 2014-08-19:
// https://sourceforge.net/p/geographiclib/discussion/1026620/thread/33ce09e0/
// Compile with
// g++ -O3 -std=c++11 -o ClosestApproach ClosestApproach.cpp
// -lGeographic -L/usr/local/lib -Wl,-rpath=/usr/local/lib
// Example: Planes leave
// (1) Istanbul 42N 29E bearing 51W traveling at 900 km/hr
// (2) Reyjkavik 64N 22W bearing 154E traveling at 800 km/hr
// at the same time; compute time of closest approach. Guess that the time of
// closest approach is after 1 hr. So run
// echo 42 29 -51 900e3 64 -22 154 800e3 1 | ./ClosestApproach
// 0 1 2696504 -3.532249e+12 46.74926 19.83775 57.4055 -16.17089
// 1 2.751696 1083726 6.786464e+10 52.80517 -0.05892146 45.43817 -9.817806
// 2 2.71894 1082700 -2657490 52.72565 0.3576737 45.66487 -9.90999
// 3 2.718941 1082700 -0.005293798 52.72565 0.3576574 45.66486 -9.909987
// 4 2.718941 1082700 0 52.72565 0.3576574 45.66486 -9.909987
// 5 2.718941 1082700 0 52.72565 0.3576574 45.66486 -9.909987
// 6 2.718941 1082700 0 52.72565 0.3576574 45.66486 -9.909987
// 7 2.718941 1082700 0 52.72565 0.3576574 45.66486 -9.909987
// 8 2.718941 1082700 0 52.72565 0.3576574 45.66486 -9.909987
// 9 2.718941 1082700 0 52.72565 0.3576574 45.66486 -9.909987
// At closest approach
// time = 2.72 hr
// dist = 1083 km
// position of first plane = 52.7N 0.3E
// position of second plane = 45.7N 9.9W
// CAVEAT: if the initial guess is bad, this program may return the time at
// which the distance is a maximum.
// Explanation:
// Consider f(t) = s12^2 / 2
// Find zeros of g(t) = f'(t) = s12' * s12 by Newton's method
// using g'(t) = (s12')^2 + s12'' * s12
// Using s12^2 / 2 as the governing function (as opposed, for example, to
// |s12|) means that in the planar limit f(t) is a quadratic function and g(t)
// is a linear function. So Newton's method just needs a single iteration.
// Let gam{1,2} be angle between s12 and v{1,2}.
// s12' = v2 * cos(gam2) - v1 * cos(gam1)
// g(t) = s12 * (v2 * cos(gam2) - v1 * cos(gam1))
// s12'' = - v2*sin(gam2) * dgam2/dt + v1*sin(gam1) * dgam1/dt
// dgam1/dt = (+ M12*v1*sin(gam1) - v2*sin(gam2)) / m12
// dgam2/dt = (- M21*v2*sin(gam2) + v1*sin(gam1)) / m12
// s12'' = (M12*v1^2*sin(gam1)^2 + M21*v2^2*sin(gam2)^2
// - 2*v1*v2*sin(gam1)*sin(gam2)) / m12
// g'(t) = v1^2 * (cos(gam1)^2 + M12*s12/m12 * sin(gam1)^2)
// + v2^2 * (cos(gam2)^2 + M21*s12/m12 * sin(gam2)^2)
// - 2*v1*v2 * (cos(gam1)*cos(gam2) + s12/m12 * sin(gam1)*sin(gam2))
// Planar limit (m12 = s12, M12 = M21 = 1):
// g(t) = (v2-v1) . (r2-r1)
// g'(t) = v1^2 + v2^2 - 2*v1*v2 * cos(gam1-gam2)
// = |v1-v2|^2 = const
// Special case when v2 = 0 (simple interception), v1 = 1
// s12' = - cos(gam1)
// g(t) = - s12 * cos(gam1)
// s12'' = sin(gam1) * dgam1/dt
// dgam1/dt = M12*sin(gam1) / m12
// s12'' = M12*sin(gam1)^2 / m12
// g'(t) = (cos(gam1)^2 + M12*s12/m12 * sin(gam1)^2)
// Planar limit (m12 = s12, M12 = M21 = 1):
// g(t) = -v1 . (r2-r1)
// g'(t) = 1 = const
using namespace std;
using namespace GeographicLib;
int