area.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include <math.h>
  2. #include <grass/gis.h>
  3. #include <grass/raster.h>
  4. #include "local_proto.h"
  5. void add_row_area(DCELL * top, DCELL * bottom, double sz, struct Cell_head *w,
  6. double *low, double *high)
  7. {
  8. double guess1, guess2, mag, tedge1[3], tedge2[3], crossp[3];
  9. int col;
  10. for (col = 0; col < w->cols - 1; col++) {
  11. /*
  12. For each cell**, we triangulate the four corners in
  13. two different ways, 1) UppperLeft to LowerRight diagonal
  14. and 2) LowerLeft to UpperRight diagonal. Then we add the
  15. smaller of the two areas to "low" and the greater of
  16. the two areas to "high".
  17. ** here, the "cell" is actually the quadrangle formed by
  18. the center point of four cells, since these are the
  19. known elevation points.
  20. */
  21. /* If NAN go to next or we get NAN for everything */
  22. if (Rast_is_d_null_value(&(bottom[col + 1])) ||
  23. Rast_is_d_null_value(&(top[col])) ||
  24. Rast_is_d_null_value(&(top[col + 1])) ||
  25. Rast_is_d_null_value(&(bottom[col]))
  26. )
  27. continue;
  28. /* guess1 --- ul to lr diag */
  29. {
  30. tedge1[X] = w->ew_res;
  31. tedge1[Y] = -w->ns_res;
  32. tedge1[Z] = sz * (bottom[col + 1] - top[col]);
  33. /* upper */
  34. tedge2[X] = 0.0;
  35. tedge2[Y] = w->ns_res;
  36. tedge2[Z] = sz * (top[col + 1] - bottom[col + 1]);
  37. v3cross(tedge1, tedge2, crossp);
  38. v3mag(crossp, &mag);
  39. guess1 = .5 * mag;
  40. /* lower */
  41. tedge2[X] = -w->ew_res;
  42. tedge2[Y] = 0.0;
  43. tedge2[Z] = sz * (bottom[col] - bottom[col + 1]);
  44. v3cross(tedge1, tedge2, crossp);
  45. v3mag(crossp, &mag);
  46. guess1 += .5 * mag;
  47. }
  48. /* guess2 --- ll to ur diag */
  49. {
  50. tedge1[X] = w->ew_res;
  51. tedge1[Y] = w->ns_res;
  52. tedge1[Z] = sz * (top[col + 1] - bottom[col]);
  53. /* upper */
  54. tedge2[X] = -w->ew_res;
  55. tedge2[Y] = 0.0;
  56. tedge2[Z] = sz * (top[col + 1] - top[col + 1]);
  57. v3cross(tedge1, tedge2, crossp);
  58. v3mag(crossp, &mag);
  59. guess2 = .5 * mag;
  60. /* lower */
  61. tedge2[X] = 0.0;
  62. tedge2[Y] = -w->ns_res;
  63. tedge2[Z] = sz * (bottom[col + 1] - top[col + 1]);
  64. v3cross(tedge1, tedge2, crossp);
  65. v3mag(crossp, &mag);
  66. guess2 += .5 * mag;
  67. }
  68. *low += (guess1 < guess2) ? guess1 : guess2;
  69. *high += (guess1 < guess2) ? guess2 : guess1;
  70. } /* ea col */
  71. }
  72. /* calculate the running area of null data cells */
  73. void add_null_area(DCELL * rast, struct Cell_head *region, double *area)
  74. {
  75. int col;
  76. for (col = 0; col < region->cols; col++) {
  77. if (Rast_is_d_null_value(&(rast[col]))) {
  78. *area += region->ew_res * region->ns_res;
  79. }
  80. }
  81. }
  82. /* return the cross product v3 = v1 cross v2 */
  83. void v3cross(double v1[3], double v2[3], double v3[3])
  84. {
  85. v3[X] = (v1[Y] * v2[Z]) - (v1[Z] * v2[Y]);
  86. v3[Y] = (v1[Z] * v2[X]) - (v1[X] * v2[Z]);
  87. v3[Z] = (v1[X] * v2[Y]) - (v1[Y] * v2[X]);
  88. }
  89. /* magnitude of vector */
  90. void v3mag(double v1[3], double *mag)
  91. {
  92. *mag = sqrt(v1[X] * v1[X] + v1[Y] * v1[Y] + v1[Z] * v1[Z]);
  93. }
  94. double conv_value(double value, int units)
  95. {
  96. if (units == U_UNDEFINED)
  97. return value;
  98. return value * G_meters_to_units_factor_sq(units);
  99. }