area_ellipse.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /**
  2. * \file area_ellipse.c
  3. *
  4. * \brief GIS Library - Ellipse area routines.
  5. *
  6. * (C) 2001-2008 by the GRASS Development Team
  7. *
  8. * This program is free software under the GNU General Public License
  9. * (>=v2). Read the file COPYING that comes with GRASS for details.
  10. *
  11. * \author GRASS GIS Development Team
  12. *
  13. * \date 1999-2008
  14. */
  15. #include <math.h>
  16. #include <grass/gis.h>
  17. #include "pi.h"
  18. static struct state {
  19. double E;
  20. double M;
  21. } state;
  22. static struct state *st = &state;
  23. /*
  24. * a is semi-major axis, e2 is eccentricity squared, s is a scale factor
  25. * code will fail if e2==0 (sphere)
  26. */
  27. /**
  28. * \brief Begin area calculations for ellipsoid.
  29. *
  30. * Initializes raster area calculations for an ellipsoid, where <b>a</b>
  31. * is the semi-major axis of the ellipse (in meters), <b>e2</b> is the
  32. * ellipsoid eccentricity squared, and <b>s</b> is a scale factor to
  33. * allow for calculations of part of the zone (<b>s</b>=1.0 is full
  34. * zone, <b>s</b>=0.5 is half the zone, and <b>s</b>=360/ew_res is for a
  35. * single grid cell).
  36. * <br>
  37. * <b>Note:</b> <b>e2</b> must be positive. A negative value makes no
  38. * sense, and zero implies a sphere.
  39. *
  40. * \param[in] a semi-major axis
  41. * \param[in] e2 ellipsoid eccentricity
  42. * \param[in] s scale factor
  43. * \return
  44. */
  45. void G_begin_zone_area_on_ellipsoid(double a, double e2, double s)
  46. {
  47. st->E = sqrt(e2);
  48. st->M = s * a * a * M_PI * (1 - e2) / st->E;
  49. }
  50. /**
  51. * \brief Calculate integral for area between two latitudes.
  52. *
  53. * This routine is part of the integral for the area between two
  54. * latitudes.
  55. *
  56. * \param[in] lat
  57. * \return double
  58. */
  59. double G_darea0_on_ellipsoid(double lat)
  60. {
  61. double x;
  62. x = st->E * sin(Radians(lat));
  63. return (st->M * (x / (1.0 - x * x) + 0.5 * log((1.0 + x) / (1.0 - x))));
  64. }
  65. /**
  66. * \brief Calculates area between latitudes.
  67. *
  68. * This routine shows how to calculate area between two lats, but
  69. * isn't efficient for row by row since <i>G_darea0_on_ellipsoid()</i>
  70. * will be called twice for the same lat, once as a <b>south</b> then
  71. * again as a <b>north</b>.
  72. * <br>
  73. * Returns the area between latitudes <b>north</b> and <b>south</b>
  74. * scaled by the factor <b>s</b> passed to
  75. * <i>G_begin_zone_area_on_ellipsoid()</i>.
  76. *
  77. * \param[in] north
  78. * \param[in] south
  79. * \return double
  80. */
  81. double G_area_for_zone_on_ellipsoid(double north, double south)
  82. {
  83. return (G_darea0_on_ellipsoid(north) - G_darea0_on_ellipsoid(south));
  84. }