find_ints.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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 "simple.h"
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <util/alloc.h>
  14. #include <util/exit.h>
  15. static int gt(const void *a, const void *b);
  16. void find_ints(struct vertex vertex_list[],
  17. struct data *input,
  18. struct intersection ilist[])
  19. {
  20. int j, k;
  21. struct active_edge_list all;
  22. struct active_edge *tempa;
  23. struct vertex *pt1, *pt2, *templ;
  24. input->ninters = 0;
  25. all.first = all.final = NULL;
  26. all.number = 0;
  27. struct vertex **pvertex = gv_calloc(input->nvertices, sizeof(struct vertex*));
  28. for (size_t i = 0; i < input->nvertices; i++)
  29. pvertex[i] = vertex_list + i;
  30. /* sort vertices by x coordinate */
  31. qsort(pvertex, input->nvertices, sizeof(struct vertex *), gt);
  32. /* walk through the vertices in order of increasing x coordinate */
  33. for (size_t i = 0; i < input->nvertices; i++) {
  34. pt1 = pvertex[i];
  35. templ = pt2 = prior(pvertex[i]);
  36. for (k = 0; k < 2; k++) { /* each vertex has 2 edges */
  37. switch (gt(&pt1, &pt2)) {
  38. case -1: /* forward edge, test and insert */
  39. for (tempa = all.first, j = 0; j < all.number;
  40. j++, tempa = tempa->next)
  41. find_intersection(tempa->name, templ, ilist, input); /* test */
  42. struct active_edge *new = gv_alloc(sizeof(struct active_edge));
  43. if (all.number == 0) {
  44. all.first = new;
  45. new->last = NULL;
  46. } /* insert */
  47. else {
  48. all.final->next = new;
  49. new->last = all.final;
  50. }
  51. new->name = templ;
  52. new->next = NULL;
  53. templ->active = new;
  54. all.final = new;
  55. all.number++;
  56. break; /* end of case -1 */
  57. case 1: /* backward edge, delete */
  58. if ((tempa = templ->active) == NULL) {
  59. fprintf(stderr,
  60. "\n***ERROR***\n trying to delete a non line\n");
  61. graphviz_exit(1);
  62. }
  63. if (all.number == 1)
  64. all.final = all.first = NULL; /* delete the line */
  65. else if (tempa == all.first) {
  66. all.first = all.first->next;
  67. all.first->last = NULL;
  68. } else if (tempa == all.final) {
  69. all.final = all.final->last;
  70. all.final->next = NULL;
  71. } else {
  72. tempa->last->next = tempa->next;
  73. tempa->next->last = tempa->last;
  74. }
  75. free(tempa);
  76. all.number--;
  77. templ->active = NULL;
  78. break; /* end of case 1 */
  79. default:
  80. break;
  81. } /* end switch */
  82. pt2 = after(pvertex[i]);
  83. templ = pvertex[i]; /*second neighbor */
  84. } /* end k for loop */
  85. } /* end i for loop */
  86. free(pvertex);
  87. }
  88. static int gt(const void *a, const void *b) {
  89. const struct vertex *const *i = a;
  90. const struct vertex *const *j = b;
  91. if ((*i)->pos.x > (*j)->pos.x) {
  92. return 1;
  93. }
  94. if ((*i)->pos.x < (*j)->pos.x) {
  95. return -1;
  96. }
  97. if ((*i)->pos.y > (*j)->pos.y) {
  98. return 1;
  99. }
  100. if ((*i)->pos.y < (*j)->pos.y) {
  101. return -1;
  102. }
  103. return 0;
  104. }