dataquad.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. /*-
  2. * Written by H. Mitasova, I. Kosinovsky, D. Gerdes Fall 1993
  3. * University of Illinois
  4. * US Army Construction Engineering Research Lab
  5. * Copyright 1993, H. Mitasova (University of Illinois),
  6. * I. Kosinovsky, (USA-CERL), and D.Gerdes (USA-CERL)
  7. *
  8. * Modified by H.Mitasova November 1996 to include variable smoothing
  9. *
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <grass/dataquad.h>
  14. /* sm added to point structure */
  15. struct triple *quad_point_new(double x, double y, double z, double sm)
  16. /* Initializes POINT structure with given arguments */
  17. {
  18. struct triple *point;
  19. if (!(point = (struct triple *)malloc(sizeof(struct triple)))) {
  20. return NULL;
  21. }
  22. point->x = x;
  23. point->y = y;
  24. point->z = z;
  25. point->sm = sm;
  26. return point;
  27. }
  28. struct quaddata *quad_data_new(double x_or, double y_or, double xmax,
  29. double ymax, int rows, int cols, int n_points,
  30. int kmax)
  31. /* Initializes QUADDATA structure with given arguments */
  32. {
  33. struct quaddata *data;
  34. int i;
  35. if (!(data = (struct quaddata *)malloc(sizeof(struct quaddata)))) {
  36. return NULL;
  37. }
  38. data->x_orig = x_or;
  39. data->y_orig = y_or;
  40. data->xmax = xmax;
  41. data->ymax = ymax;
  42. data->n_rows = rows;
  43. data->n_cols = cols;
  44. data->n_points = n_points;
  45. data->points =
  46. (struct triple *)malloc(sizeof(struct triple) * (kmax + 1));
  47. if (!data->points)
  48. return NULL;
  49. for (i = 0; i <= kmax; i++) {
  50. data->points[i].x = 0.;
  51. data->points[i].y = 0.;
  52. data->points[i].z = 0.;
  53. data->points[i].sm = 0.;
  54. }
  55. return data;
  56. }
  57. int quad_compare(struct triple *point, struct quaddata *data)
  58. /* returns the quadrant the point should be inserted in */
  59. /* called by divide() */
  60. {
  61. int cond1, cond2, cond3, cond4, rows, cols;
  62. double ew_res, ns_res;
  63. ew_res = (data->xmax - data->x_orig) / data->n_cols;
  64. ns_res = (data->ymax - data->y_orig) / data->n_rows;
  65. if (data == NULL)
  66. return -1;
  67. if (data->n_rows % 2 == 0) {
  68. rows = data->n_rows / 2;
  69. }
  70. else {
  71. rows = (int)(data->n_rows / 2) + 1;
  72. }
  73. if (data->n_cols % 2 == 0) {
  74. cols = data->n_cols / 2;
  75. }
  76. else {
  77. cols = (int)(data->n_cols / 2) + 1;
  78. }
  79. cond1 = (point->x >= data->x_orig);
  80. cond2 = (point->x >= data->x_orig + ew_res * cols);
  81. cond3 = (point->y >= data->y_orig);
  82. cond4 = (point->y >= data->y_orig + ns_res * rows);
  83. if (cond1 && cond3) {
  84. if (cond2 && cond4)
  85. return NE;
  86. if (cond2)
  87. return SE;
  88. if (cond4)
  89. return NW;
  90. return SW;
  91. }
  92. else
  93. return 0;
  94. }
  95. int quad_add_data(struct triple *point, struct quaddata *data, double dmin)
  96. /* Adds POINT to a given DATA . Called by tree function insert_quad() */
  97. /* and by data function quad_divide_data() */
  98. {
  99. int n, i, cond;
  100. double xx, yy, r;
  101. cond = 1;
  102. if (data == NULL) {
  103. fprintf(stderr, "add_data: data is NULL \n");
  104. return -5;
  105. }
  106. for (i = 0; i < data->n_points; i++) {
  107. xx = data->points[i].x - point->x;
  108. yy = data->points[i].y - point->y;
  109. r = xx * xx + yy * yy;
  110. if (r <= dmin) {
  111. cond = 0;
  112. break;
  113. }
  114. }
  115. if (cond) {
  116. n = (data->n_points)++;
  117. data->points[n].x = point->x;
  118. data->points[n].y = point->y;
  119. data->points[n].z = point->z;
  120. data->points[n].sm = point->sm;
  121. }
  122. return cond;
  123. }
  124. int quad_intersect(struct quaddata *data_inter, struct quaddata *data)
  125. /* Checks if region defined by DATA intersects the region defined
  126. by data_inter. Called by tree function MT_region_data() */
  127. {
  128. double xmin, xmax, ymin, ymax;
  129. xmin = data_inter->x_orig;
  130. xmax = data_inter->xmax;
  131. ymin = data_inter->y_orig;
  132. ymax = data_inter->ymax;
  133. if (((data->x_orig >= xmin) && (data->x_orig <= xmax)
  134. && (((data->y_orig >= ymin) && (data->y_orig <= ymax))
  135. || ((ymin >= data->y_orig) && (ymin <= data->ymax))
  136. )
  137. )
  138. || ((xmin >= data->x_orig) && (xmin <= data->xmax)
  139. && (((ymin >= data->y_orig) && (ymin <= data->ymax))
  140. || ((data->y_orig >= ymin) && (data->y_orig <= ymax))
  141. )
  142. )
  143. ) {
  144. return 1;
  145. }
  146. else
  147. return 0;
  148. }
  149. int quad_division_check(struct quaddata *data, int kmax)
  150. /* Checks if DATA needs to be divided. If data->points is empty,
  151. returns -1; if its not empty but there aren't enough points
  152. in DATA for division returns 0. Othervise (if its not empty and
  153. there are too many points) returns 1. Called by MT_insert() */
  154. {
  155. if (data->points == NULL)
  156. return -1;
  157. if (data->n_points < kmax)
  158. return 0;
  159. else
  160. return 1;
  161. }
  162. struct quaddata **quad_divide_data(struct quaddata *data, int kmax,
  163. double dmin)
  164. /* Divides DATA into 4 new datas reinserting data->points in
  165. them by calling data function quad_compare() to detrmine
  166. were to insert. Called by MT_divide(). Returns array of 4 new datas */
  167. {
  168. struct quaddata **datas;
  169. int cols1, cols2, rows1, rows2, i; /*j1, j2, jmin = 0; */
  170. double dx, dy; /* x2, y2, dist, mindist; */
  171. double xr, xm, xl, yr, ym, yl; /* left, right, middle coord */
  172. double ew_res, ns_res;
  173. ew_res = (data->xmax - data->x_orig) / data->n_cols;
  174. ns_res = (data->ymax - data->y_orig) / data->n_rows;
  175. if ((data->n_cols <= 1) || (data->n_rows <= 1)) {
  176. fprintf(stderr,
  177. "Points are too concentrated -- please increase DMIN\n");
  178. exit(0);
  179. }
  180. if (data->n_cols % 2 == 0) {
  181. cols1 = data->n_cols / 2;
  182. cols2 = cols1;
  183. }
  184. else {
  185. cols2 = (int)(data->n_cols / 2);
  186. cols1 = cols2 + 1;
  187. }
  188. if (data->n_rows % 2 == 0) {
  189. rows1 = data->n_rows / 2;
  190. rows2 = rows1;
  191. }
  192. else {
  193. rows2 = (int)(data->n_rows / 2);
  194. rows1 = rows2 + 1;
  195. }
  196. dx = cols1 * ew_res;
  197. dy = rows1 * ns_res;
  198. xl = data->x_orig;
  199. xm = xl + dx;
  200. xr = data->xmax;
  201. yl = data->y_orig;
  202. ym = yl + dy;
  203. yr = data->ymax;
  204. if (!(datas = (struct quaddata **)malloc(sizeof(struct quaddata *) * 5))) {
  205. return NULL;
  206. }
  207. datas[NE] = quad_data_new(xm, ym, xr, yr, rows2, cols2, 0, kmax);
  208. datas[SW] = quad_data_new(xl, yl, xm, ym, rows1, cols1, 0, kmax);
  209. datas[SE] = quad_data_new(xm, yl, xr, ym, rows1, cols2, 0, kmax);
  210. datas[NW] = quad_data_new(xl, ym, xm, yr, rows2, cols1, 0, kmax);
  211. for (i = 0; i < data->n_points; i++) {
  212. switch (quad_compare(data->points + i, data)) {
  213. case SW:
  214. {
  215. quad_add_data(data->points + i, datas[SW], dmin);
  216. break;
  217. }
  218. case SE:
  219. {
  220. quad_add_data(data->points + i, datas[SE], dmin);
  221. break;
  222. }
  223. case NW:
  224. {
  225. quad_add_data(data->points + i, datas[NW], dmin);
  226. break;
  227. }
  228. case NE:
  229. {
  230. quad_add_data(data->points + i, datas[NE], dmin);
  231. break;
  232. }
  233. }
  234. }
  235. data->points = NULL;
  236. return datas;
  237. }
  238. int
  239. quad_get_points(struct quaddata *data_inter, struct quaddata *data, int MAX)
  240. /* Gets such points from DATA that lie within region determined by
  241. data_inter. Called by tree function region_data(). */
  242. {
  243. int i, ind;
  244. int n = 0;
  245. int l = 0;
  246. double xmin, xmax, ymin, ymax;
  247. struct triple *point;
  248. xmin = data_inter->x_orig;
  249. xmax = data_inter->xmax;
  250. ymin = data_inter->y_orig;
  251. ymax = data_inter->ymax;
  252. for (i = 0; i < data->n_points; i++) {
  253. point = data->points + i;
  254. if (l >= MAX)
  255. return MAX + 1;
  256. if ((point->x > xmin) && (point->x < xmax)
  257. && (point->y > ymin) && (point->y < ymax)) {
  258. ind = data_inter->n_points++;
  259. data_inter->points[ind].x = point->x;
  260. data_inter->points[ind].y = point->y;
  261. data_inter->points[ind].z = point->z;
  262. data_inter->points[ind].sm = point->sm;
  263. l = l + 1;
  264. }
  265. }
  266. n = l;
  267. return (n);
  268. }