GeographicLib: Geodesic.cpp Source File (original) (raw)

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

31

32#if defined(_MSC_VER)

33

34# pragma warning (disable: 4701)

35#endif

36

38

39 using namespace std;

40

42 : maxit2_(maxit1_ + Math::digits() + 10)

43

44

45

46 , tiny_(sqrt(numeric_limits::min()))

47 , tol0_(numeric_limits::epsilon())

48

49

50

51 , tol1_(200 * tol0_)

52 , tol2_(sqrt(tol0_))

53 , tolb_(tol0_)

54 , xthresh_(1000 * tol2_)

55 , _a(a)

56 , _f(f)

57 , _exact(exact)

58 , _f1(1 - _f)

59 , _e2(_f * (2 - _f))

60 , _ep2(_e2 / Math::sq(_f1))

61 , _n(_f / ( 2 - _f))

62 , _b(_a * _f1)

63 , _c2((Math::sq(_a) + Math::sq(_b) *

64 (_e2 == 0 ? 1 :

65 Math::eatanhe(real(1), (_f < 0 ? -1 : 1) * sqrt(fabs(_e2))) / _e2))

66 / 2)

67

68

69

70

71

72

73

74

75

76

77 , _etol2(real(0.1) * tol2_ /

78 sqrt( fmax(real(0.001), fabs(_f)) * fmin(real(1), 1 - _f/2) / 2 ))

80 {

81 if (_exact)

82 _c2 = _geodexact._c2;

83 else {

84 if (!(isfinite(_a) && _a > 0))

85 throw GeographicErr("Equatorial radius is not positive");

86 if (!(isfinite(_b) && _b > 0))

87 throw GeographicErr("Polar semi-axis is not positive");

88 A3coeff();

89 C3coeff();

90 C4coeff();

91 }

92 }

93

98

99 Math::real Geodesic::SinCosSeries(bool sinp,

101 const real c[], int n) {

102

103

104

105

106

107 c += (n + sinp);

109 ar = 2 * (cosx - sinx) * (cosx + sinx),

110 y0 = n & 1 ? *--c : 0, y1 = 0;

111

112 n /= 2;

113 while (n--) {

114

115 y1 = ar * y0 - y1 + *--c;

116 y0 = ar * y1 - y0 + *--c;

117 }

118 return sinp

119 ? 2 * sinx * cosx * y0

120 : cosx * (y0 - y1);

121 }

122

124 unsigned caps) const {

125 return GeodesicLine(*this, lat1, lon1, azi1, caps);

126 }

127

129 bool arcmode, real s12_a12, unsigned outmask,

130 real& lat2, real& lon2, real& azi2,

131 real& s12, real& m12, real& M12, real& M21,

132 real& S12) const {

133 if (_exact)

134 return _geodexact.GenDirect(lat1, lon1, azi1, arcmode, s12_a12, outmask,

135 lat2, lon2, azi2,

136 s12, m12, M12, M21, S12);

137

139 return GeodesicLine(*this, lat1, lon1, azi1, outmask)

140 .

141 GenPosition(arcmode, s12_a12, outmask,

142 lat2, lon2, azi2, s12, m12, M12, M21, S12);

143 }

144

146 bool arcmode, real s12_a12,

147 unsigned caps) const {

149 real salp1, calp1;

150

152

154 return GeodesicLine(*this, lat1, lon1, azi1, salp1, calp1,

155 caps, arcmode, s12_a12);

156 }

157

159 unsigned caps) const {

160 return GenDirectLine(lat1, lon1, azi1, false, s12, caps);

161 }

162

164 real a12, unsigned caps) const {

165 return GenDirectLine(lat1, lon1, azi1, true, a12, caps);

166 }

167

169 unsigned outmask, real& s12,

173 real& S12) const {

174 if (_exact)

175 return _geodexact.GenInverse(lat1, lon1, lat2, lon2,

176 outmask, s12,

177 salp1, calp1, salp2, calp2,

178 m12, M12, M21, S12);

179

180 using std::isnan;

182

183 int lonsign = signbit(lon12) ? -1 : 1;

184 lon12 *= lonsign; lon12s *= lonsign;

187 slam12, clam12;

188

190

191 lon12s = (Math::hd - lon12) - lon12s;

192

193

196

197

198 int swapp = fabs(lat1) < fabs(lat2) || isnan(lat2) ? -1 : 1;

199 if (swapp < 0) {

200 lonsign *= -1;

201 swap(lat1, lat2);

202 }

203

204 int latsign = signbit(lat1) ? 1 : -1;

205 lat1 *= latsign;

206 lat2 *= latsign;

207

208

209

210

211

212

213

214

215

216

217

218

219 real sbet1, cbet1, sbet2, cbet2, s12x, m12x = Math::NaN();

220

222

223

224 Math::norm(sbet1, cbet1); cbet1 = fmax(tiny_, cbet1);

225

227

228 Math::norm(sbet2, cbet2); cbet2 = fmax(tiny_, cbet2);

229

230

231

232

233

234

235

236

237

238 if (cbet1 < -sbet1) {

239 if (cbet2 == cbet1)

240 sbet2 = copysign(sbet1, sbet2);

241 } else {

242 if (fabs(sbet2) == -sbet1)

243 cbet2 = cbet1;

244 }

245

247 dn1 = sqrt(1 + _ep2 * Math::sq(sbet1)),

248 dn2 = sqrt(1 + _ep2 * Math::sq(sbet2));

249

250 real a12, sig12;

251

252 real Ca[nC_];

253

254 bool meridian = lat1 == -Math::qd || slam12 == 0;

255

256 if (meridian) {

257

258

259

260

261 calp1 = clam12; salp1 = slam12;

262 calp2 = 1; salp2 = 0;

263

265

266 ssig1 = sbet1, csig1 = calp1 * cbet1,

267 ssig2 = sbet2, csig2 = calp2 * cbet2;

268

269

270 sig12 = atan2(fmax(real(0), csig1 * ssig2 - ssig1 * csig2) + real(0),

271 csig1 * csig2 + ssig1 * ssig2);

272 {

274 Lengths(_n, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2, cbet1, cbet2,

276 s12x, m12x, dummy, M12, M21, Ca);

277 }

278

279

280

281

282

283

284

285

286

287

288

289

290 if (sig12 < 1 || m12x >= 0) {

291

292 if (sig12 < 3 * tiny_ ||

293

294 (sig12 < tol0_ && (s12x < 0 || m12x < 0)))

295 sig12 = m12x = s12x = 0;

296 m12x *= _b;

297 s12x *= _b;

299 } else

300

301 meridian = false;

302 }

303

304

305 real omg12 = 0, somg12 = 2, comg12 = 0;

306 if (!meridian &&

307 sbet1 == 0 &&

308 (_f <= 0 || lon12s >= _f * Math::hd)) {

309

310

311 calp1 = calp2 = 0; salp1 = salp2 = 1;

312 s12x = _a * lam12;

313 sig12 = omg12 = lam12 / _f1;

314 m12x = _b * sin(sig12);

316 M12 = M21 = cos(sig12);

317 a12 = lon12 / _f1;

318

319 } else if (!meridian) {

320

321

322

323

324

326 sig12 = InverseStart(sbet1, cbet1, dn1, sbet2, cbet2, dn2,

327 lam12, slam12, clam12,

328 salp1, calp1, salp2, calp2, dnm,

329 Ca);

330

331 if (sig12 >= 0) {

332

333 s12x = sig12 * _b * dnm;

334 m12x = Math::sq(dnm) * _b * sin(sig12 / dnm);

336 M12 = M21 = cos(sig12 / dnm);

338 omg12 = lam12 / (_f1 * dnm);

339 } else {

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354 real ssig1 = 0, csig1 = 0, ssig2 = 0, csig2 = 0, eps = 0, domg12 = 0;

355 unsigned numit = 0;

356

357 real salp1a = tiny_, calp1a = 1, salp1b = tiny_, calp1b = -1;

358 for (bool tripn = false, tripb = false;; ++numit) {

359

360

362 real v = Lambda12(sbet1, cbet1, dn1, sbet2, cbet2, dn2, salp1, calp1,

363 slam12, clam12,

364 salp2, calp2, sig12, ssig1, csig1, ssig2, csig2,

365 eps, domg12, numit < maxit1_, dv, Ca);

366 if (tripb ||

367

368 !(fabs(v) >= (tripn ? 8 : 1) * tol0_) ||

369

370 numit == maxit2_)

371 break;

372

373 if (v > 0 && (numit > maxit1_ || calp1/salp1 > calp1b/salp1b))

374 { salp1b = salp1; calp1b = calp1; }

375 else if (v < 0 && (numit > maxit1_ || calp1/salp1 < calp1a/salp1a))

376 { salp1a = salp1; calp1a = calp1; }

377 if (numit < maxit1_ && dv > 0) {

379 dalp1 = -v/dv;

380

381

382

383 if (fabs(dalp1) < Math::pi()) {

385 sdalp1 = sin(dalp1), cdalp1 = cos(dalp1),

386 nsalp1 = salp1 * cdalp1 + calp1 * sdalp1;

387 if (nsalp1 > 0) {

388 calp1 = calp1 * cdalp1 - salp1 * sdalp1;

389 salp1 = nsalp1;

391

392

393

394 tripn = fabs(v) <= 16 * tol0_;

395 continue;

396 }

397 }

398 }

399

400

401

402

403

404

405

406

407 salp1 = (salp1a + salp1b)/2;

408 calp1 = (calp1a + calp1b)/2;

410 tripn = false;

411 tripb = (fabs(salp1a - salp1) + (calp1a - calp1) < tolb_ ||

412 fabs(salp1 - salp1b) + (calp1 - calp1b) < tolb_);

413 }

414 {

416

417

418 unsigned lengthmask = outmask |

420 Lengths(eps, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2,

421 cbet1, cbet2, lengthmask, s12x, m12x, dummy, M12, M21, Ca);

422 }

423 m12x *= _b;

424 s12x *= _b;

426 if (outmask & AREA) {

427

428 real sdomg12 = sin(domg12), cdomg12 = cos(domg12);

429 somg12 = slam12 * cdomg12 - clam12 * sdomg12;

430 comg12 = clam12 * cdomg12 + slam12 * sdomg12;

431 }

432 }

433 }

434

436 s12 = real(0) + s12x;

437

439 m12 = real(0) + m12x;

440

441 if (outmask & AREA) {

443

444 salp0 = salp1 * cbet1,

445 calp0 = hypot(calp1, salp1 * sbet1);

447 if (calp0 != 0 && salp0 != 0) {

449

450 ssig1 = sbet1, csig1 = calp1 * cbet1,

451 ssig2 = sbet2, csig2 = calp2 * cbet2,

453 eps = k2 / (2 * (1 + sqrt(1 + k2)) + k2),

454

455 A4 = Math::sq(_a) * calp0 * salp0 * _e2;

458 C4f(eps, Ca);

460 B41 = SinCosSeries(false, ssig1, csig1, Ca, nC4_),

461 B42 = SinCosSeries(false, ssig2, csig2, Ca, nC4_);

462 S12 = A4 * (B42 - B41);

463 } else

464

465 S12 = 0;

466 if (!meridian && somg12 == 2) {

467 somg12 = sin(omg12); comg12 = cos(omg12);

468 }

469

470 if (!meridian &&

471

472 comg12 > -real(0.7071) &&

473 sbet2 - sbet1 < real(1.75)) {

474

475

476

477 real domg12 = 1 + comg12, dbet1 = 1 + cbet1, dbet2 = 1 + cbet2;

478 alp12 = 2 * atan2( somg12 * ( sbet1 * dbet2 + sbet2 * dbet1 ),

479 domg12 * ( sbet1 * sbet2 + dbet1 * dbet2 ) );

480 } else {

481

483 salp12 = salp2 * calp1 - calp2 * salp1,

484 calp12 = calp2 * calp1 + salp2 * salp1;

485

486

487

488

489 if (salp12 == 0 && calp12 < 0) {

490 salp12 = tiny_ * calp1;

491 calp12 = -1;

492 }

493 alp12 = atan2(salp12, calp12);

494 }

495 S12 += _c2 * alp12;

496 S12 *= swapp * lonsign * latsign;

497

498 S12 += 0;

499 }

500

501

502 if (swapp < 0) {

503 swap(salp1, salp2);

504 swap(calp1, calp2);

506 swap(M12, M21);

507 }

508

509 salp1 *= swapp * lonsign; calp1 *= swapp * latsign;

510 salp2 *= swapp * lonsign; calp2 *= swapp * latsign;

511

512 return a12;

513 }

514

515 Math::real Geodesic::GenInverse(real lat1, real lon1, real lat2, real lon2,

516 unsigned outmask,

517 real& s12, real& azi1, real& azi2,

518 real& m12, real& M12, real& M21,

519 real& S12) const {

520 outmask &= OUT_MASK;

521 real salp1, calp1, salp2, calp2,

522 a12 = GenInverse(lat1, lon1, lat2, lon2,

523 outmask, s12, salp1, calp1, salp2, calp2,

524 m12, M12, M21, S12);

528 }

529 return a12;

530 }

531

533 real lat2, real lon2,

534 unsigned caps) const {

535 real t, salp1, calp1, salp2, calp2,

536 a12 = GenInverse(lat1, lon1, lat2, lon2,

537

538 0u, t, salp1, calp1, salp2, calp2,

539 t, t, t, t),

541

543 return

544 GeodesicLine(*this, lat1, lon1, azi1, salp1, calp1, caps, true, a12);

545 }

546

547 void Geodesic::Lengths(real eps, real sig12,

550 real cbet1, real cbet2, unsigned outmask,

553

554 real Ca[]) const {

555

556

557

558 outmask &= OUT_MASK;

559

560

561

562

563 real m0x = 0, J12 = 0, A1 = 0, A2 = 0;

564 real Cb[nC2_ + 1];

566 A1 = A1m1f(eps);

567 C1f(eps, Ca);

569 A2 = A2m1f(eps);

570 C2f(eps, Cb);

571 m0x = A1 - A2;

572 A2 = 1 + A2;

573 }

574 A1 = 1 + A1;

575 }

577 real B1 = SinCosSeries(true, ssig2, csig2, Ca, nC1_) -

578 SinCosSeries(true, ssig1, csig1, Ca, nC1_);

579

580 s12b = A1 * (sig12 + B1);

582 real B2 = SinCosSeries(true, ssig2, csig2, Cb, nC2_) -

583 SinCosSeries(true, ssig1, csig1, Cb, nC2_);

584 J12 = m0x * sig12 + (A1 * B1 - A2 * B2);

585 }

587

588 for (int l = 1; l <= nC2_; ++l)

589 Cb[l] = A1 * Ca[l] - A2 * Cb[l];

590 J12 = m0x * sig12 + (SinCosSeries(true, ssig2, csig2, Cb, nC2_) -

591 SinCosSeries(true, ssig1, csig1, Cb, nC2_));

592 }

594 m0 = m0x;

595

596

597

598 m12b = dn2 * (csig1 * ssig2) - dn1 * (ssig1 * csig2) -

599 csig1 * csig2 * J12;

600 }

602 real csig12 = csig1 * csig2 + ssig1 * ssig2;

603 real t = _ep2 * (cbet1 - cbet2) * (cbet1 + cbet2) / (dn1 + dn2);

604 M12 = csig12 + (t * ssig2 - csig2 * J12) * ssig1 / dn1;

605 M21 = csig12 - (t * ssig1 - csig1 * J12) * ssig2 / dn2;

606 }

607 }

608

610

611

616 r = (p + q - 1) / 6;

617 if ( !(q == 0 && r <= 0) ) {

619

620

621 S = p * q / 4,

623 r3 = r * r2,

624

625

626 disc = S * (S + 2 * r3);

628 if (disc >= 0) {

629 real T3 = S + r3;

630

631

632

633 T3 += T3 < 0 ? -sqrt(disc) : sqrt(disc);

634

635 real T = cbrt(T3);

636

637 u += T + (T != 0 ? r2 / T : 0);

638 } else {

639

640 real ang = atan2(sqrt(-disc), -(S + r3));

641

642

643 u += 2 * r * cos(ang / 3);

644 }

646 v = sqrt(Math::sq(u) + q),

647

648 uv = u < 0 ? q / (v - u) : u + v,

649 w = (uv - q) / (2 * v);

650

651

652 k = uv / (sqrt(uv + Math::sq(w)) + w);

653 } else {

654

655

656 k = 0;

657 }

658 return k;

659 }

660

665

667

669

670 real Ca[]) const {

671

672

673

675 sig12 = -1,

676

677 sbet12 = sbet2 * cbet1 - cbet2 * sbet1,

678 cbet12 = cbet2 * cbet1 + sbet2 * sbet1;

679 real sbet12a = sbet2 * cbet1 + cbet2 * sbet1;

680 bool shortline = cbet12 >= 0 && sbet12 < real(0.5) &&

681 cbet2 * lam12 < real(0.5);

682 real somg12, comg12;

683 if (shortline) {

685

686

687 sbetm2 /= sbetm2 + Math::sq(cbet1 + cbet2);

688 dnm = sqrt(1 + _ep2 * sbetm2);

689 real omg12 = lam12 / (_f1 * dnm);

690 somg12 = sin(omg12); comg12 = cos(omg12);

691 } else {

692 somg12 = slam12; comg12 = clam12;

693 }

694

695 salp1 = cbet2 * somg12;

696 calp1 = comg12 >= 0 ?

697 sbet12 + cbet2 * sbet1 * Math::sq(somg12) / (1 + comg12) :

698 sbet12a - cbet2 * sbet1 * Math::sq(somg12) / (1 - comg12);

699

701 ssig12 = hypot(salp1, calp1),

702 csig12 = sbet1 * sbet2 + cbet1 * cbet2 * comg12;

703

704 if (shortline && ssig12 < _etol2) {

705

706 salp2 = cbet1 * somg12;

707 calp2 = sbet12 - cbet1 * sbet2 *

708 (comg12 >= 0 ? Math::sq(somg12) / (1 + comg12) : 1 - comg12);

710

711 sig12 = atan2(ssig12, csig12);

712 } else if (fabs(_n) > real(0.1) ||

713 csig12 >= 0 ||

715

716 } else {

717

718

719 real x, y, lamscale, betscale;

720 real lam12x = atan2(-slam12, -clam12);

721 if (_f >= 0) {

722

723 {

726 eps = k2 / (2 * (1 + sqrt(1 + k2)) + k2);

727 lamscale = _f * cbet1 * A3f(eps) * Math::pi();

728 }

729 betscale = lamscale * cbet1;

730

731 x = lam12x / lamscale;

732 y = sbet12a / betscale;

733 } else {

734

736 cbet12a = cbet2 * cbet1 - sbet2 * sbet1,

737 bet12a = atan2(sbet12a, cbet12a);

738 real m12b, m0, dummy;

739

740

741 Lengths(_n, Math::pi() + bet12a,

742 sbet1, -cbet1, dn1, sbet2, cbet2, dn2,

743 cbet1, cbet2,

744 REDUCEDLENGTH, dummy, m12b, m0, dummy, dummy, Ca);

745 x = -1 + m12b / (cbet1 * cbet2 * m0 * Math::pi());

746 betscale = x < -real(0.01) ? sbet12a / x :

748 lamscale = betscale / cbet1;

749 y = lam12x / lamscale;

750 }

751

752 if (y > -tol1_ && x > -1 - xthresh_) {

753

754

755 if (_f >= 0) {

756 salp1 = fmin(real(1), -x); calp1 = - sqrt(1 - Math::sq(salp1));

757 } else {

758 calp1 = fmax(real(x > -tol1_ ? 0 : -1), x);

759 salp1 = sqrt(1 - Math::sq(calp1));

760 }

761 } else {

762

763

764

765

766

767

768

769

770

771

772

773

774

775

776

777

778

779

780

781

782

783

784

785

786

787

788

789

790

791

792

793

794

795

796 real k = Astroid(x, y);

798 omg12a = lamscale * ( _f >= 0 ? -x * k/(1 + k) : -y * (1 + k)/k );

799 somg12 = sin(omg12a); comg12 = -cos(omg12a);

800

801 salp1 = cbet2 * somg12;

802 calp1 = sbet12a - cbet2 * sbet1 * Math::sq(somg12) / (1 - comg12);

803 }

804 }

805

806 if (!(salp1 <= 0))

808 else {

809 salp1 = 1; calp1 = 0;

810 }

811 return sig12;

812 }

813

823 bool diffp, real& dlam12,

824

825 real Ca[]) const {

826

827 if (sbet1 == 0 && calp1 == 0)

828

829

830 calp1 = -tiny_;

831

833

834 salp0 = salp1 * cbet1,

835 calp0 = hypot(calp1, salp1 * sbet1);

836

837 real somg1, comg1, somg2, comg2, somg12, comg12, lam12;

838

839

840 ssig1 = sbet1; somg1 = salp0 * sbet1;

841 csig1 = comg1 = calp1 * cbet1;

843

844

845

846

847

848

849 salp2 = cbet2 != cbet1 ? salp0 / cbet2 : salp1;

850

851

852

853

854 calp2 = cbet2 != cbet1 || fabs(sbet2) != -sbet1 ?

855 sqrt(Math::sq(calp1 * cbet1) +

856 (cbet1 < -sbet1 ?

857 (cbet2 - cbet1) * (cbet1 + cbet2) :

858 (sbet1 - sbet2) * (sbet1 + sbet2))) / cbet2 :

859 fabs(calp1);

860

861

862 ssig2 = sbet2; somg2 = salp0 * sbet2;

863 csig2 = comg2 = calp2 * cbet2;

865

866

867

868 sig12 = atan2(fmax(real(0), csig1 * ssig2 - ssig1 * csig2) + real(0),

869 csig1 * csig2 + ssig1 * ssig2);

870

871

872 somg12 = fmax(real(0), comg1 * somg2 - somg1 * comg2) + real(0);

873 comg12 = comg1 * comg2 + somg1 * somg2;

874

875 real eta = atan2(somg12 * clam120 - comg12 * slam120,

876 comg12 * clam120 + somg12 * slam120);

879 eps = k2 / (2 * (1 + sqrt(1 + k2)) + k2);

880 C3f(eps, Ca);

881 B312 = (SinCosSeries(true, ssig2, csig2, Ca, nC3_-1) -

882 SinCosSeries(true, ssig1, csig1, Ca, nC3_-1));

883 domg12 = -_f * A3f(eps) * salp0 * (sig12 + B312);

884 lam12 = eta + domg12;

885

886 if (diffp) {

887 if (calp2 == 0)

888 dlam12 = - 2 * _f1 * dn1 / sbet1;

889 else {

891 Lengths(eps, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2,

893 dummy, dlam12, dummy, dummy, dummy, Ca);

894 dlam12 *= _f1 / (calp2 * cbet2);

895 }

896 }

897

898 return lam12;

899 }

900

902

904 }

905

906 void Geodesic::C3f(real eps, real c[]) const {

907

908

909 real mult = 1;

910 int o = 0;

911 for (int l = 1; l < nC3_; ++l) {

912 int m = nC3_ - l - 1;

913 mult *= eps;

915 o += m + 1;

916 }

917

918 }

919

920 void Geodesic::C4f(real eps, real c[]) const {

921

922

923 real mult = 1;

924 int o = 0;

925 for (int l = 0; l < nC4_; ++l) {

926 int m = nC4_ - l - 1;

928 o += m + 1;

929 mult *= eps;

930 }

931

932 }

933

934

935

936

937

938

939

940

941

942

943

944

945

946

947

948

949

950

951

952

953

954

955

956

957

959

960#if GEOGRAPHICLIB_GEODESIC_ORDER/2 == 1

961 static const real coeff[] = {

962

963 1, 0, 4,

964 };

965#elif GEOGRAPHICLIB_GEODESIC_ORDER/2 == 2

966 static const real coeff[] = {

967

968 1, 16, 0, 64,

969 };

970#elif GEOGRAPHICLIB_GEODESIC_ORDER/2 == 3

971 static const real coeff[] = {

972

973 1, 4, 64, 0, 256,

974 };

975#elif GEOGRAPHICLIB_GEODESIC_ORDER/2 == 4

976 static const real coeff[] = {

977

978 25, 64, 256, 4096, 0, 16384,

979 };

980#else

981#error "Bad value for GEOGRAPHICLIB_GEODESIC_ORDER"

982#endif

983 static_assert(sizeof(coeff) / sizeof(real) == nA1_/2 + 2,

984 "Coefficient array size mismatch in A1m1f");

985 int m = nA1_/2;

987 return (t + eps) / (1 - eps);

988 }

989

990

991 void Geodesic::C1f(real eps, real c[]) {

992

993#if GEOGRAPHICLIB_GEODESIC_ORDER == 3

994 static const real coeff[] = {

995

996 3, -8, 16,

997

998 -1, 16,

999

1000 -1, 48,

1001 };

1002#elif GEOGRAPHICLIB_GEODESIC_ORDER == 4

1003 static const real coeff[] = {

1004

1005 3, -8, 16,

1006

1007 1, -2, 32,

1008

1009 -1, 48,

1010

1011 -5, 512,

1012 };

1013#elif GEOGRAPHICLIB_GEODESIC_ORDER == 5

1014 static const real coeff[] = {

1015

1016 -1, 6, -16, 32,

1017

1018 1, -2, 32,

1019

1020 9, -16, 768,

1021

1022 -5, 512,

1023

1024 -7, 1280,

1025 };

1026#elif GEOGRAPHICLIB_GEODESIC_ORDER == 6

1027 static const real coeff[] = {

1028

1029 -1, 6, -16, 32,

1030

1031 -9, 64, -128, 2048,

1032

1033 9, -16, 768,

1034

1035 3, -5, 512,

1036

1037 -7, 1280,

1038

1039 -7, 2048,

1040 };

1041#elif GEOGRAPHICLIB_GEODESIC_ORDER == 7

1042 static const real coeff[] = {

1043

1044 19, -64, 384, -1024, 2048,

1045

1046 -9, 64, -128, 2048,

1047

1048 -9, 72, -128, 6144,

1049

1050 3, -5, 512,

1051

1052 35, -56, 10240,

1053

1054 -7, 2048,

1055

1056 -33, 14336,

1057 };

1058#elif GEOGRAPHICLIB_GEODESIC_ORDER == 8

1059 static const real coeff[] = {

1060

1061 19, -64, 384, -1024, 2048,

1062

1063 7, -18, 128, -256, 4096,

1064

1065 -9, 72, -128, 6144,

1066

1067 -11, 96, -160, 16384,

1068

1069 35, -56, 10240,

1070

1071 9, -14, 4096,

1072

1073 -33, 14336,

1074

1075 -429, 262144,

1076 };

1077#else

1078#error "Bad value for GEOGRAPHICLIB_GEODESIC_ORDER"

1079#endif

1080 static_assert(sizeof(coeff) / sizeof(real) ==

1081 (nC1_*nC1_ + 7*nC1_ - 2*(nC1_/2)) / 4,

1082 "Coefficient array size mismatch in C1f");

1085 d = eps;

1086 int o = 0;

1087 for (int l = 1; l <= nC1_; ++l) {

1088 int m = (nC1_ - l) / 2;

1089 c[l] = d * Math::polyval(m, coeff + o, eps2) / coeff[o + m + 1];

1090 o += m + 2;

1091 d *= eps;

1092 }

1093

1094 }

1095

1096

1097 void Geodesic::C1pf(real eps, real c[]) {

1098

1099#if GEOGRAPHICLIB_GEODESIC_ORDER == 3

1100 static const real coeff[] = {

1101

1102 -9, 16, 32,

1103

1104 5, 16,

1105

1106 29, 96,

1107 };

1108#elif GEOGRAPHICLIB_GEODESIC_ORDER == 4

1109 static const real coeff[] = {

1110

1111 -9, 16, 32,

1112

1113 -37, 30, 96,

1114

1115 29, 96,

1116

1117 539, 1536,

1118 };

1119#elif GEOGRAPHICLIB_GEODESIC_ORDER == 5

1120 static const real coeff[] = {

1121

1122 205, -432, 768, 1536,

1123

1124 -37, 30, 96,

1125

1126 -225, 116, 384,

1127

1128 539, 1536,

1129

1130 3467, 7680,

1131 };

1132#elif GEOGRAPHICLIB_GEODESIC_ORDER == 6

1133 static const real coeff[] = {

1134

1135 205, -432, 768, 1536,

1136

1137 4005, -4736, 3840, 12288,

1138

1139 -225, 116, 384,

1140

1141 -7173, 2695, 7680,

1142

1143 3467, 7680,

1144

1145 38081, 61440,

1146 };

1147#elif GEOGRAPHICLIB_GEODESIC_ORDER == 7

1148 static const real coeff[] = {

1149

1150 -4879, 9840, -20736, 36864, 73728,

1151

1152 4005, -4736, 3840, 12288,

1153

1154 8703, -7200, 3712, 12288,

1155

1156 -7173, 2695, 7680,

1157

1158 -141115, 41604, 92160,

1159

1160 38081, 61440,

1161

1162 459485, 516096,

1163 };

1164#elif GEOGRAPHICLIB_GEODESIC_ORDER == 8

1165 static const real coeff[] = {

1166

1167 -4879, 9840, -20736, 36864, 73728,

1168

1169 -86171, 120150, -142080, 115200, 368640,

1170

1171 8703, -7200, 3712, 12288,

1172

1173 1082857, -688608, 258720, 737280,

1174

1175 -141115, 41604, 92160,

1176

1177 -2200311, 533134, 860160,

1178

1179 459485, 516096,

1180

1181 109167851, 82575360,

1182 };

1183#else

1184#error "Bad value for GEOGRAPHICLIB_GEODESIC_ORDER"

1185#endif

1186 static_assert(sizeof(coeff) / sizeof(real) ==

1187 (nC1p_*nC1p_ + 7*nC1p_ - 2*(nC1p_/2)) / 4,

1188 "Coefficient array size mismatch in C1pf");

1191 d = eps;

1192 int o = 0;

1193 for (int l = 1; l <= nC1p_; ++l) {

1194 int m = (nC1p_ - l) / 2;

1195 c[l] = d * Math::polyval(m, coeff + o, eps2) / coeff[o + m + 1];

1196 o += m + 2;

1197 d *= eps;

1198 }

1199

1200 }

1201

1202

1204

1205#if GEOGRAPHICLIB_GEODESIC_ORDER/2 == 1

1206 static const real coeff[] = {

1207

1208 -3, 0, 4,

1209 };

1210#elif GEOGRAPHICLIB_GEODESIC_ORDER/2 == 2

1211 static const real coeff[] = {

1212

1213 -7, -48, 0, 64,

1214 };

1215#elif GEOGRAPHICLIB_GEODESIC_ORDER/2 == 3

1216 static const real coeff[] = {

1217

1218 -11, -28, -192, 0, 256,

1219 };

1220#elif GEOGRAPHICLIB_GEODESIC_ORDER/2 == 4

1221 static const real coeff[] = {

1222

1223 -375, -704, -1792, -12288, 0, 16384,

1224 };

1225#else

1226#error "Bad value for GEOGRAPHICLIB_GEODESIC_ORDER"

1227#endif

1228 static_assert(sizeof(coeff) / sizeof(real) == nA2_/2 + 2,

1229 "Coefficient array size mismatch in A2m1f");

1230 int m = nA2_/2;

1232 return (t - eps) / (1 + eps);

1233 }

1234

1235

1236 void Geodesic::C2f(real eps, real c[]) {

1237

1238#if GEOGRAPHICLIB_GEODESIC_ORDER == 3

1239 static const real coeff[] = {

1240

1241 1, 8, 16,

1242

1243 3, 16,

1244

1245 5, 48,

1246 };

1247#elif GEOGRAPHICLIB_GEODESIC_ORDER == 4

1248 static const real coeff[] = {

1249

1250 1, 8, 16,

1251

1252 1, 6, 32,

1253

1254 5, 48,

1255

1256 35, 512,

1257 };

1258#elif GEOGRAPHICLIB_GEODESIC_ORDER == 5

1259 static const real coeff[] = {

1260

1261 1, 2, 16, 32,

1262

1263 1, 6, 32,

1264

1265 15, 80, 768,

1266

1267 35, 512,

1268

1269 63, 1280,

1270 };

1271#elif GEOGRAPHICLIB_GEODESIC_ORDER == 6

1272 static const real coeff[] = {

1273

1274 1, 2, 16, 32,

1275

1276 35, 64, 384, 2048,

1277

1278 15, 80, 768,

1279

1280 7, 35, 512,

1281

1282 63, 1280,

1283

1284 77, 2048,

1285 };

1286#elif GEOGRAPHICLIB_GEODESIC_ORDER == 7

1287 static const real coeff[] = {

1288

1289 41, 64, 128, 1024, 2048,

1290

1291 35, 64, 384, 2048,

1292

1293 69, 120, 640, 6144,

1294

1295 7, 35, 512,

1296

1297 105, 504, 10240,

1298

1299 77, 2048,

1300

1301 429, 14336,

1302 };

1303#elif GEOGRAPHICLIB_GEODESIC_ORDER == 8

1304 static const real coeff[] = {

1305

1306 41, 64, 128, 1024, 2048,

1307

1308 47, 70, 128, 768, 4096,

1309

1310 69, 120, 640, 6144,

1311

1312 133, 224, 1120, 16384,

1313

1314 105, 504, 10240,

1315

1316 33, 154, 4096,

1317

1318 429, 14336,

1319

1320 6435, 262144,

1321 };

1322#else

1323#error "Bad value for GEOGRAPHICLIB_GEODESIC_ORDER"

1324#endif

1325 static_assert(sizeof(coeff) / sizeof(real) ==

1326 (nC2_*nC2_ + 7*nC2_ - 2*(nC2_/2)) / 4,

1327 "Coefficient array size mismatch in C2f");

1330 d = eps;

1331 int o = 0;

1332 for (int l = 1; l <= nC2_; ++l) {

1333 int m = (nC2_ - l) / 2;

1334 c[l] = d * Math::polyval(m, coeff + o, eps2) / coeff[o + m + 1];

1335 o += m + 2;

1336 d *= eps;

1337 }

1338

1339 }

1340

1341

1342 void Geodesic::A3coeff() {

1343

1344#if GEOGRAPHICLIB_GEODESIC_ORDER == 3

1345 static const real coeff[] = {

1346

1347 -1, 4,

1348

1349 1, -1, 2,

1350

1351 1, 1,

1352 };

1353#elif GEOGRAPHICLIB_GEODESIC_ORDER == 4

1354 static const real coeff[] = {

1355

1356 -1, 16,

1357

1358 -1, -2, 8,

1359

1360 1, -1, 2,

1361

1362 1, 1,

1363 };

1364#elif GEOGRAPHICLIB_GEODESIC_ORDER == 5

1365 static const real coeff[] = {

1366

1367 -3, 64,

1368

1369 -3, -1, 16,

1370

1371 3, -1, -2, 8,

1372

1373 1, -1, 2,

1374

1375 1, 1,

1376 };

1377#elif GEOGRAPHICLIB_GEODESIC_ORDER == 6

1378 static const real coeff[] = {

1379

1380 -3, 128,

1381

1382 -2, -3, 64,

1383

1384 -1, -3, -1, 16,

1385

1386 3, -1, -2, 8,

1387

1388 1, -1, 2,

1389

1390 1, 1,

1391 };

1392#elif GEOGRAPHICLIB_GEODESIC_ORDER == 7

1393 static const real coeff[] = {

1394

1395 -5, 256,

1396

1397 -5, -3, 128,

1398

1399 -10, -2, -3, 64,

1400

1401 5, -1, -3, -1, 16,

1402

1403 3, -1, -2, 8,

1404

1405 1, -1, 2,

1406

1407 1, 1,

1408 };

1409#elif GEOGRAPHICLIB_GEODESIC_ORDER == 8

1410 static const real coeff[] = {

1411

1412 -25, 2048,

1413

1414 -15, -20, 1024,

1415

1416 -5, -10, -6, 256,

1417

1418 -5, -20, -4, -6, 128,

1419

1420 5, -1, -3, -1, 16,

1421

1422 3, -1, -2, 8,

1423

1424 1, -1, 2,

1425

1426 1, 1,

1427 };

1428#else

1429#error "Bad value for GEOGRAPHICLIB_GEODESIC_ORDER"

1430#endif

1431 static_assert(sizeof(coeff) / sizeof(real) ==

1432 (nA3_*nA3_ + 7*nA3_ - 2*(nA3_/2)) / 4,

1433 "Coefficient array size mismatch in A3f");

1434 int o = 0, k = 0;

1435 for (int j = nA3_ - 1; j >= 0; --j) {

1436 int m = min(nA3_ - j - 1, j);

1437 _aA3x[k++] = Math::polyval(m, coeff + o, _n) / coeff[o + m + 1];

1438 o += m + 2;

1439 }

1440

1441 }

1442

1443

1444 void Geodesic::C3coeff() {

1445

1446#if GEOGRAPHICLIB_GEODESIC_ORDER == 3

1447 static const real coeff[] = {

1448

1449 1, 8,

1450

1451 -1, 1, 4,

1452

1453 1, 16,

1454 };

1455#elif GEOGRAPHICLIB_GEODESIC_ORDER == 4

1456 static const real coeff[] = {

1457

1458 3, 64,

1459

1460

1461

1462 0, 1, 8,

1463

1464 -1, 1, 4,

1465

1466 3, 64,

1467

1468 -3, 2, 32,

1469

1470 5, 192,

1471 };

1472#elif GEOGRAPHICLIB_GEODESIC_ORDER == 5

1473 static const real coeff[] = {

1474

1475 5, 128,

1476

1477 3, 3, 64,

1478

1479 -1, 0, 1, 8,

1480

1481 -1, 1, 4,

1482

1483 3, 128,

1484

1485 -2, 3, 64,

1486

1487 1, -3, 2, 32,

1488

1489 3, 128,

1490

1491 -9, 5, 192,

1492

1493 7, 512,

1494 };

1495#elif GEOGRAPHICLIB_GEODESIC_ORDER == 6

1496 static const real coeff[] = {

1497

1498 3, 128,

1499

1500 2, 5, 128,

1501

1502 -1, 3, 3, 64,

1503

1504 -1, 0, 1, 8,

1505

1506 -1, 1, 4,

1507

1508 5, 256,

1509

1510 1, 3, 128,

1511

1512 -3, -2, 3, 64,

1513

1514 1, -3, 2, 32,

1515

1516 7, 512,

1517

1518 -10, 9, 384,

1519

1520 5, -9, 5, 192,

1521

1522 7, 512,

1523

1524 -14, 7, 512,

1525

1526 21, 2560,

1527 };

1528#elif GEOGRAPHICLIB_GEODESIC_ORDER == 7

1529 static const real coeff[] = {

1530

1531 21, 1024,

1532

1533 11, 12, 512,

1534

1535 2, 2, 5, 128,

1536

1537 -5, -1, 3, 3, 64,

1538

1539 -1, 0, 1, 8,

1540

1541 -1, 1, 4,

1542

1543 27, 2048,

1544

1545 1, 5, 256,

1546

1547 -9, 2, 6, 256,

1548

1549 2, -3, -2, 3, 64,

1550

1551 1, -3, 2, 32,

1552

1553 3, 256,

1554

1555 -4, 21, 1536,

1556

1557 -6, -10, 9, 384,

1558

1559 -1, 5, -9, 5, 192,

1560

1561 9, 1024,

1562

1563 -10, 7, 512,

1564

1565 10, -14, 7, 512,

1566

1567 9, 1024,

1568

1569 -45, 21, 2560,

1570

1571 11, 2048,

1572 };

1573#elif GEOGRAPHICLIB_GEODESIC_ORDER == 8

1574 static const real coeff[] = {

1575

1576 243, 16384,

1577

1578 10, 21, 1024,

1579

1580 3, 11, 12, 512,

1581

1582 -2, 2, 2, 5, 128,

1583

1584 -5, -1, 3, 3, 64,

1585

1586 -1, 0, 1, 8,

1587

1588 -1, 1, 4,

1589

1590 187, 16384,

1591

1592 69, 108, 8192,

1593

1594 -2, 1, 5, 256,

1595

1596 -6, -9, 2, 6, 256,

1597

1598 2, -3, -2, 3, 64,

1599

1600 1, -3, 2, 32,

1601

1602 139, 16384,

1603

1604 -1, 12, 1024,

1605

1606 -77, -8, 42, 3072,

1607

1608 10, -6, -10, 9, 384,

1609

1610 -1, 5, -9, 5, 192,

1611

1612 127, 16384,

1613

1614 -43, 72, 8192,

1615

1616 -7, -40, 28, 2048,

1617

1618 -7, 20, -28, 14, 1024,

1619

1620 99, 16384,

1621

1622 -15, 9, 1024,

1623

1624 75, -90, 42, 5120,

1625

1626 99, 16384,

1627

1628 -99, 44, 8192,

1629

1630 429, 114688,

1631 };

1632#else

1633#error "Bad value for GEOGRAPHICLIB_GEODESIC_ORDER"

1634#endif

1635 static_assert(sizeof(coeff) / sizeof(real) ==

1636 ((nC3_-1)*(nC3_*nC3_ + 7*nC3_ - 2*(nC3_/2)))/8,

1637 "Coefficient array size mismatch in C3coeff");

1638 int o = 0, k = 0;

1639 for (int l = 1; l < nC3_; ++l) {

1640 for (int j = nC3_ - 1; j >= l; --j) {

1641 int m = min(nC3_ - j - 1, j);

1642 _cC3x[k++] = Math::polyval(m, coeff + o, _n) / coeff[o + m + 1];

1643 o += m + 2;

1644 }

1645 }

1646

1647 }

1648

1649 void Geodesic::C4coeff() {

1650

1651#if GEOGRAPHICLIB_GEODESIC_ORDER == 3

1652 static const real coeff[] = {

1653

1654 -2, 105,

1655

1656 16, -7, 35,

1657

1658 8, -28, 70, 105,

1659

1660 -2, 105,

1661

1662 -16, 7, 315,

1663

1664 4, 525,

1665 };

1666#elif GEOGRAPHICLIB_GEODESIC_ORDER == 4

1667 static const real coeff[] = {

1668

1669 11, 315,

1670

1671 -32, -6, 315,

1672

1673 -32, 48, -21, 105,

1674

1675 4, 24, -84, 210, 315,

1676

1677 -1, 105,

1678

1679 64, -18, 945,

1680

1681 32, -48, 21, 945,

1682

1683 -8, 1575,

1684

1685 -32, 12, 1575,

1686

1687 8, 2205,

1688 };

1689#elif GEOGRAPHICLIB_GEODESIC_ORDER == 5

1690 static const real coeff[] = {

1691

1692 4, 1155,

1693

1694 -368, 121, 3465,

1695

1696 1088, -352, -66, 3465,

1697

1698 48, -352, 528, -231, 1155,

1699

1700 16, 44, 264, -924, 2310, 3465,

1701

1702 4, 1155,

1703

1704 80, -99, 10395,

1705

1706 -896, 704, -198, 10395,

1707

1708 -48, 352, -528, 231, 10395,

1709

1710 -8, 1925,

1711

1712 384, -88, 17325,

1713

1714 320, -352, 132, 17325,

1715

1716 -16, 8085,

1717

1718 -256, 88, 24255,

1719

1720 64, 31185,

1721 };

1722#elif GEOGRAPHICLIB_GEODESIC_ORDER == 6

1723 static const real coeff[] = {

1724

1725 97, 15015,

1726

1727 1088, 156, 45045,

1728

1729 -224, -4784, 1573, 45045,

1730

1731 -10656, 14144, -4576, -858, 45045,

1732

1733 64, 624, -4576, 6864, -3003, 15015,

1734

1735 100, 208, 572, 3432, -12012, 30030, 45045,

1736

1737 1, 9009,

1738

1739 -2944, 468, 135135,

1740

1741 5792, 1040, -1287, 135135,

1742

1743 5952, -11648, 9152, -2574, 135135,

1744

1745 -64, -624, 4576, -6864, 3003, 135135,

1746

1747 8, 10725,

1748

1749 1856, -936, 225225,

1750

1751 -8448, 4992, -1144, 225225,

1752

1753 -1440, 4160, -4576, 1716, 225225,

1754

1755 -136, 63063,

1756

1757 1024, -208, 105105,

1758

1759 3584, -3328, 1144, 315315,

1760

1761 -128, 135135,

1762

1763 -2560, 832, 405405,

1764

1765 128, 99099,

1766 };

1767#elif GEOGRAPHICLIB_GEODESIC_ORDER == 7

1768 static const real coeff[] = {

1769

1770 10, 9009,

1771

1772 -464, 291, 45045,

1773

1774 -4480, 1088, 156, 45045,

1775

1776 10736, -224, -4784, 1573, 45045,

1777

1778 1664, -10656, 14144, -4576, -858, 45045,

1779

1780 16, 64, 624, -4576, 6864, -3003, 15015,

1781

1782 56, 100, 208, 572, 3432, -12012, 30030, 45045,

1783

1784 10, 9009,

1785

1786 112, 15, 135135,

1787

1788 3840, -2944, 468, 135135,

1789

1790 -10704, 5792, 1040, -1287, 135135,

1791

1792 -768, 5952, -11648, 9152, -2574, 135135,

1793

1794 -16, -64, -624, 4576, -6864, 3003, 135135,

1795

1796 -4, 25025,

1797

1798 -1664, 168, 225225,

1799

1800 1664, 1856, -936, 225225,

1801

1802 6784, -8448, 4992, -1144, 225225,

1803

1804 128, -1440, 4160, -4576, 1716, 225225,

1805

1806 64, 315315,

1807

1808 1792, -680, 315315,

1809

1810 -2048, 1024, -208, 105105,

1811

1812 -1792, 3584, -3328, 1144, 315315,

1813

1814 -512, 405405,

1815

1816 2048, -384, 405405,

1817

1818 3072, -2560, 832, 405405,

1819

1820 -256, 495495,

1821

1822 -2048, 640, 495495,

1823

1824 512, 585585,

1825 };

1826#elif GEOGRAPHICLIB_GEODESIC_ORDER == 8

1827 static const real coeff[] = {

1828

1829 193, 85085,

1830

1831 4192, 850, 765765,

1832

1833 20960, -7888, 4947, 765765,

1834

1835 12480, -76160, 18496, 2652, 765765,

1836

1837 -154048, 182512, -3808, -81328, 26741, 765765,

1838

1839 3232, 28288, -181152, 240448, -77792, -14586, 765765,

1840

1841 96, 272, 1088, 10608, -77792, 116688, -51051, 255255,

1842

1843 588, 952, 1700, 3536, 9724, 58344, -204204, 510510, 765765,

1844

1845 349, 2297295,

1846

1847 -1472, 510, 459459,

1848

1849 -39840, 1904, 255, 2297295,

1850

1851 52608, 65280, -50048, 7956, 2297295,

1852

1853 103744, -181968, 98464, 17680, -21879, 2297295,

1854

1855 -1344, -13056, 101184, -198016, 155584, -43758, 2297295,

1856

1857 -96, -272, -1088, -10608, 77792, -116688, 51051, 2297295,

1858

1859 464, 1276275,

1860

1861 -928, -612, 3828825,

1862

1863 64256, -28288, 2856, 3828825,

1864

1865 -126528, 28288, 31552, -15912, 3828825,

1866

1867 -41472, 115328, -143616, 84864, -19448, 3828825,

1868

1869 160, 2176, -24480, 70720, -77792, 29172, 3828825,

1870

1871 -16, 97461,

1872

1873 -16384, 1088, 5360355,

1874

1875 -2560, 30464, -11560, 5360355,

1876

1877 35840, -34816, 17408, -3536, 1786785,

1878

1879 7168, -30464, 60928, -56576, 19448, 5360355,

1880

1881 128, 2297295,

1882

1883 26624, -8704, 6891885,

1884

1885 -77824, 34816, -6528, 6891885,

1886

1887 -32256, 52224, -43520, 14144, 6891885,

1888

1889 -6784, 8423415,

1890

1891 24576, -4352, 8423415,

1892

1893 45056, -34816, 10880, 8423415,

1894

1895 -1024, 3318315,

1896

1897 -28672, 8704, 9954945,

1898

1899 1024, 1640925,

1900 };

1901#else

1902#error "Bad value for GEOGRAPHICLIB_GEODESIC_ORDER"

1903#endif

1904 static_assert(sizeof(coeff) / sizeof(real) ==

1905 (nC4_ * (nC4_ + 1) * (nC4_ + 5)) / 6,

1906 "Coefficient array size mismatch in C4coeff");

1907 int o = 0, k = 0;

1908 for (int l = 0; l < nC4_; ++l) {

1909 for (int j = nC4_ - 1; j >= l; --j) {

1910 int m = nC4_ - j - 1;

1911 _cC4x[k++] = Math::polyval(m, coeff + o, _n) / coeff[o + m + 1];

1912 o += m + 2;

1913 }

1914 }

1915

1916 }

1917

1918}

GeographicLib::Math::real real

Header for GeographicLib::GeodesicLine class.

Header for GeographicLib::Geodesic class.

Exact geodesic calculations.

Math::real GenDirect(real lat1, real lon1, real azi1, bool arcmode, real s12_a12, unsigned outmask, real &lat2, real &lon2, real &azi2, real &s12, real &m12, real &M12, real &M21, real &S12) const

GeodesicLine InverseLine(real lat1, real lon1, real lat2, real lon2, unsigned caps=ALL) const

Definition Geodesic.cpp:532

static const Geodesic & WGS84()

Definition Geodesic.cpp:94

GeodesicLine ArcDirectLine(real lat1, real lon1, real azi1, real a12, unsigned caps=ALL) const

Definition Geodesic.cpp:163

GeodesicLine Line(real lat1, real lon1, real azi1, unsigned caps=ALL) const

Definition Geodesic.cpp:123

GeodesicLine GenDirectLine(real lat1, real lon1, real azi1, bool arcmode, real s12_a12, unsigned caps=ALL) const

Definition Geodesic.cpp:145

friend class GeodesicLine

Math::real GenDirect(real lat1, real lon1, real azi1, bool arcmode, real s12_a12, unsigned outmask, real &lat2, real &lon2, real &azi2, real &s12, real &m12, real &M12, real &M21, real &S12) const

Definition Geodesic.cpp:128

GeodesicLine DirectLine(real lat1, real lon1, real azi1, real s12, unsigned caps=ALL) const

Definition Geodesic.cpp:158

Geodesic(real a, real f, bool exact=false)

Definition Geodesic.cpp:41

Exception handling for GeographicLib.

Mathematical functions needed by GeographicLib.

static void sincosd(T x, T &sinx, T &cosx)

static T atan2d(T y, T x)

static void norm(T &x, T &y)

static constexpr int qd

degrees per quarter turn

static T AngNormalize(T x)

static void sincosde(T x, T t, T &sinx, T &cosx)

static T polyval(int N, const T p[], T x)

static T AngDiff(T x, T y, T &e)

static constexpr int hd

degrees per half turn

Namespace for GeographicLib.

void swap(GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &a, GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &b)