ConvexHull.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include "growing.h"
  6. double **P, **cvxHull, **punti_bordo;
  7. /*----------------------------------------------------------------------------------------------------*/
  8. void regGrow8(struct Cell_head Elaboration, struct element_grow **mat,
  9. double **punti, int *lung, int r, int c, int v, double Th_j,
  10. int maxP)
  11. {
  12. extern int count_obj;
  13. mat[r][c].clas = v;
  14. mat[r][c].obj = count_obj;
  15. punti[*lung][0] = c;
  16. punti[*lung][1] = r;
  17. punti[*lung][2] = mat[r][c].interp;
  18. assert((*lung)++ < maxP - 1); /* Condition to finish regGrow8 */
  19. if (r - 1 >= 0) {
  20. if ((mat[r - 1][c].clas > Th_j) && (mat[r - 1][c].clas < v) &&
  21. (mat[r - 1][c].fi != 0))
  22. regGrow8(Elaboration, mat, punti, lung, r - 1, c, v, Th_j, maxP);
  23. }
  24. if (c - 1 >= 0) {
  25. if ((mat[r][c - 1].clas > Th_j) && (mat[r][c - 1].clas < v) &&
  26. (mat[r][c - 1].fi != 0))
  27. regGrow8(Elaboration, mat, punti, lung, r, c - 1, v, Th_j, maxP);
  28. }
  29. if (c + 1 < Elaboration.cols) {
  30. if ((mat[r][c + 1].clas > Th_j) && (mat[r][c + 1].clas < v) &&
  31. (mat[r][c + 1].fi != 0))
  32. regGrow8(Elaboration, mat, punti, lung, r, c + 1, v, Th_j, maxP);
  33. }
  34. if (r + 1 < Elaboration.rows) {
  35. if ((mat[r + 1][c].clas > Th_j) && (mat[r + 1][c].clas < v) &&
  36. (mat[r + 1][c].fi != 0))
  37. regGrow8(Elaboration, mat, punti, lung, r + 1, c, v, Th_j, maxP);
  38. }
  39. if ((r - 1 >= 0) && (c - 1 >= 0)) {
  40. if ((mat[r - 1][c - 1].clas > Th_j) && (mat[r - 1][c - 1].clas < v) &&
  41. (mat[r - 1][c - 1].fi != 0))
  42. regGrow8(Elaboration, mat, punti, lung, r - 1, c - 1, v, Th_j,
  43. maxP);
  44. }
  45. if ((r - 1 >= 0) && (c + 1 < Elaboration.cols)) {
  46. if ((mat[r - 1][c + 1].clas > Th_j) && (mat[r - 1][c + 1].clas < v) &&
  47. (mat[r - 1][c + 1].fi != 0))
  48. regGrow8(Elaboration, mat, punti, lung, r - 1, c + 1, v, Th_j,
  49. maxP);
  50. }
  51. if ((r + 1 < Elaboration.rows) && (c - 1 >= 0)) {
  52. if ((mat[r + 1][c - 1].clas > Th_j) && (mat[r + 1][c - 1].clas < v) &&
  53. (mat[r + 1][c - 1].fi != 0))
  54. regGrow8(Elaboration, mat, punti, lung, r + 1, c - 1, v, Th_j,
  55. maxP);
  56. }
  57. if ((r + 1 < Elaboration.rows) && (c + 1 < Elaboration.cols)) {
  58. if ((mat[r + 1][c + 1].clas > Th_j) && (mat[r + 1][c + 1].clas < v) &&
  59. (mat[r + 1][c + 1].fi != 0))
  60. regGrow8(Elaboration, mat, punti, lung, r + 1, c + 1, v, Th_j,
  61. maxP);
  62. }
  63. }
  64. int ccw(double **P, int i, int j, int k)
  65. /* true if points i, j, k counterclockwise */
  66. {
  67. double a, b, c, d;
  68. /* It compares coord differences */
  69. a = P[i][0] - P[j][0];
  70. b = P[i][1] - P[j][1];
  71. c = P[k][0] - P[j][0];
  72. d = P[k][1] - P[j][1];
  73. return a * d - b * c <= 0;
  74. }
  75. int cmpl(const void *a, const void *b)
  76. {
  77. double v;
  78. CMPM(0, a, b);
  79. CMPM(1, b, a);
  80. return 0;
  81. }
  82. int cmph(const void *a, const void *b)
  83. {
  84. return cmpl(b, a);
  85. }
  86. int make_chain(double **V, int n, int (*cmp) (const void *, const void *))
  87. {
  88. int i, j, s = 1;
  89. double *t;
  90. qsort(V, (size_t) n, sizeof(double *), cmp); /* It sorts the V's index */
  91. /* */
  92. for (i = 2; i < n; i++) {
  93. for (j = s; j >= 1 && ccw(V, i, j, j - 1); j--) ;
  94. s = j + 1;
  95. t = V[s];
  96. V[s] = V[i];
  97. V[i] = t;
  98. }
  99. return s;
  100. }
  101. int ch2d(double **P, int n)
  102. {
  103. int u = make_chain(P, n, cmpl); /* make lower hull */
  104. if (!n)
  105. return 0;
  106. P[n] = P[0];
  107. return u + make_chain(P + u, n - u + 1, cmph); /* make upper hull */
  108. }
  109. void print_hull(double **P, double **pti, int m, double **h)
  110. {
  111. int i;
  112. for (i = 0; i < m; i++) {
  113. h[i][0] = pti[(P[i] - pti[0]) / 2][0];
  114. h[i][1] = pti[(P[i] - pti[0]) / 2][1];
  115. h[i][2] = pti[(P[i] - pti[0]) / 2][2];
  116. }
  117. }
  118. int checkHull(int cR, int cC, double **oldHull, int lungOld)
  119. {
  120. double **newP;
  121. double **newPoint;
  122. int count, lungHullNew;
  123. newP = Pvector(0, lungOld + 1);
  124. newPoint = G_alloc_matrix(lungOld + 1, 2);
  125. for (count = 0; count < lungOld; count++) {
  126. newPoint[count][0] = oldHull[count][0];
  127. newPoint[count][1] = oldHull[count][1];
  128. newP[count] = newPoint[count];
  129. }
  130. newPoint[lungOld][0] = cC;
  131. newPoint[lungOld][1] = cR;
  132. newP[lungOld] = newPoint[lungOld];
  133. lungHullNew = ch2d(newP, lungOld + 1);
  134. if (lungOld != lungHullNew) {
  135. G_free_matrix(newPoint);
  136. free_Pvector(newP, 0, lungOld + 1);
  137. return 0;
  138. }
  139. else {
  140. for (count = 0; count < lungOld; count++) {
  141. if ((oldHull[count][0] != newP[count][0]) ||
  142. (oldHull[count][1] != newP[count][1])) {
  143. G_free_matrix(newPoint);
  144. free_Pvector(newP, 0, lungOld + 1);
  145. return 0;
  146. }
  147. }
  148. }
  149. G_free_matrix(newPoint);
  150. free_Pvector(newP, 0, lungOld + 1);
  151. return 1;
  152. }
  153. /*---------------------------------------------------------------------------------------------------*/
  154. double pianOriz(double **punti, int obsNum, double *minNS, double *minEW,
  155. double *maxNS, double *maxEW, struct element_grow **mat,
  156. int CBordo)
  157. {
  158. int c1;
  159. double minBordo, medioBordo; /*, minBordo1; */
  160. /*Calcola coordinate min e max della zona e media delle righe e delle colonne */
  161. *minNS = punti[0][1];
  162. *maxNS = punti[0][1];
  163. *minEW = punti[0][0];
  164. *maxEW = punti[0][0];
  165. medioBordo = 0;
  166. minBordo = punti[0][2];
  167. /*minBordo1 = punti[0][2]; */
  168. for (c1 = 0; c1 < obsNum; c1++) {
  169. if (punti[c1][0] > *maxEW)
  170. *maxEW = punti[c1][0];
  171. if (punti[c1][0] < *minEW)
  172. *minEW = punti[c1][0];
  173. if (punti[c1][1] > *maxNS)
  174. *maxNS = punti[c1][1];
  175. if (punti[c1][1] < *minNS)
  176. *minNS = punti[c1][1];
  177. /*
  178. if ((punti[c1][2] < minBordo1) && (mat[(int)(punti[c1][1])][(int)(punti[c1][0])].clas >= 1)
  179. && (mat[(int)(punti[c1][1])][(int)(punti[c1][0])].clas < CBordo)) {
  180. minBordo1 = punti[c1][2];
  181. }
  182. */
  183. if (punti[c1][2] < minBordo)
  184. minBordo = punti[c1][2];
  185. medioBordo += punti[c1][2];
  186. }
  187. medioBordo /= obsNum;
  188. return medioBordo;
  189. }
  190. /*----------------------------------------------------------------------------------------------*/
  191. double **Pvector(long nl, long nh)
  192. {
  193. double **v;
  194. v = (double **)calloc((size_t) (nh - nl + 1 + NR_END), sizeof(double *));
  195. if (!v)
  196. nrerror("allocation failure in dvector()");
  197. return v - nl + NR_END;
  198. }
  199. struct element_grow **P_alloc_element(int rows, int cols)
  200. {
  201. struct element_grow **m;
  202. int i;
  203. m = (struct element_grow **)G_calloc((rows + 1),
  204. sizeof(struct element_grow *));
  205. m[0] =
  206. (struct element_grow *)G_calloc(rows * cols,
  207. sizeof(struct element_grow));
  208. for (i = 1; i <= rows; i++)
  209. m[i] = m[i - 1] + cols;
  210. return m;
  211. }
  212. void nrerror(char error_text[])
  213. /* standard error handler */
  214. {
  215. G_debug(1, "run-time error...");
  216. G_debug(1, "%s", error_text);
  217. G_fatal_error(_("...now exiting to system..."));
  218. exit(EXIT_FAILURE);
  219. }
  220. struct element_grow **structMatrix(long nrl, long nrh, long ncl, long nch)
  221. {
  222. long i, nrow = nrh - nrl + 1, ncol = nch - ncl + 1;
  223. struct element_grow **m;
  224. /* allocate pointers to rows */
  225. m = (struct element_grow **)calloc((size_t) (nrow + NR_END),
  226. sizeof(struct element_grow *));
  227. if (!m)
  228. nrerror("allocation failure 1 in matrix()");
  229. m += NR_END;
  230. m -= nrl;
  231. /* allocate rows and set pointers to them */
  232. m[nrl] =
  233. (struct element_grow *)calloc((size_t) (nrow * ncol + NR_END),
  234. sizeof(struct element_grow));
  235. if (!m[nrl])
  236. nrerror("allocation failure 2 in matrix()");
  237. m[nrl] += NR_END;
  238. m[nrl] -= ncl;
  239. for (i = nrl + 1; i <= nrh; i++)
  240. m[i] = m[i - 1] + ncol;
  241. /* return pointer to array of pointers to rows */
  242. return m;
  243. }
  244. void free_Pvector(double **v, long nl, long nh)
  245. {
  246. free((FREE_ARG) (v + nl - NR_END));
  247. }
  248. void free_structmatrix(struct element_grow **m, long nrl, long nrh, long ncl,
  249. long nch)
  250. {
  251. free((FREE_ARG) (m[nrl] + ncl - NR_END));
  252. free((FREE_ARG) (m + nrl - NR_END));
  253. }