legal.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /*************************************************************************
  2. * Copyright (c) 2011 AT&T Intellectual Property
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * https://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors: Details at https://graphviz.org
  9. *************************************************************************/
  10. #include <assert.h>
  11. #include <float.h>
  12. #include <math.h>
  13. #include <limits.h>
  14. #include <neatogen/neato.h>
  15. #include <pathplan/pathutil.h>
  16. #include <stddef.h>
  17. #include <util/alloc.h>
  18. #include <util/exit.h>
  19. #define SLOPE(p,q) ( ( ( p.y ) - ( q.y ) ) / ( ( p.x ) - ( q.x ) ) )
  20. #define EQ_PT(v,w) (((v).x == (w).x) && ((v).y == (w).y))
  21. #define after(v) (((v)==((v)->poly->finish))?((v)->poly->start):((v)+1))
  22. #define prior(v) (((v)==((v)->poly->start))?((v)->poly->finish):((v)-1))
  23. typedef struct active_edge active_edge;
  24. typedef struct polygon polygon;
  25. typedef struct {
  26. pointf pos;
  27. polygon *poly;
  28. active_edge *active;
  29. } vertex ;
  30. struct polygon {
  31. vertex *start, *finish;
  32. boxf bb;
  33. };
  34. struct active_edge {
  35. vertex *name;
  36. struct active_edge *next, *last;
  37. };
  38. typedef struct active_edge_list {
  39. active_edge *first, *final;
  40. int number;
  41. } active_edge_list ;
  42. typedef struct {
  43. int nvertices, ninters;
  44. } data ;
  45. static int sign(double v) {
  46. if (v < 0)
  47. return -1;
  48. if (v > 0)
  49. return 1;
  50. return 0;
  51. }
  52. /* find the sign of the area of each of the triangles
  53. formed by adding a vertex of m to l
  54. also find the sign of their product */
  55. static void sgnarea(vertex *l, vertex *m, int i[])
  56. {
  57. double a, b, c, d, e, f, g, h, t;
  58. a = l->pos.x;
  59. b = l->pos.y;
  60. c = after(l)->pos.x - a;
  61. d = after(l)->pos.y - b;
  62. e = m->pos.x - a;
  63. f = m->pos.y - b;
  64. g = after(m)->pos.x - a;
  65. h = after(m)->pos.y - b;
  66. t = c * f - d * e;
  67. i[0] = sign(t);
  68. t = c * h - d * g;
  69. i[1] = sign(t);
  70. i[2] = i[0] * i[1];
  71. }
  72. /** where is `g` relative to the interval delimited by `f` and `h`?
  73. *
  74. * The order of `f` and `h` is not assumed. That is, the interval defined may be
  75. * `(f, h)` or `(h, f)` depending on whether `f` is less than or greater than
  76. * `h`.
  77. *
  78. * \param f First boundary of the interval
  79. * \param g Value to test
  80. * \param h Second boundary of the interval
  81. * \return -1 if g is not in the interval, 1 if g is in the interval, 0 if g is
  82. * on the boundary (that is, equal to f or equal to h)
  83. */
  84. static int between(double f, double g, double h) {
  85. if (f < g) {
  86. if (g < h) {
  87. return 1;
  88. }
  89. if (g > h) {
  90. return -1;
  91. }
  92. return 0;
  93. }
  94. if (f > g) {
  95. if (g > h) {
  96. return 1;
  97. }
  98. if (g < h) {
  99. return -1;
  100. }
  101. return 0;
  102. }
  103. return 0;
  104. }
  105. /* determine if vertex i of line m is on line l */
  106. static int online(vertex *l, vertex *m, int i)
  107. {
  108. pointf a, b, c;
  109. a = l->pos;
  110. b = after(l)->pos;
  111. c = i == 0 ? m->pos : after(m)->pos;
  112. return a.x == b.x
  113. ? (a.x == c.x && -1 != between(a.y, c.y, b.y))
  114. : between(a.x, c.x, b.x);
  115. }
  116. /* determine point of detected intersections */
  117. static int intpoint(vertex *l, vertex *m, double *x, double *y, int cond)
  118. {
  119. pointf ls, le, ms, me, pt1, pt2;
  120. double m1, m2, c1, c2;
  121. if (cond <= 0)
  122. return 0;
  123. ls = l->pos;
  124. le = after(l)->pos;
  125. ms = m->pos;
  126. me = after(m)->pos;
  127. switch (cond) {
  128. case 3: /* a simple intersection */
  129. if (ls.x == le.x) {
  130. *x = ls.x;
  131. *y = me.y + SLOPE(ms, me) * (*x - me.x);
  132. } else if (ms.x == me.x) {
  133. *x = ms.x;
  134. *y = le.y + SLOPE(ls, le) * (*x - le.x);
  135. } else {
  136. m1 = SLOPE(ms, me);
  137. m2 = SLOPE(ls, le);
  138. c1 = ms.y - m1 * ms.x;
  139. c2 = ls.y - m2 * ls.x;
  140. *x = (c2 - c1) / (m1 - m2);
  141. *y = (m1 * c2 - c1 * m2) / (m1 - m2);
  142. }
  143. break;
  144. case 2: /* the two lines have a common segment */
  145. if (online(l, m, 0) == -1) { /* ms between ls and le */
  146. pt1 = ms;
  147. pt2 = online(m, l, 1) == -1
  148. ? (online(m, l, 0) == -1 ? le : ls) : me;
  149. } else if (online(l, m, 1) == -1) { /* me between ls and le */
  150. pt1 = me;
  151. pt2 = online(l, m, 0) == -1
  152. ? (online(m, l, 0) == -1 ? le : ls) : ms;
  153. } else {
  154. /* may be degenerate? */
  155. if (online(m, l, 0) != -1)
  156. return 0;
  157. pt1 = ls;
  158. pt2 = le;
  159. }
  160. *x = (pt1.x + pt2.x) / 2;
  161. *y = (pt1.y + pt2.y) / 2;
  162. break;
  163. case 1: /* a vertex of line m is on line l */
  164. if ((ls.x - le.x) * (ms.y - ls.y) == (ls.y - le.y) * (ms.x - ls.x)) {
  165. *x = ms.x;
  166. *y = ms.y;
  167. } else {
  168. *x = me.x;
  169. *y = me.y;
  170. }
  171. } /* end switch */
  172. return 1;
  173. }
  174. static void
  175. putSeg (int i, vertex* v)
  176. {
  177. fprintf(stderr, "seg#%d : (%.3f, %.3f) (%.3f, %.3f)\n",
  178. i, v->pos.x, v->pos.y, after(v)->pos.x, after(v)->pos.y);
  179. }
  180. /* realIntersect:
  181. * Return 1 if a real intersection has been found
  182. */
  183. static int
  184. realIntersect (vertex *firstv, vertex *secondv, pointf p)
  185. {
  186. pointf vft, vsd, avft, avsd;
  187. vft = firstv->pos;
  188. avft = after(firstv)->pos;
  189. vsd = secondv->pos;
  190. avsd = after(secondv)->pos;
  191. if ((vft.x != avft.x && vsd.x != avsd.x) ||
  192. (vft.x == avft.x && !EQ_PT(vft, p) && !EQ_PT(avft, p)) ||
  193. (vsd.x == avsd.x && !EQ_PT(vsd, p) && !EQ_PT(avsd, p)))
  194. {
  195. if (Verbose > 1) {
  196. fprintf(stderr, "\nintersection at %.3f %.3f\n",
  197. p.x, p.y);
  198. putSeg (1, firstv);
  199. putSeg (2, secondv);
  200. }
  201. return 1;
  202. }
  203. else return 0;
  204. }
  205. /* find_intersection:
  206. * detect whether segments l and m intersect
  207. * Return 1 if found; 0 otherwise;
  208. */
  209. static int find_intersection(vertex *l, vertex *m) {
  210. double x, y;
  211. pointf p;
  212. int i[3];
  213. sgnarea(l, m, i);
  214. if (i[2] > 0)
  215. return 0;
  216. if (i[2] < 0) {
  217. sgnarea(m, l, i);
  218. if (i[2] > 0)
  219. return 0;
  220. if (!intpoint(l, m, &x, &y, i[2] < 0 ? 3 : online(m, l, abs(i[0]))))
  221. return 0;
  222. }
  223. else if (!intpoint(l, m, &x, &y, i[0] == i[1] ?
  224. 2 * MAX(online(l, m, 0),
  225. online(l, m, 1)) : online(l, m, abs(i[0]))))
  226. return 0;
  227. p.x = x;
  228. p.y = y;
  229. return realIntersect(l, m, p);
  230. }
  231. static int gt(const void *a, const void *b) {
  232. const vertex *const *i = a;
  233. const vertex *const *j = b;
  234. if ((*i)->pos.x > (*j)->pos.x) {
  235. return 1;
  236. }
  237. if ((*i)->pos.x < (*j)->pos.x) {
  238. return -1;
  239. }
  240. if ((*i)->pos.y > (*j)->pos.y) {
  241. return 1;
  242. }
  243. if ((*i)->pos.y < (*j)->pos.y) {
  244. return -1;
  245. }
  246. return 0;
  247. }
  248. /* find_ints:
  249. * Check for pairwise intersection of polygon sides
  250. * Return 1 if intersection found, 0 for not found, -1 for error.
  251. */
  252. static int find_ints(vertex vertex_list[], size_t nvertices) {
  253. int j, k, found = 0;
  254. active_edge_list all;
  255. active_edge *new, *tempa;
  256. vertex *pt1, *pt2, *templ;
  257. all.first = all.final = 0;
  258. all.number = 0;
  259. vertex **pvertex = gv_calloc(nvertices, sizeof(vertex*));
  260. for (size_t i = 0; i < nvertices; i++)
  261. pvertex[i] = vertex_list + i;
  262. /* sort vertices by x coordinate */
  263. qsort(pvertex, nvertices, sizeof(vertex *), gt);
  264. /* walk through the vertices in order of increasing x coordinate */
  265. for (size_t i = 0; i < nvertices; i++) {
  266. pt1 = pvertex[i];
  267. templ = pt2 = prior(pvertex[i]);
  268. for (k = 0; k < 2; k++) { /* each vertex has 2 edges */
  269. switch (gt(&pt1, &pt2)) {
  270. case -1: /* forward edge, test and insert */
  271. /* test */
  272. for (tempa = all.first, j = 0; j < all.number;
  273. j++, tempa = tempa->next) {
  274. found = find_intersection(tempa->name, templ);
  275. if (found)
  276. goto finish;
  277. }
  278. new = gv_alloc(sizeof(active_edge));
  279. if (all.number == 0) {
  280. all.first = new;
  281. new->last = 0;
  282. } /* insert */
  283. else {
  284. all.final->next = new;
  285. new->last = all.final;
  286. }
  287. new->name = templ;
  288. new->next = 0;
  289. templ->active = new;
  290. all.final = new;
  291. all.number++;
  292. break; /* end of case -1 */
  293. case 1: /* backward edge, delete */
  294. if ((tempa = templ->active) == 0) {
  295. agerrorf("trying to delete a non-line\n");
  296. return -1;
  297. }
  298. if (all.number == 1)
  299. all.final = all.first = 0; /* delete the line */
  300. else if (tempa == all.first) {
  301. all.first = all.first->next;
  302. all.first->last = 0;
  303. } else if (tempa == all.final) {
  304. all.final = all.final->last;
  305. all.final->next = 0;
  306. } else {
  307. tempa->last->next = tempa->next;
  308. tempa->next->last = tempa->last;
  309. }
  310. free(tempa);
  311. all.number--;
  312. templ->active = 0;
  313. break; /* end of case 1 */
  314. default:
  315. break; // same point; do nothing
  316. } /* end switch */
  317. pt2 = after(pvertex[i]);
  318. templ = pvertex[i]; /*second neighbor */
  319. } /* end k for loop */
  320. } /* end i for loop */
  321. finish :
  322. for (tempa = all.first, j = 0; j < all.number;
  323. j++, tempa = new) {
  324. new = tempa->next;
  325. free (tempa);
  326. }
  327. free (pvertex);
  328. return found;
  329. }
  330. #define INBOX(p,bb) ((p.x <= bb.UR.x) && (p.x >= bb.LL.x) && (p.y <= bb.UR.y) && (p.y >= bb.LL.y))
  331. #define NESTED(a,b) (INBOX(a.LL,b) && INBOX(a.UR,b))
  332. /* findInside:
  333. * Check if one polygon is inside another. We know that each
  334. * pair is either disjoint or one is inside the other.
  335. * Return 1 if an intersection is found, 0 otherwise.
  336. */
  337. static int
  338. findInside(Ppoly_t ** polys, int n_polys, polygon* polygon_list)
  339. {
  340. int i, j;
  341. pointf pt;
  342. Ppoly_t* p1;
  343. Ppoly_t* p2;
  344. for (i = 0; i < n_polys; i++) {
  345. p1 = polys[i];
  346. pt = p1->ps[0];
  347. for (j = i+1; j < n_polys; j++) {
  348. p2 = polys[j];
  349. if (NESTED(polygon_list[i].bb,polygon_list[j].bb)) {
  350. if (in_poly(*p2, pt)) return 1;
  351. }
  352. else if (NESTED(polygon_list[j].bb,polygon_list[i].bb)) {
  353. if (in_poly(*p1, p2->ps[0])) return 1;
  354. }
  355. }
  356. }
  357. return 0;
  358. }
  359. /* Plegal_arrangement:
  360. * Check that none of the polygons overlap.
  361. * Return 1 if okay; 0 otherwise.
  362. */
  363. int Plegal_arrangement(Ppoly_t ** polys, int n_polys)
  364. {
  365. int i, vno, found;
  366. boxf bb;
  367. double x, y;
  368. polygon *polygon_list = gv_calloc(n_polys, sizeof(polygon));
  369. size_t nverts;
  370. for (nverts = 0, i = 0; i < n_polys; i++) {
  371. nverts += polys[i]->pn;
  372. }
  373. vertex *vertex_list = gv_calloc(nverts, sizeof(vertex));
  374. for (i = vno = 0; i < n_polys; i++) {
  375. polygon_list[i].start = &vertex_list[vno];
  376. bb.LL.x = bb.LL.y = DBL_MAX;
  377. bb.UR.x = bb.UR.y = -DBL_MAX;
  378. for (size_t j = 0; j < polys[i]->pn; j++) {
  379. x = polys[i]->ps[j].x;
  380. y = polys[i]->ps[j].y;
  381. bb.LL.x = fmin(bb.LL.x,x);
  382. bb.LL.y = fmin(bb.LL.y,y);
  383. bb.UR.x = fmax(bb.UR.x,x);
  384. bb.UR.y = fmax(bb.UR.y,y);
  385. vertex_list[vno].pos.x = x;
  386. vertex_list[vno].pos.y = y;
  387. vertex_list[vno].poly = &polygon_list[i];
  388. vertex_list[vno].active = 0;
  389. vno++;
  390. }
  391. polygon_list[i].finish = &vertex_list[vno - 1];
  392. polygon_list[i].bb = bb;
  393. }
  394. found = find_ints(vertex_list, nverts);
  395. if (found < 0) {
  396. free(polygon_list);
  397. free(vertex_list);
  398. return 0;
  399. }
  400. if (!found) {
  401. found = findInside(polys, n_polys, polygon_list);
  402. }
  403. free(polygon_list);
  404. free(vertex_list);
  405. return !found;
  406. }