dgraph.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. #include <stdlib.h>
  2. #include <grass/Vect.h>
  3. #include <grass/gis.h>
  4. #include "dgraph.h"
  5. #include "e_intersect.h"
  6. #define LENGTH(DX, DY) (sqrt((DX*DX)+(DY*DY)))
  7. #ifndef MIN
  8. #define MIN(X,Y) ((X<Y)?X:Y)
  9. #endif
  10. #ifndef MAX
  11. #define MAX(X,Y) ((X>Y)?X:Y)
  12. #endif
  13. #define PI M_PI
  14. struct intersection_point
  15. {
  16. double x;
  17. double y;
  18. int group; /* IPs with very similar dist will be in the same group */
  19. };
  20. struct seg_intersection
  21. {
  22. int with; /* second segment */
  23. int ip; /* index of the IP */
  24. double dist; /* distance from first point of first segment to intersection point (IP) */
  25. };
  26. struct seg_intersection_list
  27. {
  28. int count;
  29. int allocated;
  30. struct seg_intersection *a;
  31. };
  32. struct seg_intersections
  33. {
  34. int ipcount;
  35. int ipallocated;
  36. struct intersection_point *ip;
  37. int ilcount;
  38. struct seg_intersection_list *il;
  39. int group_count;
  40. };
  41. struct seg_intersections *create_si_struct(int segments_count)
  42. {
  43. struct seg_intersections *si;
  44. int i;
  45. si = G_malloc(sizeof(struct seg_intersections));
  46. si->ipcount = 0;
  47. si->ipallocated = segments_count + 16;
  48. si->ip = G_malloc((si->ipallocated) * sizeof(struct intersection_point));
  49. si->ilcount = segments_count;
  50. si->il = G_malloc(segments_count * sizeof(struct seg_intersection_list));
  51. for (i = 0; i < segments_count; i++) {
  52. si->il[i].count = 0;
  53. si->il[i].allocated = 0;
  54. si->il[i].a = NULL;
  55. }
  56. return si;
  57. }
  58. void destroy_si_struct(struct seg_intersections *si)
  59. {
  60. int i;
  61. for (i = 0; i < si->ilcount; i++)
  62. G_free(si->il[i].a);
  63. G_free(si->il);
  64. G_free(si->ip);
  65. G_free(si);
  66. return;
  67. }
  68. /* internal use */
  69. void add_ipoint1(struct seg_intersection_list *il, int with, double dist,
  70. int ip)
  71. {
  72. struct seg_intersection *s;
  73. if (il->count == il->allocated) {
  74. il->allocated += 4;
  75. il->a =
  76. G_realloc(il->a,
  77. (il->allocated) * sizeof(struct seg_intersection));
  78. }
  79. s = &(il->a[il->count]);
  80. s->with = with;
  81. s->ip = ip;
  82. s->dist = dist;
  83. il->count++;
  84. return;
  85. }
  86. /* adds intersection point to the structure */
  87. void add_ipoint(struct line_pnts *Points, int first_seg, int second_seg,
  88. double x, double y, struct seg_intersections *si)
  89. {
  90. struct intersection_point *t;
  91. int ip;
  92. G_debug(4, "add_ipoint()");
  93. if (si->ipcount == si->ipallocated) {
  94. si->ipallocated += 16;
  95. si->ip =
  96. G_realloc(si->ip,
  97. (si->ipallocated) * sizeof(struct intersection_point));
  98. }
  99. ip = si->ipcount;
  100. t = &(si->ip[ip]);
  101. t->x = x;
  102. t->y = y;
  103. t->group = -1;
  104. si->ipcount++;
  105. add_ipoint1(&(si->il[first_seg]), second_seg,
  106. LENGTH((Points->x[first_seg] - x),
  107. (Points->y[first_seg] - y)), ip);
  108. if (second_seg >= 0)
  109. add_ipoint1(&(si->il[second_seg]), first_seg,
  110. LENGTH((Points->x[second_seg] - x),
  111. (Points->y[second_seg] - y)), ip);
  112. }
  113. void sort_intersection_list(struct seg_intersection_list *il)
  114. {
  115. int n, i, j, min;
  116. struct seg_intersection t;
  117. G_debug(4, "sort_intersection_list()");
  118. n = il->count;
  119. G_debug(4, " n=%d", n);
  120. for (i = 0; i < n - 1; i++) {
  121. min = i;
  122. for (j = i + 1; j < n; j++) {
  123. if (il->a[j].dist < il->a[min].dist) {
  124. min = j;
  125. }
  126. }
  127. if (min != i) {
  128. t = il->a[i];
  129. il->a[i] = il->a[min];
  130. il->a[min] = t;
  131. }
  132. }
  133. return;
  134. }
  135. static int compare(const void *a, const void *b)
  136. {
  137. struct intersection_point *aa, *bb;
  138. aa = *((struct intersection_point **)a);
  139. bb = *((struct intersection_point **)b);
  140. if (aa->x < bb->x)
  141. return -1;
  142. else if (aa->x > bb->x)
  143. return 1;
  144. else
  145. return (aa->y < bb->y) ? -1 : ((aa->y > bb->y) ? 1 : 0);
  146. }
  147. /* O(Points->n_points) time */
  148. double get_epsilon(struct line_pnts *Points)
  149. {
  150. int i, np;
  151. double min, t;
  152. double *x, *y;
  153. np = Points->n_points;
  154. x = Points->x;
  155. y = Points->y;
  156. min = MAX(fabs(x[1] - x[0]), fabs(y[1] - y[0]));
  157. for (i = 1; i <= np - 2; i++) {
  158. t = MAX(fabs(x[i + 1] - x[i]), fabs(y[i + 1] - y[i]));
  159. if ((t > 0) && (t < min)) {
  160. min = t;
  161. }
  162. }
  163. /* ??? is 0.001 ok ??? */
  164. return min * 0.000001;
  165. }
  166. /* currently O(n*n); future implementation O(nlogn) */
  167. struct seg_intersections *find_all_intersections(struct line_pnts *Points)
  168. {
  169. int i, j, np;
  170. int group, t;
  171. int looped;
  172. double EPSILON = 0.00000001;
  173. double *x, *y;
  174. double x1, y1, x2, y2;
  175. int res;
  176. /*int res2
  177. double x1_, y1_, x2_, y2_, z1_, z2_; */
  178. struct seg_intersections *si;
  179. struct seg_intersection_list *il;
  180. struct intersection_point **sorted;
  181. G_debug(3, "find_all_intersections()");
  182. np = Points->n_points;
  183. x = Points->x;
  184. y = Points->y;
  185. si = create_si_struct(np - 1);
  186. looped = ((x[0] == x[np - 1]) && (y[0] == y[np - 1]));
  187. G_debug(3, " looped=%d", looped);
  188. G_debug(3, " finding intersections...");
  189. for (i = 0; i < np - 1; i++) {
  190. for (j = i + 1; j < np - 1; j++) {
  191. G_debug(4, " checking %d-%d %d-%d", i, i + 1, j, j + 1);
  192. /*res = segment_intersection_2d_e(x[i], y[i], x[i+1], y[i+1], x[j], y[j], x[j+1], y[j+1], &x1, &y1, &x2, &y2); */
  193. res =
  194. segment_intersection_2d(x[i], y[i], x[i + 1], y[i + 1], x[j],
  195. y[j], x[j + 1], y[j + 1], &x1, &y1,
  196. &x2, &y2);
  197. /* res2 = segment_intersection_2d_e(x[i], y[i], x[i+1], y[i+1], x[j], y[j], x[j+1], y[j+1], &x1_, &y1_, &x2_, &y2_);
  198. if ((res != res2) || ((res != 0) && (x1!=x1_ || y1!=y1_)) ) {
  199. G_debug(0, "exact=%d orig=%d", res, res2);
  200. segment_intersection_2d_test(x[i], y[i], x[i+1], y[i+1], x[j], y[j], x[j+1], y[j+1], &x1, &y1, &x2, &y2);
  201. }
  202. */
  203. G_debug(4, " intersection type = %d", res);
  204. if (res == 1) {
  205. add_ipoint(Points, i, j, x1, y1, si);
  206. }
  207. else if ((res >= 2) && (res <= 5)) {
  208. add_ipoint(Points, i, j, x1, y1, si);
  209. add_ipoint(Points, i, j, x2, y2, si);
  210. }
  211. }
  212. }
  213. if (!looped) {
  214. /* these are not really intersection points */
  215. add_ipoint(Points, 0, -1, Points->x[0], Points->y[0], si);
  216. add_ipoint(Points, np - 2, -1, Points->x[np - 1], Points->y[np - 1],
  217. si);
  218. }
  219. G_debug(3, " finding intersections...done");
  220. G_debug(3, " postprocessing...");
  221. if (si->ipallocated > si->ipcount) {
  222. si->ipallocated = si->ipcount;
  223. si->ip =
  224. G_realloc(si->ip,
  225. (si->ipcount) * sizeof(struct intersection_point));
  226. }
  227. for (i = 0; i < si->ilcount; i++) {
  228. il = &(si->il[i]);
  229. if (il->allocated > il->count) {
  230. il->allocated = il->count;
  231. il->a =
  232. G_realloc(il->a,
  233. (il->count) * sizeof(struct seg_intersection));
  234. }
  235. if (il->count > 0) {
  236. sort_intersection_list(il);
  237. /* is it ok to use qsort here ? */
  238. }
  239. }
  240. /* si->ip will not be reallocated any more so we can use pointers */
  241. sorted = G_malloc((si->ipcount) * sizeof(struct intersection_point *));
  242. for (i = 0; i < si->ipcount; i++)
  243. sorted[i] = &(si->ip[i]);
  244. qsort(sorted, si->ipcount, sizeof(struct intersection_point *), compare);
  245. /* assign groups */
  246. group = 0; /* next available group number */
  247. for (i = 0; i < si->ipcount; i++) {
  248. t = group;
  249. for (j = i - 1; j >= 0; j--) {
  250. if (!FEQUAL(sorted[j]->x, sorted[i]->x, EPSILON))
  251. /* if (!almost_equal(sorted[j]->x, sorted[i]->x, 16)) */
  252. break;
  253. if (FEQUAL(sorted[j]->y, sorted[i]->y, EPSILON)) {
  254. /* if (almost_equal(sorted[j]->y, sorted[i]->y, 16)) { */
  255. t = sorted[j]->group;
  256. break;
  257. }
  258. }
  259. G_debug(4, " group=%d, ip=%d", t,
  260. (int)(sorted[i] - &(si->ip[0])));
  261. sorted[i]->group = t;
  262. if (t == group)
  263. group++;
  264. }
  265. si->group_count = group;
  266. G_debug(3, " postprocessing...done");
  267. /* output contents of si */
  268. for (i = 0; i < si->ilcount; i++) {
  269. G_debug(4, "%d-%d :", i, i + 1);
  270. for (j = 0; j < si->il[i].count; j++) {
  271. G_debug(4, " %d-%d, group=%d", si->il[i].a[j].with,
  272. si->il[i].a[j].with + 1, si->ip[si->il[i].a[j].ip].group);
  273. G_debug(4, " dist=%.18f", si->il[i].a[j].dist);
  274. G_debug(4, " x=%.18f, y=%.18f",
  275. si->ip[si->il[i].a[j].ip].x, si->ip[si->il[i].a[j].ip].y);
  276. }
  277. }
  278. return si;
  279. }
  280. /* create's graph with n vertices and allocates memory for e edges */
  281. /* trying to add more than e edges, produces fatal error */
  282. struct planar_graph *pg_create_struct(int n, int e)
  283. {
  284. struct planar_graph *pg;
  285. pg = G_malloc(sizeof(struct planar_graph));
  286. pg->vcount = n;
  287. pg->v = G_malloc(n * sizeof(struct pg_vertex));
  288. memset(pg->v, 0, n * sizeof(struct pg_vertex));
  289. pg->ecount = 0;
  290. pg->eallocated = MAX(e, 0);
  291. pg->e = NULL;
  292. pg->e = G_malloc(e * sizeof(struct pg_edge));
  293. return pg;
  294. }
  295. void pg_destroy_struct(struct planar_graph *pg)
  296. {
  297. int i;
  298. for (i = 0; i < pg->vcount; i++) {
  299. G_free(pg->v[i].edges);
  300. G_free(pg->v[i].angles);
  301. }
  302. G_free(pg->v);
  303. G_free(pg->e);
  304. G_free(pg);
  305. }
  306. /* v1 and v2 must be valid */
  307. int pg_existsedge(struct planar_graph *pg, int v1, int v2)
  308. {
  309. struct pg_vertex *v;
  310. struct pg_edge *e;
  311. int i, ecount;
  312. if (pg->v[v1].ecount <= pg->v[v2].ecount)
  313. v = &(pg->v[v1]);
  314. else
  315. v = &(pg->v[v2]);
  316. ecount = v->ecount;
  317. for (i = 0; i < ecount; i++) {
  318. e = v->edges[i];
  319. if (((e->v1 == v1) && (e->v2 == v2)) ||
  320. ((e->v1 == v2) && (e->v2 == v1)))
  321. return 1;
  322. }
  323. return 0;
  324. }
  325. /* for internal use */
  326. void pg_addedge1(struct pg_vertex *v, struct pg_edge *e)
  327. {
  328. if (v->ecount == v->eallocated) {
  329. v->eallocated += 4;
  330. v->edges =
  331. G_realloc(v->edges, (v->eallocated) * sizeof(struct pg_edge *));
  332. }
  333. v->edges[v->ecount] = e;
  334. v->ecount++;
  335. }
  336. void pg_addedge(struct planar_graph *pg, int v1, int v2)
  337. {
  338. struct pg_edge *e;
  339. G_debug(4, "pg_addedge(), v1=%d, v2=%d", v1, v2);
  340. if ((v1 == v2) || (v1 < 0) || (v1 >= pg->vcount) || (v2 < 0) ||
  341. (v2 >= pg->vcount)) {
  342. G_fatal_error(" pg_addedge(), v1 and/or v2 is invalid");
  343. return;
  344. }
  345. if (pg_existsedge(pg, v1, v2))
  346. return;
  347. if (pg->ecount == pg->eallocated) {
  348. G_fatal_error
  349. ("Trying to add more edges to the planar_graph than the initial allocation size allows");
  350. }
  351. e = &(pg->e[pg->ecount]);
  352. e->v1 = v1;
  353. e->v2 = v2;
  354. e->winding_left = 0; /* winding is undefined if the corresponding side is not visited */
  355. e->winding_right = 0;
  356. e->visited_left = 0;
  357. e->visited_right = 0;
  358. pg->ecount++;
  359. pg_addedge1(&(pg->v[v1]), e);
  360. pg_addedge1(&(pg->v[v2]), e);
  361. return;
  362. }
  363. struct planar_graph *pg_create(struct line_pnts *Points)
  364. {
  365. struct seg_intersections *si;
  366. struct planar_graph *pg;
  367. struct intersection_point *ip;
  368. struct pg_vertex *vert;
  369. struct pg_edge *edge;
  370. int i, j, t, v;
  371. G_debug(3, "pg_create()");
  372. si = find_all_intersections(Points);
  373. pg = pg_create_struct(si->group_count, 2 * (si->ipcount));
  374. /* set vertices info */
  375. for (i = 0; i < si->ipcount; i++) {
  376. ip = &(si->ip[i]);
  377. t = ip->group;
  378. pg->v[t].x = ip->x;
  379. pg->v[t].y = ip->y;
  380. }
  381. /* add all edges */
  382. for (i = 0; i < si->ilcount; i++) {
  383. v = si->ip[si->il[i].a[0].ip].group;
  384. for (j = 1; j < si->il[i].count; j++) {
  385. t = si->ip[si->il[i].a[j].ip].group;
  386. if (t != v) {
  387. pg_addedge(pg, v, t); /* edge direction is v ---> t */
  388. v = t;
  389. }
  390. }
  391. }
  392. /* precalculate angles with 0x */
  393. for (i = 0; i < pg->vcount; i++) {
  394. vert = &(pg->v[i]);
  395. vert->angles = G_malloc((vert->ecount) * sizeof(double));
  396. for (j = 0; j < vert->ecount; j++) {
  397. edge = vert->edges[j];
  398. t = (edge->v1 != i) ? (edge->v1) : (edge->v2);
  399. vert->angles[j] =
  400. atan2(pg->v[t].y - vert->y, pg->v[t].x - vert->x);
  401. }
  402. }
  403. destroy_si_struct(si);
  404. /*
  405. I'm not sure if shrinking of the allocated memory always preserves it's physical place.
  406. That's why I don't want to do this:
  407. if (pg->ecount < pg->eallocated) {
  408. pg->eallocated = pg->ecount;
  409. pg->e = G_realloc(pg->e, (pg->ecount)*sizeof(struct pg_edge));
  410. }
  411. */
  412. /* very time consuming */
  413. /*
  414. for (i = 0; i < pg->vcount; i++) {
  415. if (pg->v[i].ecount < pg->v[i].eallocated) {
  416. pg->v[i].eallocated = pg->v[i].ecount;
  417. pg->v[i].edges = G_realloc(pg->v[i].edges, (pg->v[i].ecount)*sizeof(struct pg_edges));
  418. }
  419. }
  420. */
  421. /* output pg */
  422. for (i = 0; i < pg->vcount; i++) {
  423. G_debug(4, " vertex %d (%g, %g)", i, pg->v[i].x, pg->v[i].y);
  424. for (j = 0; j < pg->v[i].ecount; j++) {
  425. G_debug(4, " edge %d-%d", pg->v[i].edges[j]->v1,
  426. pg->v[i].edges[j]->v2);
  427. }
  428. }
  429. return pg;
  430. }