pointset.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /// @file
  2. /// @ingroup common_utils
  3. /*************************************************************************
  4. * Copyright (c) 2011 AT&T Intellectual Property
  5. * All rights reserved. This program and the accompanying materials
  6. * are made available under the terms of the Eclipse Public License v1.0
  7. * which accompanies this distribution, and is available at
  8. * https://www.eclipse.org/legal/epl-v10.html
  9. *
  10. * Contributors: Details at https://graphviz.org
  11. *************************************************************************/
  12. #include <common/render.h>
  13. #include <common/pointset.h>
  14. #include <stddef.h>
  15. #include <util/alloc.h>
  16. typedef struct {
  17. Dtlink_t link;
  18. pointf id;
  19. } pair;
  20. static pair *mkPair(pointf p) {
  21. pair *pp = gv_alloc(sizeof(pair));
  22. pp->id = p;
  23. return pp;
  24. }
  25. static int cmppair(void *k1, void *k2) {
  26. const pointf *key1 = k1;
  27. const pointf *key2 = k2;
  28. if (key1->x > key2->x)
  29. return 1;
  30. else if (key1->x < key2->x)
  31. return -1;
  32. else if (key1->y > key2->y)
  33. return 1;
  34. else if (key1->y < key2->y)
  35. return -1;
  36. else
  37. return 0;
  38. }
  39. static Dtdisc_t intPairDisc = {
  40. offsetof(pair, id),
  41. sizeof(pointf),
  42. offsetof(pair, link),
  43. 0,
  44. free,
  45. cmppair,
  46. };
  47. PointSet *newPS(void)
  48. {
  49. return (dtopen(&intPairDisc, Dtoset));
  50. }
  51. void freePS(PointSet * ps)
  52. {
  53. dtclose(ps);
  54. }
  55. void insertPS(PointSet *ps, pointf pt) {
  56. pair *pp;
  57. pp = mkPair(pt);
  58. if (dtinsert(ps, pp) != pp)
  59. free(pp);
  60. }
  61. void addPS(PointSet *ps, double x, double y) {
  62. const pointf pt = {.x = x, .y = y};
  63. pair *pp = mkPair(pt);
  64. if (dtinsert(ps, pp) != pp)
  65. free(pp);
  66. }
  67. int inPS(PointSet *ps, pointf pt) {
  68. pair p;
  69. p.id = pt;
  70. return dtsearch(ps, &p) ? 1 : 0;
  71. }
  72. int isInPS(PointSet *ps, double x, double y) {
  73. return inPS(ps, (pointf){.x = x, .y = y});
  74. }
  75. int sizeOf(PointSet * ps)
  76. {
  77. return dtsize(ps);
  78. }
  79. pointf *pointsOf(PointSet *ps) {
  80. const size_t n = (size_t)dtsize(ps);
  81. pointf *pts = gv_calloc(n, sizeof(pointf));
  82. pair *p;
  83. pointf *pp = pts;
  84. for (p = (pair *) dtflatten(ps); p;
  85. p = (pair *)dtlink(ps, p)) {
  86. *pp++ = p->id;
  87. }
  88. return pts;
  89. }
  90. typedef struct {
  91. Dtlink_t link;
  92. point id;
  93. int v;
  94. } mpair;
  95. static void *mkMPair(void *p, Dtdisc_t *disc) {
  96. (void)disc;
  97. mpair *obj = p;
  98. mpair *ap = gv_alloc(sizeof(mpair));
  99. ap->id = obj->id;
  100. ap->v = obj->v;
  101. return ap;
  102. }
  103. static Dtdisc_t intMPairDisc = {
  104. offsetof(mpair, id),
  105. sizeof(point),
  106. offsetof(mpair, link),
  107. mkMPair,
  108. free,
  109. cmppair,
  110. };
  111. PointMap *newPM(void)
  112. {
  113. return dtopen(&intMPairDisc, Dtoset);
  114. }
  115. void clearPM(PointMap * ps)
  116. {
  117. dtclear(ps);
  118. }
  119. void freePM(PointMap * ps)
  120. {
  121. dtclose(ps);
  122. }
  123. int insertPM(PointMap * pm, int x, int y, int value)
  124. {
  125. mpair *p;
  126. mpair dummy;
  127. dummy.id.x = x;
  128. dummy.id.y = y;
  129. dummy.v = value;
  130. p = dtinsert(pm, &dummy);
  131. return p->v;
  132. }