geodesic_wgs84 1.32.17 → 1.44.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Makefile +4 -4
- data/README.md +3 -1
- data/ext/geodesic_wgs84/geodesic.c +436 -287
- data/ext/geodesic_wgs84/geodesic.h +114 -72
- data/geodesic_wgs84.gemspec +1 -1
- data/lib/geodesic_wgs84/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c45c045313d94c86f6486192b2ab4e721e9651ca
|
4
|
+
data.tar.gz: 8b4b139acfe9387ad9ffecfe77ee29d849564ba8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b623d79f1ac14608b19dfe37d07ec05889e3f6e0d4fa50b5290ca38b0fbd640cb82a204473232e3e14be165c0b63bbba18f5fbb054ddf502911758ef8114fc0b
|
7
|
+
data.tar.gz: b57d30db4536ad153f163b0ff13286ff55e4e30244f23195bb84ffa357f8fd5b19b8bb10994bb40baa041669c2ef4ec63204af57f9d5c115bc7c6483ab3fcb71
|
data/Makefile
CHANGED
@@ -9,14 +9,14 @@ all: build
|
|
9
9
|
rel: build
|
10
10
|
vim lib/geodesic_wgs84/version.rb
|
11
11
|
git commit -a
|
12
|
-
|
12
|
+
gem uninstall geodesic_wgs84 --all
|
13
13
|
rake release
|
14
14
|
|
15
15
|
install: build
|
16
16
|
git commit -a
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
gem uninstall geodesic_wgs84 --all
|
18
|
+
rake install
|
19
|
+
rm -rf pkg
|
20
20
|
|
21
21
|
build:
|
22
22
|
rake compile
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# GeodesicWgs84 -- Distance calculations on the Earth's surface
|
2
2
|
|
3
3
|
This an implementation of the geodesic algorithms described in
|
4
|
-
C. F. F. Karney "Algorithms for geodesics" (
|
4
|
+
C. F. F. Karney "Algorithms for geodesics" ( https://dx.doi.org/10.1007/s00190-012-0578-z ).
|
5
5
|
It uses the WGS84 standard as a reference ( http://en.wikipedia.org/wiki/World_Geodetic_System ).
|
6
6
|
|
7
7
|
### From the abstract of this article
|
@@ -17,6 +17,8 @@ of geodesics to be computed.
|
|
17
17
|
The files geodesic.c and geodesic.h make up for the real work and can be found
|
18
18
|
at ( http://geographiclib.sourceforge.net/html/C/ ).
|
19
19
|
|
20
|
+
The version of this gem aims to follow the author's version.
|
21
|
+
|
20
22
|
## Installation
|
21
23
|
|
22
24
|
Add this line to your application's Gemfile:
|
@@ -13,12 +13,12 @@
|
|
13
13
|
* C. F. F. Karney,
|
14
14
|
* Algorithms for geodesics,
|
15
15
|
* J. Geodesy <b>87</b>, 43--55 (2013);
|
16
|
-
*
|
16
|
+
* https://dx.doi.org/10.1007/s00190-012-0578-z
|
17
17
|
* Addenda: http://geographiclib.sf.net/geod-addenda.html
|
18
18
|
*
|
19
19
|
* See the comments in geodesic.h for documentation.
|
20
20
|
*
|
21
|
-
* Copyright (c) Charles Karney (2012-
|
21
|
+
* Copyright (c) Charles Karney (2012-2015) <charles@karney.com> and licensed
|
22
22
|
* under the MIT/X11 License. For more information, see
|
23
23
|
* http://geographiclib.sourceforge.net/
|
24
24
|
*/
|
@@ -27,8 +27,10 @@
|
|
27
27
|
#include <math.h>
|
28
28
|
|
29
29
|
#define GEOGRAPHICLIB_GEODESIC_ORDER 6
|
30
|
+
#define nA1 GEOGRAPHICLIB_GEODESIC_ORDER
|
30
31
|
#define nC1 GEOGRAPHICLIB_GEODESIC_ORDER
|
31
32
|
#define nC1p GEOGRAPHICLIB_GEODESIC_ORDER
|
33
|
+
#define nA2 GEOGRAPHICLIB_GEODESIC_ORDER
|
32
34
|
#define nC2 GEOGRAPHICLIB_GEODESIC_ORDER
|
33
35
|
#define nA3 GEOGRAPHICLIB_GEODESIC_ORDER
|
34
36
|
#define nA3x nA3
|
@@ -36,6 +38,7 @@
|
|
36
38
|
#define nC3x ((nC3 * (nC3 - 1)) / 2)
|
37
39
|
#define nC4 GEOGRAPHICLIB_GEODESIC_ORDER
|
38
40
|
#define nC4x ((nC4 * (nC4 + 1)) / 2)
|
41
|
+
#define nC (GEOGRAPHICLIB_GEODESIC_ORDER + 1)
|
39
42
|
|
40
43
|
typedef double real;
|
41
44
|
typedef int boolx;
|
@@ -137,6 +140,12 @@ static real sumx(real u, real v, real* t) {
|
|
137
140
|
return s;
|
138
141
|
}
|
139
142
|
|
143
|
+
static real polyval(int N, const real p[], real x) {
|
144
|
+
real y = N < 0 ? 0 : *p++;
|
145
|
+
while (--N >= 0) y = y * x + *p++;
|
146
|
+
return y;
|
147
|
+
}
|
148
|
+
|
140
149
|
static real minx(real x, real y)
|
141
150
|
{ return x < y ? x : y; }
|
142
151
|
|
@@ -146,24 +155,29 @@ static real maxx(real x, real y)
|
|
146
155
|
static void swapx(real* x, real* y)
|
147
156
|
{ real t = *x; *x = *y; *y = t; }
|
148
157
|
|
149
|
-
static void
|
158
|
+
static void norm2(real* sinx, real* cosx) {
|
150
159
|
real r = hypotx(*sinx, *cosx);
|
151
160
|
*sinx /= r;
|
152
161
|
*cosx /= r;
|
153
162
|
}
|
154
163
|
|
155
|
-
static real AngNormalize(real x)
|
156
|
-
|
157
|
-
|
158
|
-
|
164
|
+
static real AngNormalize(real x) {
|
165
|
+
x = fmod(x, (real)(360));
|
166
|
+
return x < -180 ? x + 360 : (x < 180 ? x : x - 360);
|
167
|
+
}
|
168
|
+
|
169
|
+
static real LatFix(real x)
|
170
|
+
{ return fabs(x) > 90 ? NaN : x; }
|
159
171
|
|
160
172
|
static real AngDiff(real x, real y) {
|
161
|
-
real t, d = sumx(
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
173
|
+
real t, d = - AngNormalize(sumx(AngNormalize(x), AngNormalize(-y), &t));
|
174
|
+
/* Here y - x = d - t (mod 360), exactly, where d is in (-180,180] and
|
175
|
+
* abs(t) <= eps (eps = 2^-45 for doubles). The only case where the
|
176
|
+
* addition of t takes the result outside the range (-180,180] is d = 180
|
177
|
+
* and t < 0. The case, d = -180 + eps, t = eps, can't happen, since
|
178
|
+
* sum would have returned the exact result in such a case (i.e., given t
|
179
|
+
* = 0). */
|
180
|
+
return (d == 180 && t < 0 ? -180 : d) - t;
|
167
181
|
}
|
168
182
|
|
169
183
|
static real AngRound(real x) {
|
@@ -171,7 +185,49 @@ static real AngRound(real x) {
|
|
171
185
|
volatile real y = fabs(x);
|
172
186
|
/* The compiler mustn't "simplify" z - (z - y) to y */
|
173
187
|
y = y < z ? z - (z - y) : y;
|
174
|
-
return x < 0 ? -y : y;
|
188
|
+
return x < 0 ? 0 - y : y;
|
189
|
+
}
|
190
|
+
|
191
|
+
static void sincosdx(real x, real* sinx, real* cosx) {
|
192
|
+
/* In order to minimize round-off errors, this function exactly reduces
|
193
|
+
* the argument to the range [-45, 45] before converting it to radians. */
|
194
|
+
real r, s, c; int q;
|
195
|
+
r = fmod(x, (real)(360));
|
196
|
+
q = (int)(floor(r / 90 + (real)(0.5)));
|
197
|
+
r -= 90 * q;
|
198
|
+
/* now abs(r) <= 45 */
|
199
|
+
r *= degree;
|
200
|
+
/* Possibly could call the gnu extension sincos */
|
201
|
+
s = sin(r); c = cos(r);
|
202
|
+
switch ((unsigned)q & 3U) {
|
203
|
+
case 0U: *sinx = s; *cosx = c; break;
|
204
|
+
case 1U: *sinx = c; *cosx = 0 - s; break;
|
205
|
+
case 2U: *sinx = 0 - s; *cosx = 0 - c; break;
|
206
|
+
default: *sinx = 0 - c; *cosx = s; break; /* case 3U */
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
static real atan2dx(real y, real x) {
|
211
|
+
/* In order to minimize round-off errors, this function rearranges the
|
212
|
+
* arguments so that result of atan2 is in the range [-pi/4, pi/4] before
|
213
|
+
* converting it to degrees and mapping the result to the correct
|
214
|
+
* quadrant. */
|
215
|
+
int q = 0; real ang;
|
216
|
+
if (fabs(y) > fabs(x)) { swapx(&x, &y); q = 2; }
|
217
|
+
if (x < 0) { x = -x; ++q; }
|
218
|
+
/* here x >= 0 and x >= abs(y), so angle is in [-pi/4, pi/4] */
|
219
|
+
ang = atan2(y, x) / degree;
|
220
|
+
switch (q) {
|
221
|
+
/* Note that atan2d(-0.0, 1.0) will return -0. However, we expect that
|
222
|
+
* atan2d will not be called with y = -0. If need be, include
|
223
|
+
*
|
224
|
+
* case 0: ang = 0 + ang; break;
|
225
|
+
*/
|
226
|
+
case 1: ang = (y > 0 ? 180 : -180) - ang; break;
|
227
|
+
case 2: ang = 90 - ang; break;
|
228
|
+
case 3: ang = -90 + ang; break;
|
229
|
+
}
|
230
|
+
return ang;
|
175
231
|
}
|
176
232
|
|
177
233
|
static void A3coeff(struct geod_geodesic* g);
|
@@ -186,9 +242,9 @@ static void Lengths(const struct geod_geodesic* g,
|
|
186
242
|
real ssig2, real csig2, real dn2,
|
187
243
|
real cbet1, real cbet2,
|
188
244
|
real* ps12b, real* pm12b, real* pm0,
|
189
|
-
|
190
|
-
/* Scratch
|
191
|
-
real
|
245
|
+
real* pM12, real* pM21,
|
246
|
+
/* Scratch area of the right size */
|
247
|
+
real Ca[]);
|
192
248
|
static real Astroid(real x, real y);
|
193
249
|
static real InverseStart(const struct geod_geodesic* g,
|
194
250
|
real sbet1, real cbet1, real dn1,
|
@@ -199,8 +255,8 @@ static real InverseStart(const struct geod_geodesic* g,
|
|
199
255
|
real* psalp2, real* pcalp2,
|
200
256
|
/* Only updated for short lines */
|
201
257
|
real* pdnm,
|
202
|
-
/* Scratch
|
203
|
-
real
|
258
|
+
/* Scratch area of the right size */
|
259
|
+
real Ca[]);
|
204
260
|
static real Lambda12(const struct geod_geodesic* g,
|
205
261
|
real sbet1, real cbet1, real dn1,
|
206
262
|
real sbet2, real cbet2, real dn2,
|
@@ -211,8 +267,8 @@ static real Lambda12(const struct geod_geodesic* g,
|
|
211
267
|
real* pssig2, real* pcsig2,
|
212
268
|
real* peps, real* pdomg12,
|
213
269
|
boolx diffp, real* pdlam12,
|
214
|
-
/* Scratch
|
215
|
-
real
|
270
|
+
/* Scratch area of the right size */
|
271
|
+
real Ca[]);
|
216
272
|
static real A3f(const struct geod_geodesic* g, real eps);
|
217
273
|
static void C3f(const struct geod_geodesic* g, real eps, real c[]);
|
218
274
|
static void C4f(const struct geod_geodesic* g, real eps, real c[]);
|
@@ -222,6 +278,7 @@ static void C1pf(real eps, real c[]);
|
|
222
278
|
static real A2m1f(real eps);
|
223
279
|
static void C2f(real eps, real c[]);
|
224
280
|
static int transit(real lon1, real lon2);
|
281
|
+
static int transitdirect(real lon1, real lon2);
|
225
282
|
static void accini(real s[]);
|
226
283
|
static void acccopy(const real s[], real t[]);
|
227
284
|
static void accadd(real s[], real y);
|
@@ -261,7 +318,7 @@ void geod_init(struct geod_geodesic* g, real a, real f) {
|
|
261
318
|
void geod_lineinit(struct geod_geodesicline* l,
|
262
319
|
const struct geod_geodesic* g,
|
263
320
|
real lat1, real lon1, real azi1, unsigned caps) {
|
264
|
-
real
|
321
|
+
real cbet1, sbet1, eps;
|
265
322
|
l->a = g->a;
|
266
323
|
l->f = g->f;
|
267
324
|
l->b = g->b;
|
@@ -269,25 +326,18 @@ void geod_lineinit(struct geod_geodesicline* l,
|
|
269
326
|
l->f1 = g->f1;
|
270
327
|
/* If caps is 0 assume the standard direct calculation */
|
271
328
|
l->caps = (caps ? caps : GEOD_DISTANCE_IN | GEOD_LONGITUDE) |
|
272
|
-
|
329
|
+
/* always allow latitude and azimuth and unrolling of longitude */
|
330
|
+
GEOD_LATITUDE | GEOD_AZIMUTH | GEOD_LONG_UNROLL;
|
273
331
|
|
274
|
-
|
275
|
-
azi1 = AngRound(AngNormalize(azi1));
|
276
|
-
lon1 = AngNormalize(lon1);
|
277
|
-
l->lat1 = lat1;
|
332
|
+
l->lat1 = LatFix(lat1);
|
278
333
|
l->lon1 = lon1;
|
279
|
-
l->azi1 = azi1;
|
280
|
-
/*
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
l->salp1 = azi1 == -180 ? 0 : sin(alp1);
|
285
|
-
l->calp1 = fabs(azi1) == 90 ? 0 : cos(alp1);
|
286
|
-
phi = lat1 * degree;
|
334
|
+
l->azi1 = AngNormalize(azi1);
|
335
|
+
/* Guard against underflow in salp0 */
|
336
|
+
sincosdx(AngRound(l->azi1), &l->salp1, &l->calp1);
|
337
|
+
|
338
|
+
sincosdx(AngRound(l->lat1), &sbet1, &cbet1); sbet1 *= l->f1;
|
287
339
|
/* Ensure cbet1 = +epsilon at poles */
|
288
|
-
sbet1
|
289
|
-
cbet1 = fabs(lat1) == 90 ? tiny : cos(phi);
|
290
|
-
SinCosNorm(&sbet1, &cbet1);
|
340
|
+
norm2(&sbet1, &cbet1); cbet1 = maxx(tiny, cbet1);
|
291
341
|
l->dn1 = sqrt(1 + g->ep2 * sq(sbet1));
|
292
342
|
|
293
343
|
/* Evaluate alp0 from sin(alp1) * cos(bet1) = sin(alp0), */
|
@@ -306,8 +356,8 @@ void geod_lineinit(struct geod_geodesicline* l,
|
|
306
356
|
* With alp0 = 0, omg1 = 0 for alp1 = 0, omg1 = pi for alp1 = pi. */
|
307
357
|
l->ssig1 = sbet1; l->somg1 = l->salp0 * sbet1;
|
308
358
|
l->csig1 = l->comg1 = sbet1 != 0 || l->calp1 != 0 ? cbet1 * l->calp1 : 1;
|
309
|
-
|
310
|
-
/*
|
359
|
+
norm2(&l->ssig1, &l->csig1); /* sig1 in (-pi, pi] */
|
360
|
+
/* norm2(somg1, comg1); -- don't need to normalize! */
|
311
361
|
|
312
362
|
l->k2 = sq(l->calp0) * g->ep2;
|
313
363
|
eps = l->k2 / (2 * (1 + sqrt(1 + l->k2)) + l->k2);
|
@@ -349,7 +399,7 @@ void geod_lineinit(struct geod_geodesicline* l,
|
|
349
399
|
}
|
350
400
|
|
351
401
|
real geod_genposition(const struct geod_geodesicline* l,
|
352
|
-
|
402
|
+
unsigned flags, real s12_a12,
|
353
403
|
real* plat2, real* plon2, real* pazi2,
|
354
404
|
real* ps12, real* pm12,
|
355
405
|
real* pM12, real* pM21,
|
@@ -371,18 +421,14 @@ real geod_genposition(const struct geod_geodesicline* l,
|
|
371
421
|
|
372
422
|
outmask &= l->caps & OUT_ALL;
|
373
423
|
if (!( TRUE /*Init()*/ &&
|
374
|
-
(
|
424
|
+
(flags & GEOD_ARCMODE || (l->caps & GEOD_DISTANCE_IN & OUT_ALL)) ))
|
375
425
|
/* Uninitialized or impossible distance calculation requested */
|
376
426
|
return NaN;
|
377
427
|
|
378
|
-
if (
|
379
|
-
real s12a;
|
428
|
+
if (flags & GEOD_ARCMODE) {
|
380
429
|
/* Interpret s12_a12 as spherical arc length */
|
381
430
|
sig12 = s12_a12 * degree;
|
382
|
-
|
383
|
-
s12a -= 180 * floor(s12a / 180);
|
384
|
-
ssig12 = s12a == 0 ? 0 : sin(sig12);
|
385
|
-
csig12 = s12a == 90 ? 0 : cos(sig12);
|
431
|
+
sincosdx(s12_a12, &ssig12, &csig12);
|
386
432
|
} else {
|
387
433
|
/* Interpret s12_a12 as distance */
|
388
434
|
real
|
@@ -435,7 +481,7 @@ real geod_genposition(const struct geod_geodesicline* l,
|
|
435
481
|
csig2 = l->csig1 * csig12 - l->ssig1 * ssig12;
|
436
482
|
dn2 = sqrt(1 + l->k2 * sq(ssig2));
|
437
483
|
if (outmask & (GEOD_DISTANCE | GEOD_REDUCEDLENGTH | GEOD_GEODESICSCALE)) {
|
438
|
-
if (
|
484
|
+
if (flags & GEOD_ARCMODE || fabs(l->f) > 0.01)
|
439
485
|
B12 = SinCosSeries(TRUE, ssig2, csig2, l->C1a, nC1);
|
440
486
|
AB1 = (1 + l->A1m1) * (B12 - l->B11);
|
441
487
|
}
|
@@ -446,34 +492,36 @@ real geod_genposition(const struct geod_geodesicline* l,
|
|
446
492
|
if (cbet2 == 0)
|
447
493
|
/* I.e., salp0 = 0, csig2 = 0. Break the degeneracy in this case */
|
448
494
|
cbet2 = csig2 = tiny;
|
449
|
-
/* tan(omg2) = sin(alp0) * tan(sig2) */
|
450
|
-
somg2 = l->salp0 * ssig2; comg2 = csig2; /* No need to normalize */
|
451
495
|
/* tan(alp0) = cos(sig2)*tan(alp2) */
|
452
496
|
salp2 = l->salp0; calp2 = l->calp0 * csig2; /* No need to normalize */
|
453
|
-
/* omg12 = omg2 - omg1 */
|
454
|
-
omg12 = atan2(somg2 * l->comg1 - comg2 * l->somg1,
|
455
|
-
comg2 * l->comg1 + somg2 * l->somg1);
|
456
497
|
|
457
498
|
if (outmask & GEOD_DISTANCE)
|
458
|
-
s12 =
|
499
|
+
s12 = flags & GEOD_ARCMODE ? l->b * ((1 + l->A1m1) * sig12 + AB1) : s12_a12;
|
459
500
|
|
460
501
|
if (outmask & GEOD_LONGITUDE) {
|
502
|
+
int E = l->salp0 < 0 ? -1 : 1; /* east or west going? */
|
503
|
+
/* tan(omg2) = sin(alp0) * tan(sig2) */
|
504
|
+
somg2 = l->salp0 * ssig2; comg2 = csig2; /* No need to normalize */
|
505
|
+
/* omg12 = omg2 - omg1 */
|
506
|
+
omg12 = flags & GEOD_LONG_UNROLL
|
507
|
+
? E * (sig12
|
508
|
+
- (atan2( ssig2, csig2) - atan2( l->ssig1, l->csig1))
|
509
|
+
+ (atan2(E * somg2, comg2) - atan2(E * l->somg1, l->comg1)))
|
510
|
+
: atan2(somg2 * l->comg1 - comg2 * l->somg1,
|
511
|
+
comg2 * l->comg1 + somg2 * l->somg1);
|
461
512
|
lam12 = omg12 + l->A3c *
|
462
513
|
( sig12 + (SinCosSeries(TRUE, ssig2, csig2, l->C3a, nC3-1)
|
463
514
|
- l->B31));
|
464
515
|
lon12 = lam12 / degree;
|
465
|
-
|
466
|
-
|
467
|
-
lon12 = AngNormalize2(lon12);
|
468
|
-
lon2 = AngNormalize(l->lon1 + lon12);
|
516
|
+
lon2 = flags & GEOD_LONG_UNROLL ? l->lon1 + lon12 :
|
517
|
+
AngNormalize(AngNormalize(l->lon1) + AngNormalize(lon12));
|
469
518
|
}
|
470
519
|
|
471
520
|
if (outmask & GEOD_LATITUDE)
|
472
|
-
lat2 =
|
521
|
+
lat2 = atan2dx(sbet2, l->f1 * cbet2);
|
473
522
|
|
474
523
|
if (outmask & GEOD_AZIMUTH)
|
475
|
-
|
476
|
-
azi2 = 0 - atan2(-salp2, calp2) / degree;
|
524
|
+
azi2 = atan2dx(salp2, calp2);
|
477
525
|
|
478
526
|
if (outmask & (GEOD_REDUCEDLENGTH | GEOD_GEODESICSCALE)) {
|
479
527
|
real
|
@@ -497,7 +545,7 @@ real geod_genposition(const struct geod_geodesicline* l,
|
|
497
545
|
B42 = SinCosSeries(FALSE, ssig2, csig2, l->C4a, nC4);
|
498
546
|
real salp12, calp12;
|
499
547
|
if (l->calp0 == 0 || l->salp0 == 0) {
|
500
|
-
/* alp12 = alp2 - alp1, used in atan2 so no need to
|
548
|
+
/* alp12 = alp2 - alp1, used in atan2 so no need to normalize */
|
501
549
|
salp12 = salp2 * l->calp1 - calp2 * l->salp1;
|
502
550
|
calp12 = calp2 * l->calp1 + salp2 * l->salp1;
|
503
551
|
/* The right thing appears to happen if alp1 = +/-180 and alp2 = 0, viz
|
@@ -542,7 +590,7 @@ real geod_genposition(const struct geod_geodesicline* l,
|
|
542
590
|
if (outmask & GEOD_AREA)
|
543
591
|
*pS12 = S12;
|
544
592
|
|
545
|
-
return
|
593
|
+
return flags & GEOD_ARCMODE ? s12_a12 : sig12 / degree;
|
546
594
|
}
|
547
595
|
|
548
596
|
void geod_position(const struct geod_geodesicline* l, real s12,
|
@@ -552,7 +600,7 @@ void geod_position(const struct geod_geodesicline* l, real s12,
|
|
552
600
|
|
553
601
|
real geod_gendirect(const struct geod_geodesic* g,
|
554
602
|
real lat1, real lon1, real azi1,
|
555
|
-
|
603
|
+
unsigned flags, real s12_a12,
|
556
604
|
real* plat2, real* plon2, real* pazi2,
|
557
605
|
real* ps12, real* pm12, real* pM12, real* pM21,
|
558
606
|
real* pS12) {
|
@@ -568,8 +616,9 @@ real geod_gendirect(const struct geod_geodesic* g,
|
|
568
616
|
|
569
617
|
geod_lineinit(&l, g, lat1, lon1, azi1,
|
570
618
|
/* Automatically supply GEOD_DISTANCE_IN if necessary */
|
571
|
-
outmask |
|
572
|
-
|
619
|
+
outmask |
|
620
|
+
(flags & GEOD_ARCMODE ? GEOD_NONE : GEOD_DISTANCE_IN));
|
621
|
+
return geod_genposition(&l, flags, s12_a12,
|
573
622
|
plat2, plon2, pazi2, ps12, pm12, pM12, pM21, pS12);
|
574
623
|
}
|
575
624
|
|
@@ -577,7 +626,7 @@ void geod_direct(const struct geod_geodesic* g,
|
|
577
626
|
real lat1, real lon1, real azi1,
|
578
627
|
real s12,
|
579
628
|
real* plat2, real* plon2, real* pazi2) {
|
580
|
-
geod_gendirect(g, lat1, lon1, azi1,
|
629
|
+
geod_gendirect(g, lat1, lon1, azi1, GEOD_NOFLAGS, s12, plat2, plon2, pazi2,
|
581
630
|
0, 0, 0, 0, 0);
|
582
631
|
}
|
583
632
|
|
@@ -588,11 +637,10 @@ real geod_geninverse(const struct geod_geodesic* g,
|
|
588
637
|
real s12 = 0, azi1 = 0, azi2 = 0, m12 = 0, M12 = 0, M21 = 0, S12 = 0;
|
589
638
|
real lon12;
|
590
639
|
int latsign, lonsign, swapp;
|
591
|
-
real
|
640
|
+
real sbet1, cbet1, sbet2, cbet2, s12x = 0, m12x = 0;
|
592
641
|
real dn1, dn2, lam12, slam12, clam12;
|
593
642
|
real a12 = 0, sig12, calp1 = 0, salp1 = 0, calp2 = 0, salp2 = 0;
|
594
|
-
|
595
|
-
real C1a[nC1 + 1], C2a[nC2 + 1], C3a[nC3];
|
643
|
+
real Ca[nC];
|
596
644
|
boolx meridian;
|
597
645
|
real omg12 = 0;
|
598
646
|
|
@@ -607,15 +655,14 @@ real geod_geninverse(const struct geod_geodesic* g,
|
|
607
655
|
/* Compute longitude difference (AngDiff does this carefully). Result is
|
608
656
|
* in [-180, 180] but -180 is only for west-going geodesics. 180 is for
|
609
657
|
* east-going and meridional geodesics. */
|
610
|
-
lon12 = AngDiff(AngNormalize(lon1), AngNormalize(lon2));
|
611
658
|
/* If very close to being on the same half-meridian, then make it so. */
|
612
|
-
lon12 = AngRound(
|
659
|
+
lon12 = AngRound(AngDiff(lon1, lon2));
|
613
660
|
/* Make longitude difference positive. */
|
614
661
|
lonsign = lon12 >= 0 ? 1 : -1;
|
615
662
|
lon12 *= lonsign;
|
616
663
|
/* If really close to the equator, treat as on equator. */
|
617
|
-
lat1 = AngRound(lat1);
|
618
|
-
lat2 = AngRound(lat2);
|
664
|
+
lat1 = AngRound(LatFix(lat1));
|
665
|
+
lat2 = AngRound(LatFix(lat2));
|
619
666
|
/* Swap points so that point with higher (abs) latitude is point 1 */
|
620
667
|
swapp = fabs(lat1) >= fabs(lat2) ? 1 : -1;
|
621
668
|
if (swapp < 0) {
|
@@ -638,17 +685,13 @@ real geod_geninverse(const struct geod_geodesic* g,
|
|
638
685
|
* check, e.g., on verifying quadrants in atan2. In addition, this
|
639
686
|
* enforces some symmetries in the results returned. */
|
640
687
|
|
641
|
-
|
688
|
+
sincosdx(lat1, &sbet1, &cbet1); sbet1 *= g->f1;
|
642
689
|
/* Ensure cbet1 = +epsilon at poles */
|
643
|
-
sbet1
|
644
|
-
cbet1 = lat1 == -90 ? tiny : cos(phi);
|
645
|
-
SinCosNorm(&sbet1, &cbet1);
|
690
|
+
norm2(&sbet1, &cbet1); cbet1 = maxx(tiny, cbet1);
|
646
691
|
|
647
|
-
|
692
|
+
sincosdx(lat2, &sbet2, &cbet2); sbet2 *= g->f1;
|
648
693
|
/* Ensure cbet2 = +epsilon at poles */
|
649
|
-
sbet2
|
650
|
-
cbet2 = fabs(lat2) == 90 ? tiny : cos(phi);
|
651
|
-
SinCosNorm(&sbet2, &cbet2);
|
694
|
+
norm2(&sbet2, &cbet2); cbet2 = maxx(tiny, cbet2);
|
652
695
|
|
653
696
|
/* If cbet1 < -sbet1, then cbet2 - cbet1 is a sensitive measure of the
|
654
697
|
* |bet1| - |bet2|. Alternatively (cbet1 >= -sbet1), abs(sbet2) + sbet1 is
|
@@ -670,8 +713,7 @@ real geod_geninverse(const struct geod_geodesic* g,
|
|
670
713
|
dn2 = sqrt(1 + g->ep2 * sq(sbet2));
|
671
714
|
|
672
715
|
lam12 = lon12 * degree;
|
673
|
-
|
674
|
-
clam12 = cos(lam12); /* lon12 == 90 isn't interesting */
|
716
|
+
sincosdx(lon12, &slam12, &clam12);
|
675
717
|
|
676
718
|
meridian = lat1 == -90 || slam12 == 0;
|
677
719
|
|
@@ -691,20 +733,22 @@ real geod_geninverse(const struct geod_geodesic* g,
|
|
691
733
|
/* sig12 = sig2 - sig1 */
|
692
734
|
sig12 = atan2(maxx(csig1 * ssig2 - ssig1 * csig2, (real)(0)),
|
693
735
|
csig1 * csig2 + ssig1 * ssig2);
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
}
|
736
|
+
Lengths(g, g->n, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2,
|
737
|
+
cbet1, cbet2, &s12x, &m12x, 0,
|
738
|
+
outmask & GEOD_GEODESICSCALE ? &M12 : 0,
|
739
|
+
outmask & GEOD_GEODESICSCALE ? &M21 : 0,
|
740
|
+
Ca);
|
700
741
|
/* Add the check for sig12 since zero length geodesics might yield m12 <
|
701
742
|
* 0. Test case was
|
702
743
|
*
|
703
|
-
* echo 20.001 0 20.001 0 |
|
744
|
+
* echo 20.001 0 20.001 0 | GeodSolve -i
|
704
745
|
*
|
705
746
|
* In fact, we will have sig12 > pi/2 for meridional geodesic which is
|
706
747
|
* not a shortest path. */
|
707
748
|
if (sig12 < 1 || m12x >= 0) {
|
749
|
+
/* Need at least 2, to handle 90 0 90 180 */
|
750
|
+
if (sig12 < 3 * tiny)
|
751
|
+
sig12 = m12x = s12x = 0;
|
708
752
|
m12x *= g->b;
|
709
753
|
s12x *= g->b;
|
710
754
|
a12 = sig12 / degree;
|
@@ -737,7 +781,7 @@ real geod_geninverse(const struct geod_geodesic* g,
|
|
737
781
|
sig12 = InverseStart(g, sbet1, cbet1, dn1, sbet2, cbet2, dn2,
|
738
782
|
lam12,
|
739
783
|
&salp1, &calp1, &salp2, &calp2, &dnm,
|
740
|
-
|
784
|
+
Ca);
|
741
785
|
|
742
786
|
if (sig12 >= 0) {
|
743
787
|
/* Short lines (InverseStart sets salp2, calp2, dnm) */
|
@@ -768,10 +812,10 @@ real geod_geninverse(const struct geod_geodesic* g,
|
|
768
812
|
for (tripn = FALSE, tripb = FALSE; numit < maxit2; ++numit) {
|
769
813
|
/* the WGS84 test set: mean = 1.47, sd = 1.25, max = 16
|
770
814
|
* WGS84 and random input: mean = 2.85, sd = 0.60 */
|
771
|
-
real dv,
|
815
|
+
real dv = 0,
|
772
816
|
v = (Lambda12(g, sbet1, cbet1, dn1, sbet2, cbet2, dn2, salp1, calp1,
|
773
817
|
&salp2, &calp2, &sig12, &ssig1, &csig1, &ssig2, &csig2,
|
774
|
-
&eps, &omg12, numit < maxit1, &dv,
|
818
|
+
&eps, &omg12, numit < maxit1, &dv, Ca)
|
775
819
|
- lam12);
|
776
820
|
/* 2 * tol0 is approximately 1 ulp for a number in [0, pi]. */
|
777
821
|
/* Reversed test to allow escape with NaNs */
|
@@ -790,7 +834,7 @@ real geod_geninverse(const struct geod_geodesic* g,
|
|
790
834
|
if (nsalp1 > 0 && fabs(dalp1) < pi) {
|
791
835
|
calp1 = calp1 * cdalp1 - salp1 * sdalp1;
|
792
836
|
salp1 = nsalp1;
|
793
|
-
|
837
|
+
norm2(&salp1, &calp1);
|
794
838
|
/* In some regimes we don't get quadratic convergence because
|
795
839
|
* slope -> 0. So use convergence conditions based on epsilon
|
796
840
|
* instead of sqrt(epsilon). */
|
@@ -808,17 +852,15 @@ real geod_geninverse(const struct geod_geodesic* g,
|
|
808
852
|
* WGS84 and random input: mean = 4.74, sd = 0.99 */
|
809
853
|
salp1 = (salp1a + salp1b)/2;
|
810
854
|
calp1 = (calp1a + calp1b)/2;
|
811
|
-
|
855
|
+
norm2(&salp1, &calp1);
|
812
856
|
tripn = FALSE;
|
813
857
|
tripb = (fabs(salp1a - salp1) + (calp1a - calp1) < tolb ||
|
814
858
|
fabs(salp1 - salp1b) + (calp1 - calp1b) < tolb);
|
815
859
|
}
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
(outmask & GEOD_GEODESICSCALE) != 0U, &M12, &M21, C1a, C2a);
|
821
|
-
}
|
860
|
+
Lengths(g, eps, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2,
|
861
|
+
cbet1, cbet2, &s12x, &m12x, 0,
|
862
|
+
outmask & GEOD_GEODESICSCALE ? &M12 : 0,
|
863
|
+
outmask & GEOD_GEODESICSCALE ? &M21 : 0, Ca);
|
822
864
|
m12x *= g->b;
|
823
865
|
s12x *= g->b;
|
824
866
|
a12 = sig12 / degree;
|
@@ -847,13 +889,12 @@ real geod_geninverse(const struct geod_geodesic* g,
|
|
847
889
|
eps = k2 / (2 * (1 + sqrt(1 + k2)) + k2),
|
848
890
|
/* Multiplier = a^2 * e^2 * cos(alpha0) * sin(alpha0). */
|
849
891
|
A4 = sq(g->a) * calp0 * salp0 * g->e2;
|
850
|
-
real C4a[nC4];
|
851
892
|
real B41, B42;
|
852
|
-
|
853
|
-
|
854
|
-
C4f(g, eps,
|
855
|
-
B41 = SinCosSeries(FALSE, ssig1, csig1,
|
856
|
-
B42 = SinCosSeries(FALSE, ssig2, csig2,
|
893
|
+
norm2(&ssig1, &csig1);
|
894
|
+
norm2(&ssig2, &csig2);
|
895
|
+
C4f(g, eps, Ca);
|
896
|
+
B41 = SinCosSeries(FALSE, ssig1, csig1, Ca, nC4);
|
897
|
+
B42 = SinCosSeries(FALSE, ssig2, csig2, Ca, nC4);
|
857
898
|
S12 = A4 * (B42 - B41);
|
858
899
|
} else
|
859
900
|
/* Avoid problems with indeterminate sig1, sig2 on equator */
|
@@ -904,8 +945,8 @@ real geod_geninverse(const struct geod_geodesic* g,
|
|
904
945
|
|
905
946
|
if (outmask & GEOD_AZIMUTH) {
|
906
947
|
/* minus signs give range [-180, 180). 0- converts -0 to +0. */
|
907
|
-
azi1 =
|
908
|
-
azi2 =
|
948
|
+
azi1 = atan2dx(salp1, calp1);
|
949
|
+
azi2 = atan2dx(salp2, calp2);
|
909
950
|
}
|
910
951
|
|
911
952
|
if (outmask & GEOD_DISTANCE)
|
@@ -961,42 +1002,58 @@ void Lengths(const struct geod_geodesic* g,
|
|
961
1002
|
real ssig2, real csig2, real dn2,
|
962
1003
|
real cbet1, real cbet2,
|
963
1004
|
real* ps12b, real* pm12b, real* pm0,
|
964
|
-
|
965
|
-
/* Scratch
|
966
|
-
real
|
967
|
-
real
|
968
|
-
real
|
1005
|
+
real* pM12, real* pM21,
|
1006
|
+
/* Scratch area of the right size */
|
1007
|
+
real Ca[]) {
|
1008
|
+
real m0 = 0, J12 = 0, A1 = 0, A2 = 0;
|
1009
|
+
real Cb[nC];
|
969
1010
|
|
970
1011
|
/* Return m12b = (reduced length)/b; also calculate s12b = distance/b,
|
971
1012
|
* and m0 = coefficient of secular term in expression for reduced length. */
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
1013
|
+
boolx redlp = pm12b || pm0 || pM12 || pM21;
|
1014
|
+
if (ps12b || redlp) {
|
1015
|
+
A1 = A1m1f(eps);
|
1016
|
+
C1f(eps, Ca);
|
1017
|
+
if (redlp) {
|
1018
|
+
A2 = A2m1f(eps);
|
1019
|
+
C2f(eps, Cb);
|
1020
|
+
m0 = A1 - A2;
|
1021
|
+
A2 = 1 + A2;
|
1022
|
+
}
|
1023
|
+
A1 = 1 + A1;
|
1024
|
+
}
|
1025
|
+
if (ps12b) {
|
1026
|
+
real B1 = SinCosSeries(TRUE, ssig2, csig2, Ca, nC1) -
|
1027
|
+
SinCosSeries(TRUE, ssig1, csig1, Ca, nC1);
|
1028
|
+
/* Missing a factor of b */
|
1029
|
+
*ps12b = A1 * (sig12 + B1);
|
1030
|
+
if (redlp) {
|
1031
|
+
real B2 = SinCosSeries(TRUE, ssig2, csig2, Cb, nC2) -
|
1032
|
+
SinCosSeries(TRUE, ssig1, csig1, Cb, nC2);
|
1033
|
+
J12 = m0 * sig12 + (A1 * B1 - A2 * B2);
|
1034
|
+
}
|
1035
|
+
} else if (redlp) {
|
1036
|
+
/* Assume here that nC1 >= nC2 */
|
1037
|
+
int l;
|
1038
|
+
for (l = 1; l <= nC2; ++l)
|
1039
|
+
Cb[l] = A1 * Ca[l] - A2 * Cb[l];
|
1040
|
+
J12 = m0 * sig12 + (SinCosSeries(TRUE, ssig2, csig2, Cb, nC2) -
|
1041
|
+
SinCosSeries(TRUE, ssig1, csig1, Cb, nC2));
|
1042
|
+
}
|
1043
|
+
if (pm0) *pm0 = m0;
|
1044
|
+
if (pm12b)
|
1045
|
+
/* Missing a factor of b.
|
1046
|
+
* Add parens around (csig1 * ssig2) and (ssig1 * csig2) to ensure
|
1047
|
+
* accurate cancellation in the case of coincident points. */
|
1048
|
+
*pm12b = dn2 * (csig1 * ssig2) - dn1 * (ssig1 * csig2) -
|
1049
|
+
csig1 * csig2 * J12;
|
1050
|
+
if (pM12 || pM21) {
|
989
1051
|
real csig12 = csig1 * csig2 + ssig1 * ssig2;
|
990
1052
|
real t = g->ep2 * (cbet1 - cbet2) * (cbet1 + cbet2) / (dn1 + dn2);
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
*pm12b = m12b;
|
996
|
-
*pm0 = m0;
|
997
|
-
if (scalep) {
|
998
|
-
*pM12 = M12;
|
999
|
-
*pM21 = M21;
|
1053
|
+
if (pM12)
|
1054
|
+
*pM12 = csig12 + (t * ssig2 - csig2 * J12) * ssig1 / dn1;
|
1055
|
+
if (pM21)
|
1056
|
+
*pM21 = csig12 - (t * ssig1 - csig1 * J12) * ssig2 / dn2;
|
1000
1057
|
}
|
1001
1058
|
}
|
1002
1059
|
|
@@ -1015,7 +1072,7 @@ real Astroid(real x, real y) {
|
|
1015
1072
|
S = p * q / 4, /* S = r^3 * s */
|
1016
1073
|
r2 = sq(r),
|
1017
1074
|
r3 = r * r2,
|
1018
|
-
/* The
|
1075
|
+
/* The discriminant of the quadratic equation for T3. This is zero on
|
1019
1076
|
* the evolute curve p^(1/3)+q^(1/3) = 1 */
|
1020
1077
|
disc = S * (S + 2 * r3);
|
1021
1078
|
real u = r;
|
@@ -1061,8 +1118,8 @@ real InverseStart(const struct geod_geodesic* g,
|
|
1061
1118
|
real* psalp2, real* pcalp2,
|
1062
1119
|
/* Only updated for short lines */
|
1063
1120
|
real* pdnm,
|
1064
|
-
/* Scratch
|
1065
|
-
real
|
1121
|
+
/* Scratch area of the right size */
|
1122
|
+
real Ca[]) {
|
1066
1123
|
real salp1 = 0, calp1 = 0, salp2 = 0, calp2 = 0, dnm = 0;
|
1067
1124
|
|
1068
1125
|
/* Return a starting point for Newton's method in salp1 and calp1 (function
|
@@ -1073,6 +1130,10 @@ real InverseStart(const struct geod_geodesic* g,
|
|
1073
1130
|
/* bet12 = bet2 - bet1 in [0, pi); bet12a = bet2 + bet1 in (-pi, 0] */
|
1074
1131
|
sbet12 = sbet2 * cbet1 - cbet2 * sbet1,
|
1075
1132
|
cbet12 = cbet2 * cbet1 + sbet2 * sbet1;
|
1133
|
+
real sbet12a;
|
1134
|
+
boolx shortline = cbet12 >= 0 && sbet12 < (real)(0.5) &&
|
1135
|
+
cbet2 * lam12 < (real)(0.5);
|
1136
|
+
real omg12 = lam12, somg12, comg12, ssig12, csig12;
|
1076
1137
|
#if defined(__GNUC__) && __GNUC__ == 4 && \
|
1077
1138
|
(__GNUC_MINOR__ < 6 || defined(__MINGW32__))
|
1078
1139
|
/* Volatile declaration needed to fix inverse cases
|
@@ -1081,18 +1142,14 @@ real InverseStart(const struct geod_geodesic* g,
|
|
1081
1142
|
* 89.333123580033 0 -89.333123580032997687 179.99295812360148422
|
1082
1143
|
* which otherwise fail with g++ 4.4.4 x86 -O3 (Linux)
|
1083
1144
|
* and g++ 4.4.0 (mingw) and g++ 4.6.1 (tdm mingw). */
|
1084
|
-
real sbet12a;
|
1085
1145
|
{
|
1086
1146
|
volatile real xx1 = sbet2 * cbet1;
|
1087
1147
|
volatile real xx2 = cbet2 * sbet1;
|
1088
1148
|
sbet12a = xx1 + xx2;
|
1089
1149
|
}
|
1090
1150
|
#else
|
1091
|
-
|
1151
|
+
sbet12a = sbet2 * cbet1 + cbet2 * sbet1;
|
1092
1152
|
#endif
|
1093
|
-
boolx shortline = cbet12 >= 0 && sbet12 < (real)(0.5) &&
|
1094
|
-
cbet2 * lam12 < (real)(0.5);
|
1095
|
-
real omg12 = lam12, somg12, comg12, ssig12, csig12;
|
1096
1153
|
if (shortline) {
|
1097
1154
|
real sbetm2 = sq(sbet1 + sbet2);
|
1098
1155
|
/* sin((bet1+bet2)/2)^2
|
@@ -1116,7 +1173,7 @@ real InverseStart(const struct geod_geodesic* g,
|
|
1116
1173
|
salp2 = cbet1 * somg12;
|
1117
1174
|
calp2 = sbet12 - cbet1 * sbet2 *
|
1118
1175
|
(comg12 >= 0 ? sq(somg12) / (1 + comg12) : 1 - comg12);
|
1119
|
-
|
1176
|
+
norm2(&salp2, &calp2);
|
1120
1177
|
/* Set return value */
|
1121
1178
|
sig12 = atan2(ssig12, csig12);
|
1122
1179
|
} else if (fabs(g->n) > (real)(0.1) || /* No astroid calc if too eccentric */
|
@@ -1148,13 +1205,12 @@ real InverseStart(const struct geod_geodesic* g,
|
|
1148
1205
|
real
|
1149
1206
|
cbet12a = cbet2 * cbet1 - sbet2 * sbet1,
|
1150
1207
|
bet12a = atan2(sbet12a, cbet12a);
|
1151
|
-
real m12b, m0
|
1208
|
+
real m12b, m0;
|
1152
1209
|
/* In the case of lon12 = 180, this repeats a calculation made in
|
1153
1210
|
* Inverse. */
|
1154
1211
|
Lengths(g, g->n, pi + bet12a,
|
1155
1212
|
sbet1, -cbet1, dn1, sbet2, cbet2, dn2,
|
1156
|
-
cbet1, cbet2,
|
1157
|
-
&dummy, &dummy, C1a, C2a);
|
1213
|
+
cbet1, cbet2, 0, &m12b, &m0, 0, 0, Ca);
|
1158
1214
|
x = -1 + m12b / (cbet1 * cbet2 * m0 * pi);
|
1159
1215
|
betscale = x < -(real)(0.01) ? sbet12a / x :
|
1160
1216
|
-g->f * sq(cbet1) * pi;
|
@@ -1214,8 +1270,9 @@ real InverseStart(const struct geod_geodesic* g,
|
|
1214
1270
|
calp1 = sbet12a - cbet2 * sbet1 * sq(somg12) / (1 - comg12);
|
1215
1271
|
}
|
1216
1272
|
}
|
1217
|
-
|
1218
|
-
|
1273
|
+
/* Sanity check on starting guess. Backwards check allows NaN through. */
|
1274
|
+
if (!(salp1 <= 0))
|
1275
|
+
norm2(&salp1, &calp1);
|
1219
1276
|
else {
|
1220
1277
|
salp1 = 1; calp1 = 0;
|
1221
1278
|
}
|
@@ -1241,8 +1298,8 @@ real Lambda12(const struct geod_geodesic* g,
|
|
1241
1298
|
real* pssig2, real* pcsig2,
|
1242
1299
|
real* peps, real* pdomg12,
|
1243
1300
|
boolx diffp, real* pdlam12,
|
1244
|
-
/* Scratch
|
1245
|
-
real
|
1301
|
+
/* Scratch area of the right size */
|
1302
|
+
real Ca[]) {
|
1246
1303
|
real salp2 = 0, calp2 = 0, sig12 = 0,
|
1247
1304
|
ssig1 = 0, csig1 = 0, ssig2 = 0, csig2 = 0, eps = 0, domg12 = 0, dlam12 = 0;
|
1248
1305
|
real salp0, calp0;
|
@@ -1262,8 +1319,8 @@ real Lambda12(const struct geod_geodesic* g,
|
|
1262
1319
|
* tan(omg1) = sin(alp0) * tan(sig1) = tan(omg1)=tan(alp1)*sin(bet1) */
|
1263
1320
|
ssig1 = sbet1; somg1 = salp0 * sbet1;
|
1264
1321
|
csig1 = comg1 = calp1 * cbet1;
|
1265
|
-
|
1266
|
-
/*
|
1322
|
+
norm2(&ssig1, &csig1);
|
1323
|
+
/* norm2(&somg1, &comg1); -- don't need to normalize! */
|
1267
1324
|
|
1268
1325
|
/* Enforce symmetries in the case abs(bet2) = -bet1. Need to be careful
|
1269
1326
|
* about this case, since this can yield singularities in the Newton
|
@@ -1284,8 +1341,8 @@ real Lambda12(const struct geod_geodesic* g,
|
|
1284
1341
|
* tan(omg2) = sin(alp0) * tan(sig2). */
|
1285
1342
|
ssig2 = sbet2; somg2 = salp0 * sbet2;
|
1286
1343
|
csig2 = comg2 = calp2 * cbet2;
|
1287
|
-
|
1288
|
-
/*
|
1344
|
+
norm2(&ssig2, &csig2);
|
1345
|
+
/* norm2(&somg2, &comg2); -- don't need to normalize! */
|
1289
1346
|
|
1290
1347
|
/* sig12 = sig2 - sig1, limit to [0, pi] */
|
1291
1348
|
sig12 = atan2(maxx(csig1 * ssig2 - ssig1 * csig2, (real)(0)),
|
@@ -1296,9 +1353,9 @@ real Lambda12(const struct geod_geodesic* g,
|
|
1296
1353
|
comg1 * comg2 + somg1 * somg2);
|
1297
1354
|
k2 = sq(calp0) * g->ep2;
|
1298
1355
|
eps = k2 / (2 * (1 + sqrt(1 + k2)) + k2);
|
1299
|
-
C3f(g, eps,
|
1300
|
-
B312 = (SinCosSeries(TRUE, ssig2, csig2,
|
1301
|
-
SinCosSeries(TRUE, ssig1, csig1,
|
1356
|
+
C3f(g, eps, Ca);
|
1357
|
+
B312 = (SinCosSeries(TRUE, ssig2, csig2, Ca, nC3-1) -
|
1358
|
+
SinCosSeries(TRUE, ssig1, csig1, Ca, nC3-1));
|
1302
1359
|
h0 = -g->f * A3f(g, eps);
|
1303
1360
|
domg12 = salp0 * h0 * (sig12 + B312);
|
1304
1361
|
lam12 = omg12 + domg12;
|
@@ -1307,10 +1364,8 @@ real Lambda12(const struct geod_geodesic* g,
|
|
1307
1364
|
if (calp2 == 0)
|
1308
1365
|
dlam12 = - 2 * g->f1 * dn1 / sbet1;
|
1309
1366
|
else {
|
1310
|
-
real dummy;
|
1311
1367
|
Lengths(g, eps, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2,
|
1312
|
-
cbet1, cbet2,
|
1313
|
-
FALSE, &dummy, &dummy, C1a, C2a);
|
1368
|
+
cbet1, cbet2, 0, &dlam12, 0, 0, 0, Ca);
|
1314
1369
|
dlam12 *= g->f1 / (calp2 * cbet2);
|
1315
1370
|
}
|
1316
1371
|
}
|
@@ -1331,177 +1386,264 @@ real Lambda12(const struct geod_geodesic* g,
|
|
1331
1386
|
}
|
1332
1387
|
|
1333
1388
|
real A3f(const struct geod_geodesic* g, real eps) {
|
1334
|
-
/* Evaluate
|
1335
|
-
|
1336
|
-
int i;
|
1337
|
-
for (i = nA3x; i; )
|
1338
|
-
v = eps * v + g->A3x[--i];
|
1339
|
-
return v;
|
1389
|
+
/* Evaluate A3 */
|
1390
|
+
return polyval(nA3 - 1, g->A3x, eps);
|
1340
1391
|
}
|
1341
1392
|
|
1342
1393
|
void C3f(const struct geod_geodesic* g, real eps, real c[]) {
|
1343
|
-
/* Evaluate C3 coeffs
|
1394
|
+
/* Evaluate C3 coeffs
|
1344
1395
|
* Elements c[1] thru c[nC3 - 1] are set */
|
1345
|
-
int i, j, k;
|
1346
1396
|
real mult = 1;
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
t = eps * t + g->C3x[--j];
|
1351
|
-
c[k--] = t;
|
1352
|
-
}
|
1353
|
-
|
1354
|
-
for (k = 1; k < nC3; ) {
|
1397
|
+
int o = 0, l;
|
1398
|
+
for (l = 1; l < nC3; ++l) { /* l is index of C3[l] */
|
1399
|
+
int m = nC3 - l - 1; /* order of polynomial in eps */
|
1355
1400
|
mult *= eps;
|
1356
|
-
c[
|
1401
|
+
c[l] = mult * polyval(m, g->C3x + o, eps);
|
1402
|
+
o += m + 1;
|
1357
1403
|
}
|
1358
1404
|
}
|
1359
1405
|
|
1360
1406
|
void C4f(const struct geod_geodesic* g, real eps, real c[]) {
|
1361
|
-
/* Evaluate C4 coeffs
|
1407
|
+
/* Evaluate C4 coeffs
|
1362
1408
|
* Elements c[0] thru c[nC4 - 1] are set */
|
1363
|
-
int i, j, k;
|
1364
1409
|
real mult = 1;
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
}
|
1371
|
-
|
1372
|
-
for (k = 1; k < nC4; ) {
|
1410
|
+
int o = 0, l;
|
1411
|
+
for (l = 0; l < nC4; ++l) { /* l is index of C4[l] */
|
1412
|
+
int m = nC4 - l - 1; /* order of polynomial in eps */
|
1413
|
+
c[l] = mult * polyval(m, g->C4x + o, eps);
|
1414
|
+
o += m + 1;
|
1373
1415
|
mult *= eps;
|
1374
|
-
c[k++] *= mult;
|
1375
1416
|
}
|
1376
1417
|
}
|
1377
1418
|
|
1378
|
-
/* Generated by Maxima on 2010-09-04 10:26:17-04:00 */
|
1379
|
-
|
1380
1419
|
/* The scale factor A1-1 = mean value of (d/dsigma)I1 - 1 */
|
1381
1420
|
real A1m1f(real eps) {
|
1382
|
-
real
|
1383
|
-
|
1384
|
-
|
1421
|
+
static const real coeff[] = {
|
1422
|
+
/* (1-eps)*A1-1, polynomial in eps2 of order 3 */
|
1423
|
+
1, 4, 64, 0, 256,
|
1424
|
+
};
|
1425
|
+
int m = nA1/2;
|
1426
|
+
real t = polyval(m, coeff, sq(eps)) / coeff[m + 1];
|
1385
1427
|
return (t + eps) / (1 - eps);
|
1386
1428
|
}
|
1387
1429
|
|
1388
1430
|
/* The coefficients C1[l] in the Fourier expansion of B1 */
|
1389
1431
|
void C1f(real eps, real c[]) {
|
1432
|
+
static const real coeff[] = {
|
1433
|
+
/* C1[1]/eps^1, polynomial in eps2 of order 2 */
|
1434
|
+
-1, 6, -16, 32,
|
1435
|
+
/* C1[2]/eps^2, polynomial in eps2 of order 2 */
|
1436
|
+
-9, 64, -128, 2048,
|
1437
|
+
/* C1[3]/eps^3, polynomial in eps2 of order 1 */
|
1438
|
+
9, -16, 768,
|
1439
|
+
/* C1[4]/eps^4, polynomial in eps2 of order 1 */
|
1440
|
+
3, -5, 512,
|
1441
|
+
/* C1[5]/eps^5, polynomial in eps2 of order 0 */
|
1442
|
+
-7, 1280,
|
1443
|
+
/* C1[6]/eps^6, polynomial in eps2 of order 0 */
|
1444
|
+
-7, 2048,
|
1445
|
+
};
|
1390
1446
|
real
|
1391
1447
|
eps2 = sq(eps),
|
1392
1448
|
d = eps;
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
d *= eps;
|
1401
|
-
c[5] = -7*d/1280;
|
1402
|
-
d *= eps;
|
1403
|
-
c[6] = -7*d/2048;
|
1449
|
+
int o = 0, l;
|
1450
|
+
for (l = 1; l <= nC1; ++l) { /* l is index of C1p[l] */
|
1451
|
+
int m = (nC1 - l) / 2; /* order of polynomial in eps^2 */
|
1452
|
+
c[l] = d * polyval(m, coeff + o, eps2) / coeff[o + m + 1];
|
1453
|
+
o += m + 2;
|
1454
|
+
d *= eps;
|
1455
|
+
}
|
1404
1456
|
}
|
1405
1457
|
|
1406
1458
|
/* The coefficients C1p[l] in the Fourier expansion of B1p */
|
1407
1459
|
void C1pf(real eps, real c[]) {
|
1460
|
+
static const real coeff[] = {
|
1461
|
+
/* C1p[1]/eps^1, polynomial in eps2 of order 2 */
|
1462
|
+
205, -432, 768, 1536,
|
1463
|
+
/* C1p[2]/eps^2, polynomial in eps2 of order 2 */
|
1464
|
+
4005, -4736, 3840, 12288,
|
1465
|
+
/* C1p[3]/eps^3, polynomial in eps2 of order 1 */
|
1466
|
+
-225, 116, 384,
|
1467
|
+
/* C1p[4]/eps^4, polynomial in eps2 of order 1 */
|
1468
|
+
-7173, 2695, 7680,
|
1469
|
+
/* C1p[5]/eps^5, polynomial in eps2 of order 0 */
|
1470
|
+
3467, 7680,
|
1471
|
+
/* C1p[6]/eps^6, polynomial in eps2 of order 0 */
|
1472
|
+
38081, 61440,
|
1473
|
+
};
|
1408
1474
|
real
|
1409
1475
|
eps2 = sq(eps),
|
1410
1476
|
d = eps;
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
d *= eps;
|
1419
|
-
c[5] = 3467*d/7680;
|
1420
|
-
d *= eps;
|
1421
|
-
c[6] = 38081*d/61440;
|
1477
|
+
int o = 0, l;
|
1478
|
+
for (l = 1; l <= nC1p; ++l) { /* l is index of C1p[l] */
|
1479
|
+
int m = (nC1p - l) / 2; /* order of polynomial in eps^2 */
|
1480
|
+
c[l] = d * polyval(m, coeff + o, eps2) / coeff[o + m + 1];
|
1481
|
+
o += m + 2;
|
1482
|
+
d *= eps;
|
1483
|
+
}
|
1422
1484
|
}
|
1423
1485
|
|
1424
1486
|
/* The scale factor A2-1 = mean value of (d/dsigma)I2 - 1 */
|
1425
1487
|
real A2m1f(real eps) {
|
1426
|
-
real
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1488
|
+
static const real coeff[] = {
|
1489
|
+
/* (eps+1)*A2-1, polynomial in eps2 of order 3 */
|
1490
|
+
-11, -28, -192, 0, 256,
|
1491
|
+
};
|
1492
|
+
int m = nA2/2;
|
1493
|
+
real t = polyval(m, coeff, sq(eps)) / coeff[m + 1];
|
1494
|
+
return (t - eps) / (1 + eps);
|
1430
1495
|
}
|
1431
1496
|
|
1432
1497
|
/* The coefficients C2[l] in the Fourier expansion of B2 */
|
1433
1498
|
void C2f(real eps, real c[]) {
|
1499
|
+
static const real coeff[] = {
|
1500
|
+
/* C2[1]/eps^1, polynomial in eps2 of order 2 */
|
1501
|
+
1, 2, 16, 32,
|
1502
|
+
/* C2[2]/eps^2, polynomial in eps2 of order 2 */
|
1503
|
+
35, 64, 384, 2048,
|
1504
|
+
/* C2[3]/eps^3, polynomial in eps2 of order 1 */
|
1505
|
+
15, 80, 768,
|
1506
|
+
/* C2[4]/eps^4, polynomial in eps2 of order 1 */
|
1507
|
+
7, 35, 512,
|
1508
|
+
/* C2[5]/eps^5, polynomial in eps2 of order 0 */
|
1509
|
+
63, 1280,
|
1510
|
+
/* C2[6]/eps^6, polynomial in eps2 of order 0 */
|
1511
|
+
77, 2048,
|
1512
|
+
};
|
1434
1513
|
real
|
1435
1514
|
eps2 = sq(eps),
|
1436
1515
|
d = eps;
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
d *= eps;
|
1445
|
-
c[5] = 63*d/1280;
|
1446
|
-
d *= eps;
|
1447
|
-
c[6] = 77*d/2048;
|
1516
|
+
int o = 0, l;
|
1517
|
+
for (l = 1; l <= nC2; ++l) { /* l is index of C2[l] */
|
1518
|
+
int m = (nC2 - l) / 2; /* order of polynomial in eps^2 */
|
1519
|
+
c[l] = d * polyval(m, coeff + o, eps2) / coeff[o + m + 1];
|
1520
|
+
o += m + 2;
|
1521
|
+
d *= eps;
|
1522
|
+
}
|
1448
1523
|
}
|
1449
1524
|
|
1450
1525
|
/* The scale factor A3 = mean value of (d/dsigma)I3 */
|
1451
1526
|
void A3coeff(struct geod_geodesic* g) {
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1527
|
+
static const real coeff[] = {
|
1528
|
+
/* A3, coeff of eps^5, polynomial in n of order 0 */
|
1529
|
+
-3, 128,
|
1530
|
+
/* A3, coeff of eps^4, polynomial in n of order 1 */
|
1531
|
+
-2, -3, 64,
|
1532
|
+
/* A3, coeff of eps^3, polynomial in n of order 2 */
|
1533
|
+
-1, -3, -1, 16,
|
1534
|
+
/* A3, coeff of eps^2, polynomial in n of order 2 */
|
1535
|
+
3, -1, -2, 8,
|
1536
|
+
/* A3, coeff of eps^1, polynomial in n of order 1 */
|
1537
|
+
1, -1, 2,
|
1538
|
+
/* A3, coeff of eps^0, polynomial in n of order 0 */
|
1539
|
+
1, 1,
|
1540
|
+
};
|
1541
|
+
int o = 0, k = 0, j;
|
1542
|
+
for (j = nA3 - 1; j >= 0; --j) { /* coeff of eps^j */
|
1543
|
+
int m = nA3 - j - 1 < j ? nA3 - j - 1 : j; /* order of polynomial in n */
|
1544
|
+
g->A3x[k++] = polyval(m, coeff + o, g->n) / coeff[o + m + 1];
|
1545
|
+
o += m + 2;
|
1546
|
+
}
|
1458
1547
|
}
|
1459
1548
|
|
1460
1549
|
/* The coefficients C3[l] in the Fourier expansion of B3 */
|
1461
1550
|
void C3coeff(struct geod_geodesic* g) {
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1551
|
+
static const real coeff[] = {
|
1552
|
+
/* C3[1], coeff of eps^5, polynomial in n of order 0 */
|
1553
|
+
3, 128,
|
1554
|
+
/* C3[1], coeff of eps^4, polynomial in n of order 1 */
|
1555
|
+
2, 5, 128,
|
1556
|
+
/* C3[1], coeff of eps^3, polynomial in n of order 2 */
|
1557
|
+
-1, 3, 3, 64,
|
1558
|
+
/* C3[1], coeff of eps^2, polynomial in n of order 2 */
|
1559
|
+
-1, 0, 1, 8,
|
1560
|
+
/* C3[1], coeff of eps^1, polynomial in n of order 1 */
|
1561
|
+
-1, 1, 4,
|
1562
|
+
/* C3[2], coeff of eps^5, polynomial in n of order 0 */
|
1563
|
+
5, 256,
|
1564
|
+
/* C3[2], coeff of eps^4, polynomial in n of order 1 */
|
1565
|
+
1, 3, 128,
|
1566
|
+
/* C3[2], coeff of eps^3, polynomial in n of order 2 */
|
1567
|
+
-3, -2, 3, 64,
|
1568
|
+
/* C3[2], coeff of eps^2, polynomial in n of order 2 */
|
1569
|
+
1, -3, 2, 32,
|
1570
|
+
/* C3[3], coeff of eps^5, polynomial in n of order 0 */
|
1571
|
+
7, 512,
|
1572
|
+
/* C3[3], coeff of eps^4, polynomial in n of order 1 */
|
1573
|
+
-10, 9, 384,
|
1574
|
+
/* C3[3], coeff of eps^3, polynomial in n of order 2 */
|
1575
|
+
5, -9, 5, 192,
|
1576
|
+
/* C3[4], coeff of eps^5, polynomial in n of order 0 */
|
1577
|
+
7, 512,
|
1578
|
+
/* C3[4], coeff of eps^4, polynomial in n of order 1 */
|
1579
|
+
-14, 7, 512,
|
1580
|
+
/* C3[5], coeff of eps^5, polynomial in n of order 0 */
|
1581
|
+
21, 2560,
|
1582
|
+
};
|
1583
|
+
int o = 0, k = 0, l, j;
|
1584
|
+
for (l = 1; l < nC3; ++l) { /* l is index of C3[l] */
|
1585
|
+
for (j = nC3 - 1; j >= l; --j) { /* coeff of eps^j */
|
1586
|
+
int m = nC3 - j - 1 < j ? nC3 - j - 1 : j; /* order of polynomial in n */
|
1587
|
+
g->C3x[k++] = polyval(m, coeff + o, g->n) / coeff[o + m + 1];
|
1588
|
+
o += m + 2;
|
1589
|
+
}
|
1590
|
+
}
|
1477
1591
|
}
|
1478
1592
|
|
1479
|
-
/* Generated by Maxima on 2012-10-19 08:02:34-04:00 */
|
1480
|
-
|
1481
1593
|
/* The coefficients C4[l] in the Fourier expansion of I4 */
|
1482
1594
|
void C4coeff(struct geod_geodesic* g) {
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1595
|
+
static const real coeff[] = {
|
1596
|
+
/* C4[0], coeff of eps^5, polynomial in n of order 0 */
|
1597
|
+
97, 15015,
|
1598
|
+
/* C4[0], coeff of eps^4, polynomial in n of order 1 */
|
1599
|
+
1088, 156, 45045,
|
1600
|
+
/* C4[0], coeff of eps^3, polynomial in n of order 2 */
|
1601
|
+
-224, -4784, 1573, 45045,
|
1602
|
+
/* C4[0], coeff of eps^2, polynomial in n of order 3 */
|
1603
|
+
-10656, 14144, -4576, -858, 45045,
|
1604
|
+
/* C4[0], coeff of eps^1, polynomial in n of order 4 */
|
1605
|
+
64, 624, -4576, 6864, -3003, 15015,
|
1606
|
+
/* C4[0], coeff of eps^0, polynomial in n of order 5 */
|
1607
|
+
100, 208, 572, 3432, -12012, 30030, 45045,
|
1608
|
+
/* C4[1], coeff of eps^5, polynomial in n of order 0 */
|
1609
|
+
1, 9009,
|
1610
|
+
/* C4[1], coeff of eps^4, polynomial in n of order 1 */
|
1611
|
+
-2944, 468, 135135,
|
1612
|
+
/* C4[1], coeff of eps^3, polynomial in n of order 2 */
|
1613
|
+
5792, 1040, -1287, 135135,
|
1614
|
+
/* C4[1], coeff of eps^2, polynomial in n of order 3 */
|
1615
|
+
5952, -11648, 9152, -2574, 135135,
|
1616
|
+
/* C4[1], coeff of eps^1, polynomial in n of order 4 */
|
1617
|
+
-64, -624, 4576, -6864, 3003, 135135,
|
1618
|
+
/* C4[2], coeff of eps^5, polynomial in n of order 0 */
|
1619
|
+
8, 10725,
|
1620
|
+
/* C4[2], coeff of eps^4, polynomial in n of order 1 */
|
1621
|
+
1856, -936, 225225,
|
1622
|
+
/* C4[2], coeff of eps^3, polynomial in n of order 2 */
|
1623
|
+
-8448, 4992, -1144, 225225,
|
1624
|
+
/* C4[2], coeff of eps^2, polynomial in n of order 3 */
|
1625
|
+
-1440, 4160, -4576, 1716, 225225,
|
1626
|
+
/* C4[3], coeff of eps^5, polynomial in n of order 0 */
|
1627
|
+
-136, 63063,
|
1628
|
+
/* C4[3], coeff of eps^4, polynomial in n of order 1 */
|
1629
|
+
1024, -208, 105105,
|
1630
|
+
/* C4[3], coeff of eps^3, polynomial in n of order 2 */
|
1631
|
+
3584, -3328, 1144, 315315,
|
1632
|
+
/* C4[4], coeff of eps^5, polynomial in n of order 0 */
|
1633
|
+
-128, 135135,
|
1634
|
+
/* C4[4], coeff of eps^4, polynomial in n of order 1 */
|
1635
|
+
-2560, 832, 405405,
|
1636
|
+
/* C4[5], coeff of eps^5, polynomial in n of order 0 */
|
1637
|
+
128, 99099,
|
1638
|
+
};
|
1639
|
+
int o = 0, k = 0, l, j;
|
1640
|
+
for (l = 0; l < nC4; ++l) { /* l is index of C4[l] */
|
1641
|
+
for (j = nC4 - 1; j >= l; --j) { /* coeff of eps^j */
|
1642
|
+
int m = nC4 - j - 1; /* order of polynomial in n */
|
1643
|
+
g->C4x[k++] = polyval(m, coeff + o, g->n) / coeff[o + m + 1];
|
1644
|
+
o += m + 2;
|
1645
|
+
}
|
1646
|
+
}
|
1505
1647
|
}
|
1506
1648
|
|
1507
1649
|
int transit(real lon1, real lon2) {
|
@@ -1516,6 +1658,13 @@ int transit(real lon1, real lon2) {
|
|
1516
1658
|
(lon2 < 0 && lon1 >= 0 && lon12 < 0 ? -1 : 0);
|
1517
1659
|
}
|
1518
1660
|
|
1661
|
+
int transitdirect(real lon1, real lon2) {
|
1662
|
+
lon1 = fmod(lon1, (real)(720));
|
1663
|
+
lon2 = fmod(lon2, (real)(720));
|
1664
|
+
return ( ((lon2 >= 0 && lon2 < 360) || lon2 < -360 ? 0 : 1) -
|
1665
|
+
((lon1 >= 0 && lon1 < 360) || lon1 < -360 ? 0 : 1) );
|
1666
|
+
}
|
1667
|
+
|
1519
1668
|
void accini(real s[]) {
|
1520
1669
|
/* Initialize an accumulator; this is an array with two elements. */
|
1521
1670
|
s[0] = s[1] = 0;
|
@@ -1583,13 +1732,13 @@ void geod_polygon_addedge(const struct geod_geodesic* g,
|
|
1583
1732
|
real azi, real s) {
|
1584
1733
|
if (p->num) { /* Do nothing is num is zero */
|
1585
1734
|
real lat, lon, S12;
|
1586
|
-
geod_gendirect(g, p->lat, p->lon, azi,
|
1735
|
+
geod_gendirect(g, p->lat, p->lon, azi, GEOD_LONG_UNROLL, s,
|
1587
1736
|
&lat, &lon, 0,
|
1588
1737
|
0, 0, 0, 0, p->polyline ? 0 : &S12);
|
1589
1738
|
accadd(p->P, s);
|
1590
1739
|
if (!p->polyline) {
|
1591
1740
|
accadd(p->A, S12);
|
1592
|
-
p->crossings +=
|
1741
|
+
p->crossings += transitdirect(p->lon, lon);
|
1593
1742
|
}
|
1594
1743
|
p->lat = lat; p->lon = lon;
|
1595
1744
|
++p->num;
|
@@ -1720,11 +1869,11 @@ unsigned geod_polygon_testedge(const struct geod_geodesic* g,
|
|
1720
1869
|
crossings = p->crossings;
|
1721
1870
|
{
|
1722
1871
|
real lat, lon, s12, S12;
|
1723
|
-
geod_gendirect(g, p->lat, p->lon, azi,
|
1872
|
+
geod_gendirect(g, p->lat, p->lon, azi, GEOD_LONG_UNROLL, s,
|
1724
1873
|
&lat, &lon, 0,
|
1725
1874
|
0, 0, 0, 0, &S12);
|
1726
1875
|
tempsum += S12;
|
1727
|
-
crossings +=
|
1876
|
+
crossings += transitdirect(p->lon, lon);
|
1728
1877
|
geod_geninverse(g, lat, lon, p->lat0, p->lon0,
|
1729
1878
|
&s12, 0, 0, 0, 0, 0, &S12);
|
1730
1879
|
perimeter += s12;
|