sw_voronoi.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include <stdlib.h>
  2. #include "sw_defs.h"
  3. /* implicit parameters: nsites, sqrt_nsites, xmin, xmax, ymin, ymax,
  4. deltax, deltay (can all be estimates).
  5. Performance suffers if they are wrong; better to make nsites,
  6. deltax, and deltay too big than too small. (?) */
  7. int voronoi(int triangulate, struct Site *(*nextsite) (void))
  8. {
  9. struct Site *newsite, *bot, *top, *temp, *p;
  10. struct Site *v;
  11. struct Point newintstar;
  12. int pm;
  13. struct Halfedge *lbnd, *rbnd, *llbnd, *rrbnd, *bisector;
  14. struct Edge *e;
  15. PQinitialize();
  16. bottomsite = (*nextsite) ();
  17. out_site(bottomsite);
  18. ELinitialize();
  19. newsite = (*nextsite) ();
  20. while (1) {
  21. if (!PQempty())
  22. newintstar = PQ_min();
  23. if (newsite != (struct Site *)NULL && (PQempty()
  24. || newsite->coord.y < newintstar.y || (newsite->coord.y == newintstar.y && newsite->coord.x < newintstar.x))) { /* new site is smallest */
  25. out_site(newsite);
  26. lbnd = ELleftbnd(&(newsite->coord));
  27. rbnd = ELright(lbnd);
  28. bot = rightreg(lbnd);
  29. e = bisect(bot, newsite);
  30. bisector = HEcreate(e, le);
  31. ELinsert(lbnd, bisector);
  32. if ((p = intersect(lbnd, bisector)) != (struct Site *)NULL) {
  33. PQdelete(lbnd);
  34. PQinsert(lbnd, p, dist(p, newsite));
  35. }
  36. lbnd = bisector;
  37. bisector = HEcreate(e, re);
  38. ELinsert(lbnd, bisector);
  39. if ((p = intersect(bisector, rbnd)) != (struct Site *)NULL) {
  40. PQinsert(bisector, p, dist(p, newsite));
  41. }
  42. /* get next site, but ensure that it doesn't have the same
  43. coordinates as the previous. If so, step over to the following
  44. site. Andrea Aime 4/7/2001 */
  45. do
  46. temp = (*nextsite) ();
  47. while (temp != (struct Site *)NULL &&
  48. temp->coord.x == newsite->coord.x &&
  49. temp->coord.y == newsite->coord.y);
  50. newsite = temp;
  51. }
  52. else if (!PQempty())
  53. /* intersection is smallest */
  54. {
  55. lbnd = PQextractmin();
  56. llbnd = ELleft(lbnd);
  57. rbnd = ELright(lbnd);
  58. rrbnd = ELright(rbnd);
  59. bot = leftreg(lbnd);
  60. top = rightreg(rbnd);
  61. out_triple(bot, top, rightreg(lbnd));
  62. v = lbnd->vertex;
  63. makevertex(v);
  64. endpoint(lbnd->ELedge, lbnd->ELpm, v);
  65. endpoint(rbnd->ELedge, rbnd->ELpm, v);
  66. ELdelete(lbnd);
  67. PQdelete(rbnd);
  68. ELdelete(rbnd);
  69. pm = le;
  70. if (bot->coord.y > top->coord.y) {
  71. temp = bot;
  72. bot = top;
  73. top = temp;
  74. pm = re;
  75. }
  76. e = bisect(bot, top);
  77. bisector = HEcreate(e, pm);
  78. ELinsert(llbnd, bisector);
  79. endpoint(e, re - pm, v);
  80. deref(v);
  81. if ((p = intersect(llbnd, bisector)) != (struct Site *)NULL) {
  82. PQdelete(llbnd);
  83. PQinsert(llbnd, p, dist(p, bot));
  84. }
  85. if ((p = intersect(bisector, rrbnd)) != (struct Site *)NULL) {
  86. PQinsert(bisector, p, dist(p, bot));
  87. }
  88. }
  89. else
  90. break;
  91. }
  92. for (lbnd = ELright(ELleftend); lbnd != ELrightend; lbnd = ELright(lbnd)) {
  93. e = lbnd->ELedge;
  94. out_ep(e);
  95. }
  96. return 0;
  97. }