Guest User

Untitled

a guest
Aug 15th, 2018
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.58 KB | None | 0 0
  1. #ifndef __QUADTREE
  2. #define __QUADTREE
  3.  
  4. #include <iostream>
  5. #include <queue>
  6.  
  7. using namespace std;
  8.  
  9. //Quadtree voor punten met int-co"ordinaten
  10. //de PRquadtree kan alleen punten bevatten met
  11. //-maxcoordinaat <= x < maxcoordinaat
  12. //-maxcoordinaat <= y < maxcoordinaat
  13.  
  14. static const int OOST = 0;
  15. static const int WEST = 1;
  16. static const int NOORD = 0;
  17. static const int ZUID = 2;
  18.  
  19. /*
  20. * 1 | 0
  21. * ---------
  22. * 3 | 2
  23. */
  24.  
  25. class Gebied {
  26. public:
  27.  
  28. Gebied(int maxc) : xl(-maxc), xr(maxc), yl(-maxc), yr(maxc), xc(0), yc(0) {
  29. };
  30.  
  31. void maakdeelgebied(int x, int y) {
  32. if (x < xc)
  33. xr = xc;
  34. else
  35. xl = xc;
  36. if (y < yc)
  37. yr = yc;
  38. else
  39. yl = yc;
  40. xc = (xl + xr) / 2;
  41. yc = (yl + yr) / 2;
  42. cout << "Gebied is door punt (" << x << "," << y << ") gesplitst -> centrum = (" << xc << "," << yc << ")" << endl;
  43. };
  44.  
  45. int geefKwadrant(int x, int y) const {
  46. return (x < xc ? WEST : OOST) + (y < yc ? ZUID : NOORD);
  47. }
  48.  
  49. int geefXCentrum() const {
  50. return xc;
  51. }
  52.  
  53. int geefYCentrum() const {
  54. return yc;
  55. }
  56. private:
  57. int xl, xr, yl, yr, xc, yc; //geven grenzen gebied; l,r,c: links, rechts, centraal.
  58. };
  59.  
  60. class PRquadtree {
  61. public:
  62.  
  63. PRquadtree(int _maxcoordinaat) : maxcoordinaat(_maxcoordinaat), k(0) {
  64. };
  65. //voegtoe veronderstelt dat het punt in het gebied ligt.
  66. void voegtoe(int x, int y);
  67.  
  68. friend ostream & operator <<(ostream& os, const PRquadtree& boom) {
  69. os << "PRQuadtree: " << endl;
  70. for (int i = 0; i < 20; i++) os << "*";
  71. os << endl;
  72.  
  73. queue<Knoop*> wachtrij;
  74. int knoopTeller = 0;
  75. int volgendeDiepte = 1;
  76. int vorigeDiepte = 0;
  77. int aantalBladeren = 0;
  78. if (boom.k != 0) {
  79. wachtrij.push(boom.k);
  80. } else {
  81. os << "PRQuadtree is leeg" << endl;
  82. }
  83. while (!wachtrij.empty()) {
  84. knoopTeller++;
  85. Knoop* huidigeknoop = wachtrij.front();
  86. wachtrij.pop();
  87. if (huidigeknoop != 0) {
  88. if (huidigeknoop->isblad()) {
  89. Blad* huidigblad = (Blad*) huidigeknoop;
  90. os << *huidigblad << " | ";
  91. aantalBladeren++;
  92. } else {
  93. Nietblad* huidignietblad = (Nietblad*) huidigeknoop;
  94. for (int i = 0; i < 4; i++) {
  95. wachtrij.push(huidignietblad->geefkind(i));
  96. }
  97. vorigeDiepte = volgendeDiepte + 4;
  98. os << "(NB) | ";
  99. }
  100. } else {
  101. os << "(null) | ";
  102. }
  103. if (knoopTeller == volgendeDiepte) {
  104. os << endl;
  105. volgendeDiepte = vorigeDiepte;
  106. }
  107. }
  108. os << endl << "Aantal bladeren: " << aantalBladeren << endl;
  109. }
  110. protected:
  111.  
  112. class Knoop {
  113. public:
  114. virtual bool isblad() const = 0;
  115. };
  116.  
  117. class Blad : public Knoop {
  118. public:
  119.  
  120. Blad(int _x, int _y) : x(_x), y(_y) {
  121. };
  122.  
  123. virtual bool isblad() const {
  124. return true;
  125. }
  126. int x, y; //co"ordinaten punt
  127.  
  128. friend ostream & operator <<(ostream& os, const Blad& blad) {
  129. os << "(" << blad.x << "," << blad.y << ")";
  130. }
  131. };
  132.  
  133. class Nietblad : public Knoop {
  134. public:
  135.  
  136. Nietblad() {
  137. for (int i = 0; i < 4; i++)
  138. kind[i] = 0;
  139. }
  140.  
  141. virtual bool isblad() const {
  142. return false;
  143. }
  144.  
  145. Knoop** geefkind(int x, int y, int xc, int yc) {//geen const: kindtabel kan gewijzigd worden
  146. int xindex = (x < xc ? WEST : OOST);
  147. int yindex = (y < yc ? ZUID : NOORD);
  148. cout << "Index van (" << x << "," << y << "): " << (xindex + yindex) << endl;
  149. return &kind[xindex + yindex];
  150. }
  151.  
  152. Knoop** geefKindInKwadrant(int kwadrant) {
  153. return &kind[kwadrant];
  154. }
  155.  
  156. Knoop* geefkind(int index) {
  157. return kind[index];
  158. }
  159.  
  160. private:
  161. Knoop* kind[4]; //indexeren met windrichting (bv. kind[NOORD+OOST] bevat punten
  162. //met x en y kleiner dan grenswaarde)
  163. //leeg gebied: nulpointer
  164. };
  165. const int maxcoordinaat; //wordt opgegeven in constructor;
  166. Knoop* k;
  167. };
  168.  
  169. void PRquadtree::voegtoe(int x, int y) {
  170. cout << "Nieuw punt (" << x << "," << y << ") toevoegen" << endl;
  171. // Gebied aanmaken a.d.h.v. de maxcoördinaat
  172. Gebied gebied(maxcoordinaat);
  173.  
  174. // Gebied al in 4 splitsen. Anders wordt enkel kind[0] van de wortel gebruikt
  175. gebied.maakdeelgebied(x, y);
  176.  
  177. // Blad aanmaken met de gegevens coördinaten
  178. Knoop* nieuwBlad = new Blad(x, y);
  179.  
  180. if (k == 0) {
  181. cout << "Wortel is leeg, vervangen met Nietblad" << endl;
  182. // PRQuadtree is leeg
  183. // Wortel wijst nu naar een Nietblad met 1 kind
  184. k = new Nietblad();
  185. //gebied.maakdeelgebied(x, y);
  186. cout << "Laat kind wijzen naar knoop met index van (" << x << "," << y << ")" << endl;
  187. Knoop** hulp = (static_cast<Nietblad*> (k))->geefkind(x, y, gebied.geefXCentrum(), gebied.geefYCentrum());
  188. (*hulp) = nieuwBlad;
  189. } else {
  190. cout << "Wortel is niet leeg" << endl;
  191. // Pointer bijhouden naar de het adres van de knoop waaronder het nieuwe
  192. // blad moet komen
  193. Knoop** kind = &k;
  194.  
  195. // Zolang k bestaat en geen blad is moeten we verder zoeken
  196. while (*kind != 0 && !(*kind)->isblad()) {
  197. gebied.maakdeelgebied(x, y);
  198. cout << "Laat kind wijzen naar knoop met index van (" << x << "," << y << ")" << endl;
  199. kind = ((static_cast<Nietblad*> (*kind)))->geefKindInKwadrant(gebied.geefKwadrant(x, y));
  200. }
  201.  
  202. // Is kind een adres naar een nullpointer? Dan kunnen we het nieuwe blad
  203. // gewoon aan de boom hangen
  204. if (*kind == 0) {
  205. cout << "Kind is nullpointer, wordt vervangen door het nieuwe blad" << endl;
  206. (*kind) = nieuwBlad;
  207. } else {
  208. cout << "Kind is geen nullpointer, dit blad moet gesplitst worden" << endl;
  209. // Blad gevonden, dit moet gesplitst worden
  210.  
  211. // Nietblad aanmaken
  212. Knoop* nietblad = new Nietblad();
  213.  
  214. // Pointer naar het oude blad bijhouden
  215. Knoop* oudBlad = *kind;
  216.  
  217. // Kind vervangen door het nietblad
  218. (*kind) = nietblad;
  219.  
  220. // Nietblad_hulp declareren
  221. Knoop* nietblad_hulp = 0;
  222.  
  223. // Zolang het gevonden blad in hetzelfde kwadrant ligt als het
  224. // nieuwe punt, moeten we verder splitsen
  225. int kwadrantOudBlad = gebied.geefKwadrant((static_cast<Blad*> (oudBlad))->x, (static_cast<Blad*> (oudBlad))->y);
  226. int kwadrantNieuwBlad = gebied.geefKwadrant(x, y);
  227.  
  228. while (kwadrantOudBlad == kwadrantNieuwBlad) {
  229. // Beide punten liggen in hetzelfde kwadrant
  230. cout << "Beide punten liggen in hetzelfde kwadrant: " << kwadrantOudBlad << endl;
  231.  
  232. // Nieuw nietblad aanmaken
  233. nietblad_hulp = new Nietblad();
  234.  
  235. // Plaats waar het nieuwe Nietblad moet komen bepalen
  236. cout << "Verplaats kindpointer naar index " << kwadrantOudBlad << " van nietblad" << endl;
  237. kind = (static_cast<Nietblad*> (nietblad))->geefKindInKwadrant(kwadrantOudBlad);
  238. (*kind) = nietblad_hulp;
  239. cout << "Nietblad toegevoegd aan de boom" << endl;
  240.  
  241. // Gebied opsplitsen
  242. gebied.maakdeelgebied((static_cast<Blad*> (oudBlad))->x, ((static_cast<Blad*> (oudBlad))->y));
  243.  
  244. //Kwadranten opnieuw berekenen
  245. kwadrantOudBlad = gebied.geefKwadrant((static_cast<Blad*> (oudBlad))->x, (static_cast<Blad*> (oudBlad))->y);
  246. kwadrantNieuwBlad = gebied.geefKwadrant(x, y);
  247.  
  248. // Nieuw adres waar het oude punt moet terechtkomen bepalen
  249. cout << "Verplaats kindpointer naar index " << kwadrantOudBlad << " van nietblad_hulp" << endl;
  250. kind = (static_cast<Nietblad*> (nietblad_hulp))->geefKindInKwadrant(kwadrantOudBlad);
  251. }
  252. // We vragen een pointer naar de plaats waar het nieuwe punt moet
  253. // toegevoegd worden. Deze pointer is sowieso 0, want anders bevinden
  254. // we ons nog in de while-lus
  255.  
  256. // Het oude blad opnieuw aan de boom toevoegen
  257. cout << "Punt (" << (static_cast<Blad*> (oudBlad))->x << "," << (static_cast<Blad*> (oudBlad))->y << ") opnieuw toevoegen aan de boom" << endl;
  258. (*kind) = oudBlad;
  259.  
  260. // De nieuwe coördinaat kan nu toegevoegd worden aan de boom
  261. Knoop** hulp;
  262. cout << "Verplaats hulppointer naar index " << kwadrantNieuwBlad << " van nietblad_hulp" << endl;
  263. if (nietblad_hulp != 0)
  264. hulp = (static_cast<Nietblad*> (nietblad_hulp))->geefKindInKwadrant(kwadrantNieuwBlad);
  265. else
  266. hulp = (static_cast<Nietblad*> (nietblad))->geefKindInKwadrant(kwadrantNieuwBlad);
  267. cout << "Punt (" << x << "," << y << ") toevoegen aan de boom" << endl;
  268. (*hulp) = nieuwBlad;
  269. }
  270. }
  271. cout << "Nieuw punt (" << x << "," << y << ") is toegevoegd" << endl << endl;
  272. cout << *this;
  273. for (int i = 0; i < 20; i++) cout << "*";
  274. cout << endl << endl;
  275. }
  276.  
  277. #endif
Add Comment
Please, Sign In to add comment