/Proj4/proj_mdist.c

http://github.com/route-me/route-me · C · 132 lines · 87 code · 4 blank · 41 comment · 9 complexity · 57a36df679a7f7e08818a60f5216408c MD5 · raw file

  1. /*
  2. ** libproj -- library of cartographic projections
  3. **
  4. ** Copyright (c) 2003, 2006 Gerald I. Evenden
  5. */
  6. static const char
  7. LIBPROJ_ID[] = "$Id: proj_mdist.c,v 1.1 2006/10/18 05:21:31 fwarmerdam Exp $";
  8. /*
  9. ** Permission is hereby granted, free of charge, to any person obtaining
  10. ** a copy of this software and associated documentation files (the
  11. ** "Software"), to deal in the Software without restriction, including
  12. ** without limitation the rights to use, copy, modify, merge, publish,
  13. ** distribute, sublicense, and/or sell copies of the Software, and to
  14. ** permit persons to whom the Software is furnished to do so, subject to
  15. ** the following conditions:
  16. **
  17. ** The above copyright notice and this permission notice shall be
  18. ** included in all copies or substantial portions of the Software.
  19. **
  20. ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  23. ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  24. ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  25. ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  26. ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. */
  28. /* Computes distance from equator along the meridian to latitude phi
  29. ** and inverse on unit ellipsoid.
  30. ** Precision commensurate with double precision.
  31. */
  32. #define PROJ_LIB__
  33. #include "projects.h"
  34. #define MAX_ITER 20
  35. #define TOL 1e-14
  36. struct MDIST {
  37. int nb;
  38. double es;
  39. double E;
  40. double b[1];
  41. };
  42. #define B ((struct MDIST *)b)
  43. void *
  44. proj_mdist_ini(double es) {
  45. double numf, numfi, twon1, denf, denfi, ens, T, twon;
  46. double den, El, Es;
  47. double E[MAX_ITER];
  48. struct MDIST *b;
  49. int i, j;
  50. /* generate E(e^2) and its terms E[] */
  51. ens = es;
  52. numf = twon1 = denfi = 1.;
  53. denf = 1.;
  54. twon = 4.;
  55. Es = El = E[0] = 1.;
  56. for (i = 1; i < MAX_ITER ; ++i) {
  57. numf *= (twon1 * twon1);
  58. den = twon * denf * denf * twon1;
  59. T = numf/den;
  60. Es -= (E[i] = T * ens);
  61. ens *= es;
  62. twon *= 4.;
  63. denf *= ++denfi;
  64. twon1 += 2.;
  65. if (Es == El) /* jump out if no change */
  66. break;
  67. El = Es;
  68. }
  69. if ((b = (struct MDIST *)malloc(sizeof(struct MDIST)+
  70. (i*sizeof(double)))) == NULL)
  71. return(NULL);
  72. b->nb = i - 1;
  73. b->es = es;
  74. b->E = Es;
  75. /* generate b_n coefficients--note: collapse with prefix ratios */
  76. b->b[0] = Es = 1. - Es;
  77. numf = denf = 1.;
  78. numfi = 2.;
  79. denfi = 3.;
  80. for (j = 1; j < i; ++j) {
  81. Es -= E[j];
  82. numf *= numfi;
  83. denf *= denfi;
  84. b->b[j] = Es * numf / denf;
  85. numfi += 2.;
  86. denfi += 2.;
  87. }
  88. return (b);
  89. }
  90. double
  91. proj_mdist(double phi, double sphi, double cphi, const void *b) {
  92. double sc, sum, sphi2, D;
  93. int i;
  94. sc = sphi * cphi;
  95. sphi2 = sphi * sphi;
  96. D = phi * B->E - B->es * sc / sqrt(1. - B->es * sphi2);
  97. sum = B->b[i = B->nb];
  98. while (i) sum = B->b[--i] + sphi2 * sum;
  99. return(D + sc * sum);
  100. }
  101. double
  102. proj_inv_mdist(double dist, const void *b) {
  103. double s, t, phi, k;
  104. int i;
  105. k = 1./(1.- B->es);
  106. i = MAX_ITER;
  107. phi = dist;
  108. while ( i-- ) {
  109. s = sin(phi);
  110. t = 1. - B->es * s * s;
  111. phi -= t = (proj_mdist(phi, s, cos(phi), b) - dist) *
  112. (t * sqrt(t)) * k;
  113. if (fabs(t) < TOL) /* that is no change */
  114. return phi;
  115. }
  116. /* convergence failed */
  117. pj_errno = -17;
  118. return phi;
  119. }
  120. /* Revision Log:
  121. ** $Log: proj_mdist.c,v $
  122. ** Revision 1.1 2006/10/18 05:21:31 fwarmerdam
  123. ** New
  124. **
  125. ** Revision 3.1 2006/01/11 01:38:18 gie
  126. ** Initial
  127. **
  128. */