gradient.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*!
  2. \file gradient.c
  3. \brief Gradient computation
  4. (C) 2014 by the GRASS Development Team
  5. This program is free software under the GNU General Public
  6. License (>=v2). Read the file COPYING that comes with GRASS
  7. for details.
  8. \author Anna Petrasova
  9. */
  10. /*!
  11. \brief Gradient computation
  12. Gradient computation (second order approximation)
  13. using central differencing scheme (plus forward and backward
  14. difference of second order approximation). When one or more of the cells,
  15. from which the gradient for a particular cell is computed, is null,
  16. gradient for that particular cell is set to 0.
  17. \param array pointer to RASTER3D_Array with input values
  18. \param step array of x, y, z steps for gradient (resolution values)
  19. \param[out] grad_x pointer to RASTER3D_Array_double with gradient in x direction
  20. \param[out] grad_y pointer to RASTER3D_Array_double with gradient in y direction
  21. \param[out] grad_z pointer to RASTER3D_Array_double with gradient in z direction
  22. */
  23. #include <grass/raster3d.h>
  24. void Rast3d_gradient_double(RASTER3D_Array_double *array, double *step,
  25. RASTER3D_Array_double *grad_x,
  26. RASTER3D_Array_double *grad_y,
  27. RASTER3D_Array_double *grad_z)
  28. {
  29. int col, row, depth;
  30. double val0, val1, val2;
  31. for (depth = 0; depth < array->sz; depth++) {
  32. for (row = 0; row < array->sy; row++) {
  33. /* row start */
  34. val0 = RASTER3D_ARRAY_ACCESS(array, 0, row, depth);
  35. val1 = RASTER3D_ARRAY_ACCESS(array, 1, row, depth);
  36. val2 = RASTER3D_ARRAY_ACCESS(array, 2, row, depth);
  37. if (Rast_is_d_null_value(&val0))
  38. Rast_set_null_value(&RASTER3D_ARRAY_ACCESS(grad_x, 0, row, depth),
  39. 1, DCELL_TYPE);
  40. else if (Rast_is_d_null_value(&val1) || Rast_is_d_null_value(&val2))
  41. RASTER3D_ARRAY_ACCESS(grad_x, 0, row, depth) = 0;
  42. else
  43. RASTER3D_ARRAY_ACCESS(grad_x, 0, row, depth) =
  44. (-3 * val0 + 4 * val1 - val2) / (2 * step[0]);
  45. /* row end */
  46. val0 = RASTER3D_ARRAY_ACCESS(array, array->sx - 3, row, depth);
  47. val1 = RASTER3D_ARRAY_ACCESS(array, array->sx - 2, row, depth);
  48. val2 = RASTER3D_ARRAY_ACCESS(array, array->sx - 1, row, depth);
  49. if (Rast_is_d_null_value(&val2))
  50. Rast_set_null_value(
  51. &RASTER3D_ARRAY_ACCESS(grad_x, array->sx - 1, row, depth),
  52. 1, DCELL_TYPE);
  53. else if (Rast_is_d_null_value(&val0) || Rast_is_d_null_value(&val1))
  54. RASTER3D_ARRAY_ACCESS(grad_x, array->sx - 1, row, depth) = 0;
  55. else
  56. RASTER3D_ARRAY_ACCESS(grad_x, array->sx - 1, row, depth) =
  57. (3 * val2 - 4 * val1 + val0) / (2 * step[0]);
  58. /* row */
  59. for (col = 1; col < array->sx - 1; col++) {
  60. val0 = RASTER3D_ARRAY_ACCESS(array, col - 1, row, depth);
  61. val1 = RASTER3D_ARRAY_ACCESS(array, col, row, depth);
  62. val2 = RASTER3D_ARRAY_ACCESS(array, col + 1, row, depth);
  63. if (Rast_is_d_null_value(&val1))
  64. Rast_set_null_value(
  65. &RASTER3D_ARRAY_ACCESS(grad_x, col, row, depth),
  66. 1, DCELL_TYPE);
  67. else if (Rast_is_d_null_value(&val0) || Rast_is_d_null_value(&val2))
  68. RASTER3D_ARRAY_ACCESS(grad_x, col, row, depth) = 0;
  69. else
  70. RASTER3D_ARRAY_ACCESS(grad_x, col, row, depth) =
  71. (val2 - val0) / (2 * step[0]);
  72. }
  73. }
  74. }
  75. for (depth = 0; depth < array->sz; depth++) {
  76. for (col = 0; col < array->sx; col++) {
  77. /* col start */
  78. val0 = RASTER3D_ARRAY_ACCESS(array, col, 0, depth);
  79. val1 = RASTER3D_ARRAY_ACCESS(array, col, 1, depth);
  80. val2 = RASTER3D_ARRAY_ACCESS(array, col, 2, depth);
  81. if (Rast_is_d_null_value(&val0))
  82. Rast_set_null_value(&RASTER3D_ARRAY_ACCESS(grad_y, col, 0, depth),
  83. 1, DCELL_TYPE);
  84. else if (Rast_is_d_null_value(&val1) || Rast_is_d_null_value(&val2))
  85. RASTER3D_ARRAY_ACCESS(grad_y, col, 0, depth) = 0;
  86. else
  87. RASTER3D_ARRAY_ACCESS(grad_y, col, 0, depth) =
  88. -(-3 * val0 + 4 * val1 - val2) / (2 * step[1]);
  89. /* col end */
  90. val0 = RASTER3D_ARRAY_ACCESS(array, col, array->sy - 3, depth);
  91. val1 = RASTER3D_ARRAY_ACCESS(array, col, array->sy - 2, depth);
  92. val2 = RASTER3D_ARRAY_ACCESS(array, col, array->sy - 1, depth);
  93. if (Rast_is_d_null_value(&val2))
  94. Rast_set_null_value(
  95. &RASTER3D_ARRAY_ACCESS(grad_y, col, array->sy - 1, depth),
  96. 1, DCELL_TYPE);
  97. else if (Rast_is_d_null_value(&val0) || Rast_is_d_null_value(&val1))
  98. RASTER3D_ARRAY_ACCESS(grad_y, col, array->sy - 1, depth) = 0;
  99. else
  100. RASTER3D_ARRAY_ACCESS(grad_y, col, array->sy - 1, depth) =
  101. -(3 * val2 - 4 * val1 + val0) / (2 * step[1]);
  102. /* col */
  103. for (row = 1; row < array->sy - 1; row++) {
  104. val0 = RASTER3D_ARRAY_ACCESS(array, col, row - 1, depth);
  105. val1 = RASTER3D_ARRAY_ACCESS(array, col, row, depth);
  106. val2 = RASTER3D_ARRAY_ACCESS(array, col, row + 1, depth);
  107. if (Rast_is_d_null_value(&val1))
  108. Rast_set_null_value(
  109. &RASTER3D_ARRAY_ACCESS(grad_y, col, row, depth),
  110. 1, DCELL_TYPE);
  111. else if (Rast_is_d_null_value(&val0) || Rast_is_d_null_value(&val2))
  112. RASTER3D_ARRAY_ACCESS(grad_y, col, row, depth) = 0;
  113. else
  114. RASTER3D_ARRAY_ACCESS(grad_y, col, row, depth) =
  115. -(val2 - val0) / (2 * step[1]);
  116. }
  117. }
  118. }
  119. for (row = 0; row < array->sy; row++) {
  120. for (col = 0; col < array->sx; col++) {
  121. /* vertical col start */
  122. val0 = RASTER3D_ARRAY_ACCESS(array, col, row, 0);
  123. val1 = RASTER3D_ARRAY_ACCESS(array, col, row, 1);
  124. val2 = RASTER3D_ARRAY_ACCESS(array, col, row, 2);
  125. if (Rast_is_d_null_value(&val0))
  126. Rast_set_null_value(&RASTER3D_ARRAY_ACCESS(grad_z, col, row, 0),
  127. 1, DCELL_TYPE);
  128. else if (Rast_is_d_null_value(&val1) || Rast_is_d_null_value(&val2))
  129. RASTER3D_ARRAY_ACCESS(grad_z, col, row, 0) = 0;
  130. else
  131. RASTER3D_ARRAY_ACCESS(grad_z, col, row, 0) =
  132. (-3 * val0 + 4 * val1 - val2) / (2 * step[2]);
  133. /* vertical col end */
  134. val0 = RASTER3D_ARRAY_ACCESS(array, col, row, array->sz - 3);
  135. val1 = RASTER3D_ARRAY_ACCESS(array, col, row, array->sz - 2);
  136. val2 = RASTER3D_ARRAY_ACCESS(array, col, row, array->sz - 1);
  137. if (Rast_is_d_null_value(&val2))
  138. Rast_set_null_value(
  139. &RASTER3D_ARRAY_ACCESS(grad_z, col, row, array->sz - 1),
  140. 1, DCELL_TYPE);
  141. else if (Rast_is_d_null_value(&val0) || Rast_is_d_null_value(&val1))
  142. RASTER3D_ARRAY_ACCESS(grad_z, col, row, array->sz - 1) = 0;
  143. else
  144. RASTER3D_ARRAY_ACCESS(grad_z, col, row, array->sz - 1) =
  145. (3 * val2 - 4 * val1 + val0) / (2 * step[2]);
  146. /* vertical col */
  147. for (depth = 1; depth < array->sz - 1; depth++) {
  148. val0 = RASTER3D_ARRAY_ACCESS(array, col, row, depth - 1);
  149. val1 = RASTER3D_ARRAY_ACCESS(array, col, row, depth);
  150. val2 = RASTER3D_ARRAY_ACCESS(array, col, row, depth + 1);
  151. if (Rast_is_d_null_value(&val1))
  152. Rast_set_null_value(
  153. &RASTER3D_ARRAY_ACCESS(grad_z, col, row, depth),
  154. 1, DCELL_TYPE);
  155. else if (Rast_is_d_null_value(&val0) || Rast_is_d_null_value(&val2))
  156. RASTER3D_ARRAY_ACCESS(grad_z, col, row, depth) = 0;
  157. else
  158. RASTER3D_ARRAY_ACCESS(grad_z, col, row, depth) =
  159. (val2 - val0) / (2 * step[2]);
  160. }
  161. }
  162. }
  163. }