pattern.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #include "local_proto.h"
  2. /*directions
  3. * 3|2|1
  4. * 4|0|8
  5. * 5|6|7 */
  6. static int nextr[8] = { -1, -1, -1, 0, 1, 1, 1, 0 };
  7. static int nextc[8] = { 1, 0, -1, -1, -1, 0, 1, 1 };
  8. int calc_pattern(PATTERN * pattern, int row, int cur_row, int col)
  9. {
  10. /* calculate parameters of geomorphons and store it in the struct pattern */
  11. int i, j, pattern_size = 0;
  12. double zenith_angle, nadir_angle, angle;
  13. double nadir_threshold, zenith_threshold;
  14. double zenith_height, nadir_height, zenith_distance, nadir_distance;
  15. double cur_northing, cur_easting, target_northing, target_easting;
  16. double cur_distance;
  17. double center_height, height;
  18. /* use distance calculation */
  19. cur_northing = Rast_row_to_northing(row + 0.5, &window);
  20. cur_easting = Rast_col_to_easting(col + 0.5, &window);
  21. center_height = elevation.elev[cur_row][col];
  22. pattern->num_positives = 0;
  23. pattern->num_negatives = 0;
  24. pattern->positives = 0;
  25. pattern->negatives = 0;
  26. for (i = 0; i < 8; ++i) {
  27. /* reset patterns */
  28. pattern->pattern[i] = 0;
  29. pattern->elevation[i] = 0.;
  30. pattern->distance[i] = 0.;
  31. j = skip_cells + 1;
  32. zenith_angle = -(PI2);
  33. nadir_angle = PI2;
  34. if (cur_row + j * nextr[i] < 0 ||
  35. cur_row + j * nextr[i] > row_buffer_size - 1 ||
  36. col + j * nextc[i] < 0 || col + j * nextc[i] > ncols - 1)
  37. continue; /* border: current cell is on the end of DEM */
  38. if (Rast_is_f_null_value
  39. (&elevation.elev[cur_row + nextr[i]][col + nextc[i]]))
  40. continue; /* border: next value is null, line-of-sight does not exists */
  41. pattern_size++; /* line-of-sight exists, continue calculate visibility */
  42. target_northing =
  43. Rast_row_to_northing(row + j * nextr[i] + 0.5, &window);
  44. target_easting =
  45. Rast_col_to_easting(col + j * nextc[i] + 0.5, &window);
  46. cur_distance =
  47. G_distance(cur_easting, cur_northing, target_easting,
  48. target_northing);
  49. while (cur_distance < search_distance) {
  50. if (cur_row + j * nextr[i] < 0 ||
  51. cur_row + j * nextr[i] > row_buffer_size - 1 ||
  52. col + j * nextc[i] < 0 || col + j * nextc[i] > ncols - 1)
  53. break; /* reached end of DEM (cols) or buffer (rows) */
  54. height =
  55. elevation.elev[cur_row + j * nextr[i]][col + j * nextc[i]] -
  56. center_height;
  57. angle = atan2(height, cur_distance);
  58. if (angle > zenith_angle) {
  59. zenith_angle = angle;
  60. zenith_height = height;
  61. zenith_distance = cur_distance;
  62. }
  63. if (angle < nadir_angle) {
  64. nadir_angle = angle;
  65. nadir_height = height;
  66. nadir_distance = cur_distance;
  67. }
  68. j += cell_step;
  69. /* j++; */ /* go to next cell */
  70. target_northing =
  71. Rast_row_to_northing(row + j * nextr[i] + 0.5, &window);
  72. target_easting =
  73. Rast_col_to_easting(col + j * nextc[i] + 0.5, &window);
  74. cur_distance =
  75. G_distance(cur_easting, cur_northing, target_easting,
  76. target_northing);
  77. } /* end line of sight */
  78. /* original paper version */
  79. /* zenith_angle=PI2-zenith_angle;
  80. nadir_angle=PI2+nadir_angle;
  81. if(fabs(zenith_angle-nadir_angle) > flat_threshold) {
  82. if((nadir_angle-zenith_angle) > 0) {
  83. patterns->pattern[i]=1;
  84. patterns->elevation[i]=nadir_height;
  85. patterns->distance[i]=nadir_distance;
  86. patterns->num_positives++;
  87. } else {
  88. patterns->pattern[i]=-1;
  89. patterns->elevation[i]=zenith_height;
  90. patterns->distance[i]=zenith_distance;
  91. patterns->num_negatives++;
  92. }
  93. } else {
  94. patterns->distance[i]=search_distance;
  95. }
  96. */
  97. /* this is used to lower flat threshold if distance exceed flat_distance parameter */
  98. zenith_threshold = (flat_distance > 0 &&
  99. flat_distance <
  100. zenith_distance) ? atan2(flat_threshold_height,
  101. zenith_distance) :
  102. flat_threshold;
  103. nadir_threshold = (flat_distance > 0 &&
  104. flat_distance <
  105. nadir_distance) ? atan2(flat_threshold_height,
  106. nadir_distance) :
  107. flat_threshold;
  108. if (zenith_angle > zenith_threshold)
  109. pattern->positives += i;
  110. if (nadir_angle < -nadir_threshold)
  111. pattern->negatives += i;
  112. if (fabs(zenith_angle) > zenith_threshold ||
  113. fabs(nadir_angle) > nadir_threshold) {
  114. if (fabs(nadir_angle) < fabs(zenith_angle)) {
  115. pattern->pattern[i] = 1;
  116. pattern->elevation[i] = zenith_height; /* ZMIANA! */
  117. pattern->distance[i] = zenith_distance;
  118. pattern->num_positives++;
  119. }
  120. if (fabs(nadir_angle) > fabs(zenith_angle)) {
  121. pattern->pattern[i] = -1;
  122. pattern->elevation[i] = nadir_height; /* ZMIANA! */
  123. pattern->distance[i] = nadir_distance;
  124. pattern->num_negatives++;
  125. }
  126. }
  127. else {
  128. pattern->distance[i] = search_distance;
  129. }
  130. } /* end for */
  131. return pattern_size;
  132. }