Advertisement
Guest User

Untitled

a guest
Mar 26th, 2017
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.60 KB | None | 0 0
  1. import java.awt.*;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4.  
  5. class QuadTree {
  6. private static final int CAPACITY = 4;
  7.  
  8. private final AABB boundary;
  9.  
  10. private List<Node> points = new ArrayList<>();
  11.  
  12. private QuadTree northWest;
  13. private QuadTree northEast;
  14. private QuadTree southWest;
  15. private QuadTree southEast;
  16.  
  17. QuadTree(AABB boundary){
  18. this.boundary = boundary;
  19. }
  20.  
  21. Node closestNode(Point clickPoint, Location origin, double scale){
  22. Location clickLocation = Location.newFromPoint(clickPoint, origin, scale);
  23. return closestNode(clickLocation);
  24. }
  25.  
  26. private Node closestNode(Location clickLocation){
  27. if(!boundary.containsPoint(clickLocation)) return null;
  28. if(northWest != null){
  29. Node nwClosestNode = northWest.closestNode(clickLocation);
  30. Node neClosestNode = northEast.closestNode(clickLocation);
  31. Node seClosestNode = southEast.closestNode(clickLocation);
  32. Node swClosestNode = southWest.closestNode(clickLocation);
  33. Node closestNode = null;
  34. if(nwClosestNode != null) closestNode = nwClosestNode;
  35. if(neClosestNode != null) closestNode = neClosestNode;
  36. if(seClosestNode != null) closestNode = seClosestNode;
  37. if(swClosestNode != null) closestNode = swClosestNode;
  38. double distance;
  39. if(closestNode == null) distance = Double.MAX_VALUE;
  40. else {
  41. double xdiff = clickLocation.x - closestNode.getLocation().x;
  42. double ydiff = clickLocation.y - closestNode.getLocation().y;
  43. distance = (xdiff * xdiff) + (ydiff * ydiff);
  44. }
  45. if(nwClosestNode == null) closestNode = closerNode(clickLocation, closestNode, distance);
  46. if(neClosestNode == null) closestNode = closerNode(clickLocation, closestNode, distance);
  47. if(seClosestNode == null) closestNode = closerNode(clickLocation, closestNode, distance);
  48. if(swClosestNode == null) closestNode = closerNode(clickLocation, closestNode, distance);
  49. return closestNode;
  50. }
  51. Node closestNode = closestPointInQuad(clickLocation);
  52. return closestNode;
  53. }
  54.  
  55. private Node closerNode(Location clickLocation, Node closestNode, double distance){
  56. if(!(boundary.containsPoint(new Location(clickLocation.x + distance, clickLocation.y)) ||
  57. boundary.containsPoint(new Location(clickLocation.x - distance, clickLocation.y)) ||
  58. boundary.containsPoint(new Location(clickLocation.x, clickLocation.y + distance)) ||
  59. boundary.containsPoint(new Location(clickLocation.x, clickLocation.y - distance)))){
  60. return closestNode;
  61. }
  62. if(northWest != null){
  63. Node nwClosestNode = northWest.closerNode(clickLocation, closestNode, distance);
  64. Node neClosestNode = northEast.closerNode(clickLocation, closestNode, distance);
  65. Node seClosestNode = southEast.closerNode(clickLocation, closestNode, distance);
  66. Node swClosestNode = southWest.closerNode(clickLocation, closestNode, distance);
  67. if(nwClosestNode != null) return nwClosestNode;
  68. if(neClosestNode != null) return neClosestNode;
  69. if(seClosestNode != null) return seClosestNode;
  70. if(swClosestNode != null) return swClosestNode;
  71. }
  72. closestNode = closestNodeInQuad(clickLocation, closestNode, distance);
  73. return closestNode;
  74. }
  75.  
  76. private Node closestPointInQuad(Location clickLocation){
  77. return closestNodeInQuad(clickLocation, null, Double.MAX_VALUE);
  78. }
  79.  
  80. private Node closestNodeInQuad(Location clickLocation, Node closestNode, double lowestDistance){
  81. for(Node n : points){
  82. double xdiff = clickLocation.x - n.getLocation().x;
  83. double ydiff = clickLocation.y - n.getLocation().y;
  84. double distance = (xdiff*xdiff) + (ydiff*ydiff);
  85. if(distance < lowestDistance){
  86. lowestDistance = distance;
  87. closestNode = n;
  88. }
  89. }
  90. return closestNode;
  91. }
  92.  
  93. boolean insert(Node n){
  94. if(!boundary.containsPoint(n.getLocation()))
  95. return false;
  96.  
  97. if(points.size() < CAPACITY){
  98. points.add(n);
  99. return true;
  100. }
  101.  
  102. if(northWest == null)
  103. subdivide();
  104.  
  105. if(northWest.insert(n)) return true;
  106. if(northEast.insert(n)) return true;
  107. if(southWest.insert(n)) return true;
  108. if(southEast.insert(n)) return true;
  109.  
  110. return false;
  111. }
  112.  
  113. private void subdivide(){
  114. northWest = new QuadTree(new AABB(new Location(boundary.getCentre().x - boundary.getHalfDimension()/2,
  115. boundary.getCentre().y - boundary.getHalfDimension()/2),
  116. boundary.getHalfDimension()/2));
  117. northEast = new QuadTree(new AABB(new Location(boundary.getCentre().x + boundary.getHalfDimension()/2,
  118. boundary.getCentre().y - boundary.getHalfDimension()/2),
  119. boundary.getHalfDimension()/2));
  120. southWest = new QuadTree(new AABB(new Location(boundary.getCentre().x - boundary.getHalfDimension()/2,
  121. boundary.getCentre().y + boundary.getHalfDimension()/2),
  122. boundary.getHalfDimension()/2));
  123. southEast = new QuadTree(new AABB(new Location(boundary.getCentre().x + boundary.getHalfDimension()/2,
  124. boundary.getCentre().y + boundary.getHalfDimension()/2),
  125. boundary.getHalfDimension()/2));
  126.  
  127. for(Node n : points){
  128. northWest.insert(n);
  129. northEast.insert(n);
  130. southWest.insert(n);
  131. southEast.insert(n);
  132. }
  133. }
  134.  
  135. void draw(Graphics g, Location location, double scale){
  136. if(boundary != null) boundary.draw(g, location, scale);
  137. if(northEast != null) northEast.draw(g, location, scale);
  138. if(northWest != null) northWest.draw(g, location, scale);
  139. if(southEast != null) southEast.draw(g, location, scale);
  140. if(southWest != null) southWest.draw(g, location, scale);
  141. for(Node n : points) n.draw(g, location, scale);
  142. }
  143.  
  144.  
  145. }
  146.  
  147. class AABB {
  148. private final Location centre;
  149. private final double halfDimension;
  150.  
  151. AABB(Location centre, double halfDimension){
  152. this.centre = centre;
  153. this.halfDimension = halfDimension;
  154. }
  155.  
  156. boolean containsPoint(Location l){
  157. if(l.x < centre.x + halfDimension && l.x > centre.x - halfDimension){
  158. if(l.y < centre.y + halfDimension && l.y > centre.y - halfDimension){
  159. return true;
  160. }
  161. }
  162. return false;
  163. }
  164.  
  165. void draw(Graphics g, Location location, double scale){
  166. Location nw = new Location(centre.x - halfDimension, centre.y + halfDimension);
  167. Location se = new Location(centre.x + halfDimension, centre.y - halfDimension);
  168. Point nwPoint = nw.asPoint(location, scale);
  169. Point sePoint = se.asPoint(location, scale);
  170. g.drawRect(nwPoint.x, nwPoint.y, Math.abs(sePoint.x - nwPoint.x),Math.abs( sePoint.y - nwPoint.y));
  171. }
  172.  
  173. Location getCentre() {
  174. return centre;
  175. }
  176.  
  177. double getHalfDimension() {
  178. return halfDimension;
  179. }
  180. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement