37double Geodesic::GreatCircleDistBear(
double Lon1,
double Lat1,
double Lon2,
38 double Lat2,
double *Dist,
double *Bear1,
41 double a = GEODESIC_WGS84_SEMI_MAJORAXIS;
42 double b = GEODESIC_WGS84_SEMI_MINORAXIS;
43 double f = (GEODESIC_WGS84_SEMI_MAJORAXIS - GEODESIC_WGS84_SEMI_MINORAXIS) /
44 GEODESIC_WGS84_SEMI_MAJORAXIS;
48 double lambda, lambdaprime;
49 double sinrLat1, cosrLat1, sinrLat2, cosrLat2, sinlambda,
51 double sinsigma, cossigma, cos2sigmam, sigma, sinalpha, cos2alpha,
58 if (Dist) *Dist = 0.0;
59 if (Bear1) *Bear1 = 0.0;
60 if (Bear2) *Bear2 = 0.0;
62 if (fabs(Lon1 - Lon2) < 1e-12 && fabs(Lat1 - Lat2) < 1e-12) {
68 Lon1 = GEODESIC_DEG2RAD(Lon1);
69 Lat1 = GEODESIC_DEG2RAD(Lat1);
70 Lon2 = GEODESIC_DEG2RAD(Lon2);
71 Lat2 = GEODESIC_DEG2RAD(Lat2);
74 rLat1 = atan((1 - f) * tan(Lat1));
75 rLat2 = atan((1 - f) * tan(Lat2));
76 sinrLat1 = sin(rLat1);
77 cosrLat1 = cos(rLat1);
78 sinrLat2 = sin(rLat2);
79 cosrLat2 = cos(rLat2);
83 lambdaprime = 2 * M_PI;
86 sinlambda = sin(lambda);
87 coslambda = cos(lambda);
89 sqrt(pow(cosrLat2 * sinlambda, 2.0) +
90 pow(cosrLat1 * sinrLat2 - sinrLat1 * cosrLat2 * coslambda, 2.0));
91 if (sinsigma < 1e-12) {
94 if (Dist) *Dist = dist;
95 if (Bear1) *Bear1 = 180.0;
96 if (Bear2) *Bear2 = 0.0;
100 cossigma = sinrLat1 * sinrLat2 + cosrLat1 * cosrLat2 * coslambda;
101 sigma = atan2(sinsigma, cossigma);
105 sinalpha = cosrLat1 * cosrLat2 * sinlambda / sinsigma;
106 cos2alpha = 1 - pow(sinalpha, 2.0);
107 if (cos2alpha == 0.0)
110 cos2sigmam = cossigma - 2 * sinrLat1 * sinrLat2 / cos2alpha;
113 C = f / 16 * cos2alpha * (4 + f * (4 - 3 * cos2alpha));
114 lambdaprime = lambda;
117 (1.0 - C) * f * sinalpha *
118 (sigma + C * sinsigma *
120 C * cossigma * (-1.0 + 2.0 * pow(cos2sigmam, 2.0))));
121 }
while (fabs(lambda - lambdaprime) > 1e-12 && (itersleft--));
123 if (itersleft == 0) {
126 if (Dist) *Dist = dist;
127 if (Bear1) *Bear1 = 180.0;
128 if (Bear2) *Bear2 = 0.0;
132 u2 = cos2alpha * (pow(a, 2.0) - pow(b, 2.0)) / pow(b, 2.0);
133 A = 1 + u2 / 16384 * (4096 + u2 * (-768 + u2 * (320 - 175 * u2)));
134 B = u2 / 1024 * (256 + u2 * (-128 + u2 * (74 - 74 * u2)));
140 (cossigma * (-1.0 + 2.0 * pow(cos2sigmam, 2.0)) -
141 B / 6 * cos2sigmam * (-3.0 + 4.0 * pow(sinsigma, 2.0)) *
142 (-3 + 4 * pow(cos2sigmam, 2.0)))));
143 if (Dist) *Dist = dist;
145 *Bear1 = GEODESIC_RAD2DEG(
146 atan2(cosrLat2 * sinlambda,
147 cosrLat1 * sinrLat2 - sinrLat1 * cosrLat2 * coslambda));
148 while (*Bear1 < 0.0) *Bear1 += 360.0;
151 *Bear2 = GEODESIC_RAD2DEG(
152 atan2(cosrLat1 * sinlambda,
153 -sinrLat1 * cosrLat2 + cosrLat1 * sinrLat2 * coslambda));
154 while (*Bear2 < 0.0) *Bear2 += 360.0;
163void Geodesic::GreatCircleTravel(
double Lon1,
double Lat1,
double Dist,
164 double Bear1,
double *Lon2,
double *Lat2,
167 double a = GEODESIC_WGS84_SEMI_MAJORAXIS;
168 double b = GEODESIC_WGS84_SEMI_MINORAXIS;
169 double f = (GEODESIC_WGS84_SEMI_MAJORAXIS - GEODESIC_WGS84_SEMI_MINORAXIS) /
170 GEODESIC_WGS84_SEMI_MAJORAXIS;
173 if (Lon2) *Lon2 = Lon1;
174 if (Lat2) *Lat2 = Lat1;
175 if (Bear2) *Bear2 = Bear1;
183 Lon1 = GEODESIC_DEG2RAD(Lon1);
184 Lat1 = GEODESIC_DEG2RAD(Lat1);
185 Bear1 = GEODESIC_DEG2RAD(Bear1);
186 if (Lon2) *Lon2 = Lon1;
187 if (Lat2) *Lat2 = Lat1;
188 if (Bear2) *Bear2 = Bear1;
205 double u2, A, B, C, twosigmam, costwosigmam, cos2twosigmam, deltasigma,
209 rLat1 = (1.0 - f) * tan(Lat1);
210 cosrLat1 = 1.0 / sqrt(1.0 + rLat1 * rLat1);
211 sinrLat1 = rLat1 * cosrLat1;
212 sinalpha1 = sin(Bear1);
213 cosalpha1 = cos(Bear1);
215 sigma1 = atan2(rLat1, cosalpha1);
217 sinalpha = cosrLat1 * sinalpha1;
218 sin2alpha = sinalpha * sinalpha;
220 cos2alpha = 1 - (sin2alpha);
221 u2 = cos2alpha * ((a * a) - (b * b)) / (b * b);
223 (u2 / 16384) * (4096 + u2 * (-768 + u2 * (320 - 175 * u2)));
225 B = (u2 / 1024) * (256 + u2 * (-128 + u2 * (74 - 47 * u2)));
227 distoverba = Dist / (b * A);
229 sigmaprime = sigma - 1.0;
230 while (fabs(sigmaprime - sigma) > 1e-12) {
231 twosigmam = 2 * sigma1 + sigma;
232 costwosigmam = cos(twosigmam);
233 cos2twosigmam = costwosigmam * costwosigmam;
234 sinsigma = sin(sigma);
236 deltasigma = B * sinsigma *
237 (costwosigmam + (B / 4.0) *
238 (cos(sigma) * (-1 + 2 * cos2twosigmam) -
239 (B / 6.0) * costwosigmam *
240 (-3 + 4 * sinsigma * sinsigma) *
241 (-3 + 4 * cos2twosigmam)));
244 sigma = distoverba + deltasigma;
246 sinsigma = sin(sigma);
247 cossigma = cos(sigma);
248 twosigmam = 2 * sigma1 + sigma;
249 costwosigmam = cos(twosigmam);
250 cos2twosigmam = costwosigmam * costwosigmam;
254 sinrLat1 * cossigma + cosrLat1 * sinsigma * cosalpha1,
256 sqrt(sin2alpha + pow(sinrLat1 * sinsigma -
257 cosrLat1 * cossigma * cosalpha1,
259 *Lat2 = GEODESIC_RAD2DEG(*Lat2);
263 lambda = atan2(sinsigma * sinalpha1,
264 cosrLat1 * cossigma - sinrLat1 * sinsigma * cosalpha1);
266 C = (f / 16.0) * cos2alpha * (4 + f * (4 - 3 * cos2alpha));
268 L = lambda - (1 - C) * f * sinalpha *
269 (sigma + C * sinsigma *
271 C * cossigma * (-1 + 2 * cos2twosigmam)));
272 *Lon2 = GEODESIC_RAD2DEG(Lon1 + L);
276 *Bear2 = atan2(sinalpha,
277 -sinrLat1 * sinsigma + cosrLat1 * cossigma * cosalpha1);
278 *Bear2 = GEODESIC_RAD2DEG(*Bear2);