29 #if !defined(HAVE_C99_MATH)
30 #define HAVE_C99_MATH 0
33 #define GEOGRAPHICLIB_GEODESIC_ORDER 6
34 #define nA1 GEOGRAPHICLIB_GEODESIC_ORDER
35 #define nC1 GEOGRAPHICLIB_GEODESIC_ORDER
36 #define nC1p GEOGRAPHICLIB_GEODESIC_ORDER
37 #define nA2 GEOGRAPHICLIB_GEODESIC_ORDER
38 #define nC2 GEOGRAPHICLIB_GEODESIC_ORDER
39 #define nA3 GEOGRAPHICLIB_GEODESIC_ORDER
41 #define nC3 GEOGRAPHICLIB_GEODESIC_ORDER
42 #define nC3x ((nC3 * (nC3 - 1)) / 2)
43 #define nC4 GEOGRAPHICLIB_GEODESIC_ORDER
44 #define nC4x ((nC4 * (nC4 + 1)) / 2)
45 #define nC (GEOGRAPHICLIB_GEODESIC_ORDER + 1)
50 static unsigned init = 0;
51 static const int FALSE = 0;
52 static const int TRUE = 1;
53 static unsigned digits, maxit1, maxit2;
55 tiny, tol0, tol1, tol2, tolb, xthresh;
59 #if defined(__DBL_MANT_DIG__)
60 digits = __DBL_MANT_DIG__;
64 #if defined(__DBL_EPSILON__)
69 #if defined(__DBL_MIN__)
70 realmin = __DBL_MIN__;
72 realmin =
pow(0.5, 1022);
77 pi =
atan2(0.0, -1.0);
80 maxit2 = maxit1 + digits + 10;
90 xthresh = 1000 * tol2;
114 #define copysignx copysign
131 y = log1px(2 *
y/(1 -
y))/2;
132 return x < 0 ? -
y :
y;
136 return fabs(
x) * (
y < 0 || (
y == 0 && 1/
y < 0) ? -1 : 1);
144 return x < 0 ? -
y :
y;
151 volatile real vpp =
s - up;
154 if (
t) *
t = -(up + vpp);
163 while (--
N >= 0)
y =
y *
x + *
p++;
169 {
return (
b <
a) ?
b :
a; }
172 {
return (
a <
b) ?
b :
a; }
178 real r = hypotx(*sinx, *cosx);
185 x = remainder(
x, (
real)(360));
186 return x != -180 ?
x : 180;
189 return x <= -180 ?
x + 360 : (
x <= 180 ?
x :
x - 360);
194 {
return fabs(
x) > 90 ? NaN :
x; }
197 real t,
d = AngNormalize(sumx(AngNormalize(-
x), AngNormalize(
y), &
t));
204 return sumx(
d == 180 &&
t > 0 ? -180 :
d,
t,
e);
210 if (
x == 0)
return 0;
214 return x < 0 ? -
y :
y;
221 #if HAVE_C99_MATH && !defined(__GNUC__)
224 r = remquo(
x, (
real)(90), &
q);
234 switch ((
unsigned)
q & 3
U) {
235 case 0
U: *sinx =
s; *cosx =
c;
break;
236 case 1
U: *sinx =
c; *cosx = -
s;
break;
237 case 2
U: *sinx = -
s; *cosx = -
c;
break;
238 default: *sinx = -
c; *cosx =
s;
break;
240 if (
x != 0) { *sinx += (
real)(0); *cosx += (
real)(0); }
250 if (
x < 0) {
x = -
x; ++
q; }
259 case 1: ang = (
y >= 0 ? 180 : -180) - ang;
break;
260 case 2: ang = 90 - ang;
break;
261 case 3: ang = -90 + ang;
break;
269 static real SinCosSeries(boolx sinp,
304 boolx diffp,
real* pdlam12,
315 static int transit(
real lon1,
real lon2);
316 static int transitdirect(
real lon1,
real lon2);
317 static void accini(
real s[]);
318 static void acccopy(
const real s[],
real t[]);
321 static void accneg(
real s[]);
328 g->e2 =
g->f * (2 -
g->f);
329 g->ep2 =
g->e2 / sq(
g->f1);
330 g->n =
g->f / ( 2 -
g->f);
332 g->c2 = (sq(
g->a) + sq(
g->b) *
345 g->etol2 = 0.1 * tol2 /
358 real cbet1, sbet1, eps;
369 l->lat1 = LatFix(lat1);
375 sincosdx(AngRound(
l->lat1), &sbet1, &cbet1); sbet1 *=
l->f1;
377 norm2(&sbet1, &cbet1); cbet1 = maxx(tiny, cbet1);
378 l->dn1 =
sqrt(1 +
g->ep2 * sq(sbet1));
381 l->salp0 =
l->salp1 * cbet1;
384 l->calp0 = hypotx(
l->calp1,
l->salp1 * sbet1);
394 l->ssig1 = sbet1;
l->somg1 =
l->salp0 * sbet1;
395 l->csig1 =
l->comg1 = sbet1 != 0 ||
l->calp1 != 0 ? cbet1 *
l->calp1 : 1;
399 l->k2 = sq(
l->calp0) *
g->ep2;
400 eps =
l->k2 / (2 * (1 +
sqrt(1 +
l->k2)) +
l->k2);
402 if (
l->caps & CAP_C1) {
404 l->A1m1 = A1m1f(eps);
406 l->B11 = SinCosSeries(
TRUE,
l->ssig1,
l->csig1,
l->C1a, nC1);
409 l->stau1 =
l->ssig1 *
c +
l->csig1 *
s;
410 l->ctau1 =
l->csig1 *
c -
l->ssig1 *
s;
415 if (
l->caps & CAP_C1p)
418 if (
l->caps & CAP_C2) {
419 l->A2m1 = A2m1f(eps);
421 l->B21 = SinCosSeries(
TRUE,
l->ssig1,
l->csig1,
l->C2a, nC2);
424 if (
l->caps & CAP_C3) {
426 l->A3c = -
l->f *
l->salp0 * A3f(
g, eps);
427 l->B31 = SinCosSeries(
TRUE,
l->ssig1,
l->csig1,
l->C3a, nC3-1);
430 if (
l->caps & CAP_C4) {
433 l->A4 = sq(
l->a) *
l->calp0 *
l->salp0 *
g->e2;
434 l->B41 = SinCosSeries(
FALSE,
l->ssig1,
l->csig1,
l->C4a, nC4);
437 l->a13 =
l->s13 = NaN;
444 azi1 = AngNormalize(azi1);
446 sincosdx(AngRound(azi1), &salp1, &calp1);
447 geod_lineinit_int(
l,
g, lat1, lon1, azi1, salp1, calp1, caps);
453 unsigned flags,
real a12_s12,
462 real s12,
unsigned caps) {
467 unsigned flags,
real s12_a12,
472 real lat2 = 0, lon2 = 0, azi2 = 0, s12 = 0,
473 m12 = 0, M12 = 0, M21 = 0, S12 = 0;
475 real sig12, ssig12, csig12, B12 = 0, AB1 = 0;
476 real omg12, lam12, lon12;
477 real ssig2, csig2, sbet2, cbet2, somg2, comg2, salp2, calp2, dn2;
496 sincosdx(s12_a12, &ssig12, &csig12);
500 tau12 = s12_a12 / (
l->b * (1 +
l->A1m1)),
504 B12 = - SinCosSeries(
TRUE,
505 l->stau1 *
c +
l->ctau1 *
s,
506 l->ctau1 *
c -
l->stau1 *
s,
508 sig12 = tau12 - (B12 -
l->B11);
509 ssig12 =
sin(sig12); csig12 =
cos(sig12);
510 if (
fabs(
l->f) > 0.01) {
533 ssig2 =
l->ssig1 * csig12 +
l->csig1 * ssig12;
534 csig2 =
l->csig1 * csig12 -
l->ssig1 * ssig12;
535 B12 = SinCosSeries(
TRUE, ssig2, csig2,
l->C1a, nC1);
536 serr = (1 +
l->A1m1) * (sig12 + (B12 -
l->B11)) - s12_a12 /
l->b;
537 sig12 = sig12 - serr /
sqrt(1 +
l->k2 * sq(ssig2));
538 ssig12 =
sin(sig12); csig12 =
cos(sig12);
544 ssig2 =
l->ssig1 * csig12 +
l->csig1 * ssig12;
545 csig2 =
l->csig1 * csig12 -
l->ssig1 * ssig12;
546 dn2 =
sqrt(1 +
l->k2 * sq(ssig2));
549 B12 = SinCosSeries(
TRUE, ssig2, csig2,
l->C1a, nC1);
550 AB1 = (1 +
l->A1m1) * (B12 -
l->B11);
553 sbet2 =
l->calp0 * ssig2;
555 cbet2 = hypotx(
l->salp0,
l->calp0 * csig2);
558 cbet2 = csig2 = tiny;
560 salp2 =
l->salp0; calp2 =
l->calp0 * csig2;
564 l->b * ((1 +
l->A1m1) * sig12 + AB1) :
568 real E = copysignx(1,
l->salp0);
570 somg2 =
l->salp0 * ssig2; comg2 = csig2;
576 :
atan2(somg2 *
l->comg1 - comg2 *
l->somg1,
577 comg2 *
l->comg1 + somg2 *
l->somg1);
578 lam12 = omg12 +
l->A3c *
579 ( sig12 + (SinCosSeries(
TRUE, ssig2, csig2,
l->C3a, nC3-1)
583 AngNormalize(AngNormalize(
l->lon1) + AngNormalize(lon12));
587 lat2 = atan2dx(sbet2,
l->f1 * cbet2);
590 azi2 = atan2dx(salp2, calp2);
594 B22 = SinCosSeries(
TRUE, ssig2, csig2,
l->C2a, nC2),
595 AB2 = (1 +
l->A2m1) * (B22 -
l->B21),
596 J12 = (
l->A1m1 -
l->A2m1) * sig12 + (AB1 - AB2);
600 m12 =
l->b * ((dn2 * (
l->csig1 * ssig2) -
l->dn1 * (
l->ssig1 * csig2))
601 -
l->csig1 * csig2 * J12);
603 real t =
l->k2 * (ssig2 -
l->ssig1) * (ssig2 +
l->ssig1) /
605 M12 = csig12 + (
t * ssig2 - csig2 * J12) *
l->ssig1 /
l->dn1;
606 M21 = csig12 - (
t *
l->ssig1 -
l->csig1 * J12) * ssig2 / dn2;
612 B42 = SinCosSeries(
FALSE, ssig2, csig2,
l->C4a, nC4);
614 if (
l->calp0 == 0 ||
l->salp0 == 0) {
616 salp12 = salp2 *
l->calp1 - calp2 *
l->salp1;
617 calp12 = calp2 *
l->calp1 + salp2 *
l->salp1;
627 salp12 =
l->calp0 *
l->salp0 *
628 (csig12 <= 0 ?
l->csig1 * (1 - csig12) + ssig12 *
l->ssig1 :
629 ssig12 * (
l->csig1 * ssig12 / (1 + csig12) +
l->ssig1));
630 calp12 = sq(
l->salp0) + sq(
l->calp0) *
l->csig1 * csig2;
632 S12 =
l->c2 *
atan2(salp12, calp12) +
l->A4 * (B42 -
l->B41);
646 if (pM12) *pM12 = M12;
647 if (pM21) *pM21 = M21;
657 l->a13 =
geod_genposition(
l,
GEOD_NOFLAGS,
l->s13, 0, 0, 0, 0, 0, 0, 0, 0);
661 l->a13 = a13;
l->s13 = NaN;
662 geod_genposition(
l,
GEOD_ARCMODE,
l->a13, 0, 0, 0, &
l->s13, 0, 0, 0, 0);
666 unsigned flags,
real s13_a13) {
668 geod_setarc(
l, s13_a13) :
674 geod_genposition(
l,
FALSE, s12, plat2, plon2, pazi2, 0, 0, 0, 0, 0);
679 unsigned flags,
real s12_a12,
698 plat2, plon2, pazi2, ps12, pm12, pM12, pM21, pS12);
716 real s12 = 0, m12 = 0, M12 = 0, M21 = 0, S12 = 0;
718 int latsign, lonsign, swapp;
719 real sbet1, cbet1, sbet2, cbet2, s12x = 0, m12x = 0;
720 real dn1, dn2, lam12, slam12, clam12;
725 real omg12 = 0, somg12 = 2, comg12 = 0;
737 lon12 = AngDiff(
lon1, lon2, &lon12s);
739 lonsign = lon12 >= 0 ? 1 : -1;
741 lon12 = lonsign * AngRound(lon12);
742 lon12s = AngRound((180 - lon12) - lonsign * lon12s);
745 sincosdx(lon12s, &slam12, &clam12);
748 sincosdx(lon12, &slam12, &clam12);
752 lat2 = AngRound(LatFix(lat2));
761 latsign =
lat1 < 0 ? 1 : -1;
776 sincosdx(
lat1, &sbet1, &cbet1); sbet1 *=
g->f1;
778 norm2(&sbet1, &cbet1); cbet1 = maxx(tiny, cbet1);
780 sincosdx(lat2, &sbet2, &cbet2); sbet2 *=
g->f1;
782 norm2(&sbet2, &cbet2); cbet2 = maxx(tiny, cbet2);
792 if (cbet1 < -sbet1) {
794 sbet2 = sbet2 < 0 ? sbet1 : -sbet1;
796 if (
fabs(sbet2) == -sbet1)
800 dn1 =
sqrt(1 +
g->ep2 * sq(sbet1));
801 dn2 =
sqrt(1 +
g->ep2 * sq(sbet2));
803 meridian =
lat1 == -90 || slam12 == 0;
810 real ssig1, csig1, ssig2, csig2;
812 calp2 = 1; salp2 = 0;
815 ssig1 = sbet1; csig1 =
calp1 * cbet1;
816 ssig2 = sbet2; csig2 = calp2 * cbet2;
819 sig12 =
atan2(maxx((
real)(0), csig1 * ssig2 - ssig1 * csig2),
820 csig1 * csig2 + ssig1 * ssig2);
821 Lengths(
g,
g->n, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2,
822 cbet1, cbet2, &s12x, &m12x, 0,
833 if (sig12 < 1 || m12x >= 0) {
835 if (sig12 < 3 * tiny)
836 sig12 = m12x = s12x = 0;
848 (
g->f <= 0 || lon12s >=
g->f * 180)) {
853 sig12 = omg12 = lam12 /
g->f1;
854 m12x =
g->b *
sin(sig12);
856 M12 = M21 =
cos(sig12);
859 }
else if (!meridian) {
866 sig12 = InverseStart(
g, sbet1, cbet1, dn1, sbet2, cbet2, dn2,
867 lam12, slam12, clam12,
873 s12x = sig12 *
g->b * dnm;
874 m12x = sq(dnm) *
g->b *
sin(sig12 / dnm);
876 M12 = M21 =
cos(sig12 / dnm);
878 omg12 = lam12 / (
g->f1 * dnm);
892 real ssig1 = 0, csig1 = 0, ssig2 = 0, csig2 = 0, eps = 0, domg12 = 0;
895 real salp1a = tiny, calp1a = 1, salp1b = tiny, calp1b = -1;
897 for (tripn =
FALSE, tripb =
FALSE; numit < maxit2; ++numit) {
901 v = Lambda12(
g, sbet1, cbet1, dn1, sbet2, cbet2, dn2,
salp1,
calp1,
903 &salp2, &calp2, &sig12, &ssig1, &csig1, &ssig2, &csig2,
904 &eps, &domg12, numit < maxit1, &dv, Ca);
907 if (tripb || !(
fabs(
v) >= (tripn ? 8 : 1) * tol0))
break;
909 if (
v > 0 && (numit > maxit1 ||
calp1/
salp1 > calp1b/salp1b))
911 else if (
v < 0 && (numit > maxit1 ||
calp1/
salp1 < calp1a/salp1a))
913 if (numit < maxit1 && dv > 0) {
917 sdalp1 =
sin(dalp1), cdalp1 =
cos(dalp1),
919 if (nsalp1 > 0 &&
fabs(dalp1) < pi) {
926 tripn =
fabs(
v) <= 16 * tol0;
938 salp1 = (salp1a + salp1b)/2;
939 calp1 = (calp1a + calp1b)/2;
945 Lengths(
g, eps, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2,
946 cbet1, cbet2, &s12x, &m12x, 0,
954 real sdomg12 =
sin(domg12), cdomg12 =
cos(domg12);
955 somg12 = slam12 * cdomg12 - clam12 * sdomg12;
956 comg12 = clam12 * cdomg12 + slam12 * sdomg12;
970 salp0 =
salp1 * cbet1,
973 if (calp0 != 0 && salp0 != 0) {
976 ssig1 = sbet1, csig1 =
calp1 * cbet1,
977 ssig2 = sbet2, csig2 = calp2 * cbet2,
978 k2 = sq(calp0) *
g->ep2,
979 eps = k2 / (2 * (1 +
sqrt(1 + k2)) + k2),
981 A4 = sq(
g->a) * calp0 * salp0 *
g->e2;
983 norm2(&ssig1, &csig1);
984 norm2(&ssig2, &csig2);
986 B41 = SinCosSeries(
FALSE, ssig1, csig1, Ca, nC4);
987 B42 = SinCosSeries(
FALSE, ssig2, csig2, Ca, nC4);
988 S12 =
A4 * (B42 - B41);
993 if (!meridian && somg12 > 1) {
994 somg12 =
sin(omg12); comg12 =
cos(omg12);
999 comg12 > -(
real)(0.7071) &&
1000 sbet2 - sbet1 < (
real)(1.75)) {
1005 domg12 = 1 + comg12, dbet1 = 1 + cbet1, dbet2 = 1 + cbet2;
1006 alp12 = 2 *
atan2( somg12 * ( sbet1 * dbet2 + sbet2 * dbet1 ),
1007 domg12 * ( sbet1 * sbet2 + dbet1 * dbet2 ) );
1017 if (salp12 == 0 && calp12 < 0) {
1018 salp12 = tiny *
calp1;
1021 alp12 =
atan2(salp12, calp12);
1023 S12 +=
g->c2 * alp12;
1024 S12 *= swapp * lonsign * latsign;
1031 swapx(&
salp1, &salp2);
1032 swapx(&
calp1, &calp2);
1037 salp1 *= swapp * lonsign;
calp1 *= swapp * latsign;
1038 salp2 *= swapp * lonsign; calp2 *= swapp * latsign;
1040 if (psalp1) *psalp1 =
salp1;
1041 if (pcalp1) *pcalp1 =
calp1;
1042 if (psalp2) *psalp2 = salp2;
1043 if (pcalp2) *pcalp2 = calp2;
1050 if (pM12) *pM12 = M12;
1051 if (pM21) *pM21 = M21;
1065 a12 = geod_geninverse_int(
g,
lat1,
lon1, lat2, lon2, ps12,
1067 pm12, pM12, pM21, pS12);
1069 if (pazi2) *pazi2 = atan2dx(salp2, calp2);
1078 a12 = geod_geninverse_int(
g,
lat1,
lon1, lat2, lon2, 0,
1086 geod_setarc(
l, a12);
1092 geod_geninverse(
g,
lat1,
lon1, lat2, lon2, ps12, pazi1, pazi2, 0, 0, 0, 0);
1103 ar = 2 * (cosx - sinx) * (cosx + sinx);
1104 y0 =
n & 1 ? *--
c : 0;
y1 = 0;
1113 ? 2 * sinx * cosx *
y0
1131 boolx redlp = pm12b || pm0 || pM12 || pM21;
1132 if (ps12b || redlp) {
1144 real B1 = SinCosSeries(
TRUE, ssig2, csig2, Ca, nC1) -
1145 SinCosSeries(
TRUE, ssig1, csig1, Ca, nC1);
1147 *ps12b =
A1 * (sig12 + B1);
1149 real B2 = SinCosSeries(
TRUE, ssig2, csig2, Cb, nC2) -
1150 SinCosSeries(
TRUE, ssig1, csig1, Cb, nC2);
1151 J12 =
m0 * sig12 + (
A1 * B1 -
A2 * B2);
1156 for (
l = 1;
l <= nC2; ++
l)
1157 Cb[
l] =
A1 * Ca[
l] -
A2 * Cb[
l];
1158 J12 =
m0 * sig12 + (SinCosSeries(
TRUE, ssig2, csig2, Cb, nC2) -
1159 SinCosSeries(
TRUE, ssig1, csig1, Cb, nC2));
1166 *pm12b = dn2 * (csig1 * ssig2) - dn1 * (ssig1 * csig2) -
1167 csig1 * csig2 * J12;
1169 real csig12 = csig1 * csig2 + ssig1 * ssig2;
1170 real t =
g->ep2 * (cbet1 - cbet2) * (cbet1 + cbet2) / (dn1 + dn2);
1172 *pM12 = csig12 + (
t * ssig2 - csig2 * J12) * ssig1 / dn1;
1174 *pM21 = csig12 - (
t * ssig1 - csig1 * J12) * ssig2 / dn2;
1185 r = (
p +
q - 1) / 6;
1186 if ( !(
q == 0 && r <= 0) ) {
1195 disc =
S * (
S + 2 *
r3);
1207 u +=
T + (
T != 0 ?
r2 /
T : 0);
1213 u += 2 * r *
cos(ang / 3);
1217 uv = u < 0 ?
q / (
v - u) : u +
v;
1218 w = (uv -
q) / (2 *
v);
1221 k = uv / (
sqrt(uv + sq(
w)) +
w);
1249 sbet12 = sbet2 * cbet1 - cbet2 * sbet1,
1250 cbet12 = cbet2 * cbet1 + sbet2 * sbet1;
1252 boolx shortline = cbet12 >= 0 && sbet12 < (
real)(0.5) &&
1253 cbet2 * lam12 < (
real)(0.5);
1254 real somg12, comg12, ssig12, csig12;
1255 #if defined(__GNUC__) && __GNUC__ == 4 && \
1256 (__GNUC_MINOR__ < 6 || defined(__MINGW32__))
1264 volatile real xx1 = sbet2 * cbet1;
1265 volatile real xx2 = cbet2 * sbet1;
1266 sbet12a = xx1 + xx2;
1269 sbet12a = sbet2 * cbet1 + cbet2 * sbet1;
1272 real sbetm2 = sq(sbet1 + sbet2), omg12;
1275 sbetm2 /= sbetm2 + sq(cbet1 + cbet2);
1276 dnm =
sqrt(1 +
g->ep2 * sbetm2);
1277 omg12 = lam12 / (
g->f1 * dnm);
1278 somg12 =
sin(omg12); comg12 =
cos(omg12);
1280 somg12 = slam12; comg12 = clam12;
1283 salp1 = cbet2 * somg12;
1284 calp1 = comg12 >= 0 ?
1285 sbet12 + cbet2 * sbet1 * sq(somg12) / (1 + comg12) :
1286 sbet12a - cbet2 * sbet1 * sq(somg12) / (1 - comg12);
1289 csig12 = sbet1 * sbet2 + cbet1 * cbet2 * comg12;
1291 if (shortline && ssig12 < g->etol2) {
1293 salp2 = cbet1 * somg12;
1294 calp2 = sbet12 - cbet1 * sbet2 *
1295 (comg12 >= 0 ? sq(somg12) / (1 + comg12) : 1 - comg12);
1296 norm2(&salp2, &calp2);
1298 sig12 =
atan2(ssig12, csig12);
1301 ssig12 >= 6 *
fabs(
g->n) * pi * sq(cbet1)) {
1306 real y, lamscale, betscale;
1316 k2 = sq(sbet1) *
g->ep2,
1317 eps = k2 / (2 * (1 +
sqrt(1 + k2)) + k2);
1318 lamscale =
g->f * cbet1 * A3f(
g, eps) * pi;
1320 betscale = lamscale * cbet1;
1322 x = lam12x / lamscale;
1323 y = sbet12a / betscale;
1327 cbet12a = cbet2 * cbet1 - sbet2 * sbet1,
1328 bet12a =
atan2(sbet12a, cbet12a);
1332 Lengths(
g,
g->n, pi + bet12a,
1333 sbet1, -cbet1, dn1, sbet2, cbet2, dn2,
1334 cbet1, cbet2, 0, &m12b, &
m0, 0, 0, Ca);
1335 x = -1 + m12b / (cbet1 * cbet2 *
m0 * pi);
1336 betscale =
x < -(
real)(0.01) ? sbet12a /
x :
1337 -
g->f * sq(cbet1) * pi;
1338 lamscale = betscale / cbet1;
1339 y = lam12x / lamscale;
1342 if (
y > -tol1 &&
x > -1 - xthresh) {
1387 omg12a = lamscale * (
g->f >= 0 ? -
x * k/(1 + k) : -
y * (1 + k)/k );
1388 somg12 =
sin(omg12a); comg12 = -
cos(omg12a);
1390 salp1 = cbet2 * somg12;
1391 calp1 = sbet12a - cbet2 * sbet1 * sq(somg12) / (1 - comg12);
1423 boolx diffp,
real* pdlam12,
1426 real salp2 = 0, calp2 = 0, sig12 = 0,
1427 ssig1 = 0, csig1 = 0, ssig2 = 0, csig2 = 0, eps = 0,
1428 domg12 = 0, dlam12 = 0;
1430 real somg1, comg1, somg2, comg2, somg12, comg12, lam12;
1433 if (sbet1 == 0 &&
calp1 == 0)
1439 salp0 =
salp1 * cbet1;
1444 ssig1 = sbet1; somg1 = salp0 * sbet1;
1445 csig1 = comg1 =
calp1 * cbet1;
1446 norm2(&ssig1, &csig1);
1453 salp2 = cbet2 != cbet1 ? salp0 / cbet2 :
salp1;
1458 calp2 = cbet2 != cbet1 ||
fabs(sbet2) != -sbet1 ?
1461 (cbet2 - cbet1) * (cbet1 + cbet2) :
1462 (sbet1 - sbet2) * (sbet1 + sbet2))) / cbet2 :
1466 ssig2 = sbet2; somg2 = salp0 * sbet2;
1467 csig2 = comg2 = calp2 * cbet2;
1468 norm2(&ssig2, &csig2);
1472 sig12 =
atan2(maxx((
real)(0), csig1 * ssig2 - ssig1 * csig2),
1473 csig1 * csig2 + ssig1 * ssig2);
1476 somg12 = maxx((
real)(0), comg1 * somg2 - somg1 * comg2);
1477 comg12 = comg1 * comg2 + somg1 * somg2;
1479 eta =
atan2(somg12 * clam120 - comg12 * slam120,
1480 comg12 * clam120 + somg12 * slam120);
1481 k2 = sq(calp0) *
g->ep2;
1482 eps = k2 / (2 * (1 +
sqrt(1 + k2)) + k2);
1484 B312 = (SinCosSeries(
TRUE, ssig2, csig2, Ca, nC3-1) -
1485 SinCosSeries(
TRUE, ssig1, csig1, Ca, nC3-1));
1486 domg12 = -
g->f * A3f(
g, eps) * salp0 * (sig12 + B312);
1487 lam12 = eta + domg12;
1491 dlam12 = - 2 *
g->f1 * dn1 / sbet1;
1493 Lengths(
g, eps, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2,
1494 cbet1, cbet2, 0, &dlam12, 0, 0, 0, Ca);
1495 dlam12 *=
g->f1 / (calp2 * cbet2);
1516 return polyval(nA3 - 1,
g->A3x, eps);
1524 for (
l = 1;
l < nC3; ++
l) {
1525 int m = nC3 -
l - 1;
1527 c[
l] = mult * polyval(
m,
g->C3x + o, eps);
1537 for (
l = 0;
l < nC4; ++
l) {
1538 int m = nC4 -
l - 1;
1539 c[
l] = mult * polyval(
m,
g->C4x + o, eps);
1547 static const real coeff[] = {
1552 real t = polyval(
m, coeff, sq(eps)) / coeff[
m + 1];
1553 return (
t + eps) / (1 - eps);
1558 static const real coeff[] = {
1576 for (
l = 1;
l <= nC1; ++
l) {
1577 int m = (nC1 -
l) / 2;
1578 c[
l] =
d * polyval(
m, coeff + o, eps2) / coeff[o +
m + 1];
1586 static const real coeff[] = {
1588 205, -432, 768, 1536,
1590 4005, -4736, 3840, 12288,
1604 for (
l = 1;
l <= nC1p; ++
l) {
1605 int m = (nC1p -
l) / 2;
1606 c[
l] =
d * polyval(
m, coeff + o, eps2) / coeff[o +
m + 1];
1614 static const real coeff[] = {
1616 -11, -28, -192, 0, 256,
1619 real t = polyval(
m, coeff, sq(eps)) / coeff[
m + 1];
1620 return (
t - eps) / (1 + eps);
1625 static const real coeff[] = {
1643 for (
l = 1;
l <= nC2; ++
l) {
1644 int m = (nC2 -
l) / 2;
1645 c[
l] =
d * polyval(
m, coeff + o, eps2) / coeff[o +
m + 1];
1653 static const real coeff[] = {
1667 int o = 0, k = 0,
j;
1668 for (
j = nA3 - 1;
j >= 0; --
j) {
1669 int m = nA3 -
j - 1 <
j ? nA3 -
j - 1 :
j;
1670 g->A3x[k++] = polyval(
m, coeff + o,
g->n) / coeff[o +
m + 1];
1677 static const real coeff[] = {
1709 int o = 0, k = 0,
l,
j;
1710 for (
l = 1;
l < nC3; ++
l) {
1711 for (
j = nC3 - 1;
j >=
l; --
j) {
1712 int m = nC3 -
j - 1 <
j ? nC3 -
j - 1 :
j;
1713 g->C3x[k++] = polyval(
m, coeff + o,
g->n) / coeff[o +
m + 1];
1721 static const real coeff[] = {
1727 -224, -4784, 1573, 45045,
1729 -10656, 14144, -4576, -858, 45045,
1731 64, 624, -4576, 6864, -3003, 15015,
1733 100, 208, 572, 3432, -12012, 30030, 45045,
1739 5792, 1040, -1287, 135135,
1741 5952, -11648, 9152, -2574, 135135,
1743 -64, -624, 4576, -6864, 3003, 135135,
1749 -8448, 4992, -1144, 225225,
1751 -1440, 4160, -4576, 1716, 225225,
1757 3584, -3328, 1144, 315315,
1765 int o = 0, k = 0,
l,
j;
1766 for (
l = 0;
l < nC4; ++
l) {
1767 for (
j = nC4 - 1;
j >=
l; --
j) {
1768 int m = nC4 -
j - 1;
1769 g->C4x[k++] = polyval(
m, coeff + o,
g->n) / coeff[o +
m + 1];
1781 lon2 = AngNormalize(lon2);
1782 lon12 = AngDiff(
lon1, lon2, 0);
1783 return lon1 <= 0 && lon2 > 0 && lon12 > 0 ? 1 :
1784 (lon2 <= 0 && lon1 > 0 && lon12 < 0 ? -1 : 0);
1790 lon2 = remainder(lon2, (
real)(720));
1791 return ( (lon2 >= 0 && lon2 < 360 ? 0 : 1) -
1792 (
lon1 >= 0 &&
lon1 < 360 ? 0 : 1) );
1796 return ( ((lon2 >= 0 && lon2 < 360) || lon2 < -360 ? 0 : 1) -
1801 void accini(
real s[]) {
1808 t[0] =
s[0];
t[1] =
s[1];
1813 real u,
z = sumx(
y,
s[1], &u);
1814 s[0] = sumx(
z,
s[0], &
s[1]);
1829 void accneg(
real s[]) {
1831 s[0] = -
s[0];
s[1] = -
s[1];
1835 p->polyline = (polylinep != 0);
1840 p->lat0 =
p->lon0 =
p->lat =
p->lon = NaN;
1843 p->num =
p->crossings = 0;
1851 p->lat0 =
p->lat =
lat;
1852 p->lon0 =
p->lon =
lon;
1856 &s12, 0, 0, 0, 0, 0,
p->polyline ? 0 : &S12);
1860 p->crossings += transit(
p->lon,
lon);
1874 0, 0, 0, 0,
p->polyline ? 0 : &S12);
1878 p->crossings += transitdirect(
p->lon,
lon);
1889 real s12, S12,
t[2], area0;
1893 if (!
p->polyline &&
pA) *
pA = 0;
1897 if (pP) *pP =
p->P[0];
1901 &s12, 0, 0, 0, 0, 0, &S12);
1902 if (pP) *pP = accsum(
p->P, s12);
1905 crossings =
p->crossings + transit(
p->lon,
p->lon0);
1906 area0 = 4 * pi *
g->c2;
1908 accadd(
t, (
t[0] < 0 ? 1 : -1) * area0/2);
1917 else if (
t[0] <= -area0/2)
1925 if (
pA) *
pA = 0 +
t[0];
1934 real perimeter, tempsum, area0;
1936 unsigned num =
p->num + 1;
1939 if (!
p->polyline &&
pA) *
pA = 0;
1942 perimeter =
p->P[0];
1943 tempsum =
p->polyline ? 0 :
p->A[0];
1944 crossings =
p->crossings;
1945 for (
i = 0;
i < (
p->polyline ? 1 : 2); ++
i) {
1948 i == 0 ?
p->lat :
lat,
i == 0 ?
p->lon :
lon,
1949 i != 0 ?
p->lat0 :
lat,
i != 0 ?
p->lon0 :
lon,
1950 &s12, 0, 0, 0, 0, 0,
p->polyline ? 0 : &S12);
1954 crossings += transit(
i == 0 ?
p->lon :
lon,
1955 i != 0 ?
p->lon0 :
lon);
1959 if (pP) *pP = perimeter;
1963 area0 = 4 * pi *
g->c2;
1965 tempsum += (tempsum < 0 ? 1 : -1) * area0/2;
1972 if (tempsum > area0/2)
1974 else if (tempsum <= -area0/2)
1977 if (tempsum >= area0)
1979 else if (tempsum < 0)
1982 if (
pA) *
pA = 0 + tempsum;
1991 real perimeter, tempsum, area0;
1993 unsigned num =
p->num + 1;
1996 if (!
p->polyline &&
pA) *
pA = NaN;
1999 perimeter =
p->P[0] +
s;
2001 if (pP) *pP = perimeter;
2006 crossings =
p->crossings;
2013 crossings += transitdirect(
p->lon,
lon);
2015 &s12, 0, 0, 0, 0, 0, &S12);
2018 crossings += transit(
lon,
p->lon0);
2021 area0 = 4 * pi *
g->c2;
2023 tempsum += (tempsum < 0 ? 1 : -1) * area0/2;
2030 if (tempsum > area0/2)
2032 else if (tempsum <= -area0/2)
2035 if (tempsum >= area0)
2037 else if (tempsum < 0)
2040 if (pP) *pP = perimeter;
2041 if (
pA) *
pA = 0 + tempsum;
2051 for (
i = 0;
i <
n; ++
i)