/Proj4/pj_mlfn.c

http://github.com/route-me/route-me · C · 61 lines · 54 code · 2 blank · 5 comment · 3 complexity · 0a33f005f884f2ca1a56a9b9ece4d2ca MD5 · raw file

  1. #ifndef lint
  2. static const char SCCSID[]="@(#)pj_mlfn.c 4.5 95/07/06 GIE REL";
  3. #endif
  4. #include "projects.h"
  5. /* meridinal distance for ellipsoid and inverse
  6. ** 8th degree - accurate to < 1e-5 meters when used in conjuction
  7. ** with typical major axis values.
  8. ** Inverse determines phi to EPS (1e-11) radians, about 1e-6 seconds.
  9. */
  10. #define C00 1.
  11. #define C02 .25
  12. #define C04 .046875
  13. #define C06 .01953125
  14. #define C08 .01068115234375
  15. #define C22 .75
  16. #define C44 .46875
  17. #define C46 .01302083333333333333
  18. #define C48 .00712076822916666666
  19. #define C66 .36458333333333333333
  20. #define C68 .00569661458333333333
  21. #define C88 .3076171875
  22. #define EPS 1e-11
  23. #define MAX_ITER 10
  24. #define EN_SIZE 5
  25. double *
  26. pj_enfn(double es) {
  27. double t, *en;
  28. en = (double *)pj_malloc(EN_SIZE * sizeof(double));
  29. if (en) {
  30. en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08)));
  31. en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08)));
  32. en[2] = (t = es * es) * (C44 - es * (C46 + es * C48));
  33. en[3] = (t *= es) * (C66 - es * C68);
  34. en[4] = t * es * C88;
  35. } /* else return NULL if unable to allocate memory */
  36. return en;
  37. }
  38. double
  39. pj_mlfn(double phi, double sphi, double cphi, double *en) {
  40. cphi *= sphi;
  41. sphi *= sphi;
  42. return(en[0] * phi - cphi * (en[1] + sphi*(en[2]
  43. + sphi*(en[3] + sphi*en[4]))));
  44. }
  45. double
  46. pj_inv_mlfn(double arg, double es, double *en) {
  47. double s, t, phi, k = 1./(1.-es);
  48. int i;
  49. phi = arg;
  50. for (i = MAX_ITER; i ; --i) { /* rarely goes over 2 iterations */
  51. s = sin(phi);
  52. t = 1. - es * s * s;
  53. phi -= t = (pj_mlfn(phi, s, cos(phi), en) - arg) * (t * sqrt(t)) * k;
  54. if (fabs(t) < EPS)
  55. return phi;
  56. }
  57. pj_errno = -17;
  58. return phi;
  59. }