neighbors.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #ifndef __NEIGHBORS_H
  2. #define __NEIGHBORS_H
  3. #include <vector>
  4. #include <unordered_map>
  5. #include <set>
  6. namespace neighbors {
  7. typedef std::pair<unsigned int, unsigned int> pt;
  8. struct Neighbors {
  9. typedef std::pair<int, int> p0_t;
  10. typedef std::unordered_map< pt, std::set<p0_t> > ns_t;
  11. ns_t nbmap;
  12. std::set<p0_t> defaults;
  13. unsigned int w;
  14. unsigned int h;
  15. void init(unsigned int _w, unsigned int _h) {
  16. w = _w;
  17. h = _h;
  18. for (int xi = -1; xi <= 1; xi++) {
  19. for (int yi = -1; yi <= 1; yi++) {
  20. if (xi == 0 && yi == 0) continue;
  21. defaults.insert(p0_t(xi, yi));
  22. }
  23. }
  24. nbmap.clear();
  25. for (unsigned int x = 0; x < w; x++) {
  26. for (unsigned int y = 0; y < h; y++) {
  27. if (x > 0 && x < w - 1 &&
  28. y > 0 && y < h - 1)
  29. continue;
  30. auto& v = nbmap[std::make_pair(x, y)];
  31. for (int xi = -1; xi <= 1; xi++) {
  32. for (int yi = -1; yi <= 1; yi++) {
  33. if (xi == 0 && yi == 0) continue;
  34. p0_t tmp(x+xi, y+yi);
  35. if (tmp.first < 0 || tmp.first >= (int)w || tmp.second < 0 || tmp.second >= (int)h)
  36. continue;
  37. v.insert(v.end(), p0_t(xi, yi));
  38. }
  39. }
  40. }
  41. }
  42. }
  43. void clear() {
  44. init(w, h);
  45. }
  46. const std::set<p0_t>& operator()(const pt& xy) const {
  47. ns_t::const_iterator i = nbmap.find(xy);
  48. if (i != nbmap.end()) {
  49. return i->second;
  50. }
  51. return defaults;
  52. }
  53. static pt mk(const p0_t& off, unsigned int x, unsigned int y) {
  54. return pt(off.first + x, off.second + y);
  55. }
  56. static pt mk(const p0_t& off, const pt& xy) {
  57. return pt(off.first + xy.first, off.second + xy.second);
  58. }
  59. bool linked(const pt& xy1, const pt& xy2) const {
  60. ns_t::const_iterator i = nbmap.find(xy1);
  61. if (i == nbmap.end())
  62. return true;
  63. p0_t tmp((int)xy2.first - (int)xy1.first, (int)xy2.second - (int)xy1.second);
  64. return i->second.count(tmp);
  65. }
  66. };
  67. }
  68. namespace serialize {
  69. template <>
  70. struct reader<neighbors::Neighbors> {
  71. void read(Source& s, neighbors::Neighbors& t) {
  72. serialize::read(s, t.w);
  73. serialize::read(s, t.h);
  74. t.init(t.w, t.h);
  75. }
  76. };
  77. template <>
  78. struct writer<neighbors::Neighbors> {
  79. void write(Sink& s, const neighbors::Neighbors& t) {
  80. serialize::write(s, t.w);
  81. serialize::write(s, t.h);
  82. }
  83. };
  84. }
  85. #endif