/Proj4/PJ_gn_sinu.c

http://github.com/route-me/route-me · C · 103 lines · 97 code · 4 blank · 2 comment · 18 complexity · d256ab339699281799f1be84cd4296db MD5 · raw file

  1. #ifndef lint
  2. static const char SCCSID[]="@(#)PJ_gn_sinu.c 4.1 94/02/15 GIE REL";
  3. #endif
  4. #define PROJ_PARMS__ \
  5. double *en; \
  6. double m, n, C_x, C_y;
  7. #define PJ_LIB__
  8. #include "projects.h"
  9. PROJ_HEAD(gn_sinu, "General Sinusoidal Series") "\n\tPCyl, Sph.\n\tm= n=";
  10. PROJ_HEAD(sinu, "Sinusoidal (Sanson-Flamsteed)") "\n\tPCyl, Sph&Ell";
  11. PROJ_HEAD(eck6, "Eckert VI") "\n\tPCyl, Sph.";
  12. PROJ_HEAD(mbtfps, "McBryde-Thomas Flat-Polar Sinusoidal") "\n\tPCyl, Sph.";
  13. #define EPS10 1e-10
  14. #define MAX_ITER 8
  15. #define LOOP_TOL 1e-7
  16. /* Ellipsoidal Sinusoidal only */
  17. FORWARD(e_forward); /* ellipsoid */
  18. double s, c;
  19. xy.y = pj_mlfn(lp.phi, s = sin(lp.phi), c = cos(lp.phi), P->en);
  20. xy.x = lp.lam * c / sqrt(1. - P->es * s * s);
  21. return (xy);
  22. }
  23. INVERSE(e_inverse); /* ellipsoid */
  24. double s;
  25. if ((s = fabs(lp.phi = pj_inv_mlfn(xy.y, P->es, P->en))) < HALFPI) {
  26. s = sin(lp.phi);
  27. lp.lam = xy.x * sqrt(1. - P->es * s * s) / cos(lp.phi);
  28. } else if ((s - EPS10) < HALFPI)
  29. lp.lam = 0.;
  30. else I_ERROR;
  31. return (lp);
  32. }
  33. /* General spherical sinusoidals */
  34. FORWARD(s_forward); /* sphere */
  35. if (!P->m)
  36. lp.phi = P->n != 1. ? aasin(P->n * sin(lp.phi)): lp.phi;
  37. else {
  38. double k, V;
  39. int i;
  40. k = P->n * sin(lp.phi);
  41. for (i = MAX_ITER; i ; --i) {
  42. lp.phi -= V = (P->m * lp.phi + sin(lp.phi) - k) /
  43. (P->m + cos(lp.phi));
  44. if (fabs(V) < LOOP_TOL)
  45. break;
  46. }
  47. if (!i)
  48. F_ERROR
  49. }
  50. xy.x = P->C_x * lp.lam * (P->m + cos(lp.phi));
  51. xy.y = P->C_y * lp.phi;
  52. return (xy);
  53. }
  54. INVERSE(s_inverse); /* sphere */
  55. double s;
  56. xy.y /= P->C_y;
  57. lp.phi = P->m ? aasin((P->m * xy.y + sin(xy.y)) / P->n) :
  58. ( P->n != 1. ? aasin(sin(xy.y) / P->n) : xy.y );
  59. lp.lam = xy.x / (P->C_x * (P->m + cos(xy.y)));
  60. return (lp);
  61. }
  62. FREEUP; if (P) { if (P->en) pj_dalloc(P->en); pj_dalloc(P); } }
  63. static void /* for spheres, only */
  64. setup(PJ *P) {
  65. P->es = 0;
  66. P->C_x = (P->C_y = sqrt((P->m + 1.) / P->n))/(P->m + 1.);
  67. P->inv = s_inverse;
  68. P->fwd = s_forward;
  69. }
  70. ENTRY1(sinu, en)
  71. if (!(P->en = pj_enfn(P->es)))
  72. E_ERROR_0;
  73. if (P->es) {
  74. P->inv = e_inverse;
  75. P->fwd = e_forward;
  76. } else {
  77. P->n = 1.;
  78. P->m = 0.;
  79. setup(P);
  80. }
  81. ENDENTRY(P)
  82. ENTRY1(eck6, en)
  83. P->m = 1.;
  84. P->n = 2.570796326794896619231321691;
  85. setup(P);
  86. ENDENTRY(P)
  87. ENTRY1(mbtfps, en)
  88. P->m = 0.5;
  89. P->n = 1.785398163397448309615660845;
  90. setup(P);
  91. ENDENTRY(P)
  92. ENTRY1(gn_sinu, en)
  93. if (pj_param(P->params, "tn").i && pj_param(P->params, "tm").i) {
  94. P->n = pj_param(P->params, "dn").f;
  95. P->m = pj_param(P->params, "dm").f;
  96. } else
  97. E_ERROR(-99)
  98. setup(P);
  99. ENDENTRY(P)