WIP: Find nearest neighbor algorithm
This commit is contained in:
		
							parent
							
								
									db3f5d9407
								
							
						
					
					
						commit
						ccd46d07a8
					
				
							
								
								
									
										88
									
								
								quadtree.py
									
									
									
									
									
								
							
							
						
						
									
										88
									
								
								quadtree.py
									
									
									
									
									
								
							| @ -24,16 +24,18 @@ class Ball: | |||||||
| @dataclass | @dataclass | ||||||
| class QNode: | class QNode: | ||||||
|     aabb: Rect |     aabb: Rect | ||||||
|     points: List = field(default_factory=list) |     points: List[Tuple[float, float]] = field(default_factory=list) | ||||||
| 
 | 
 | ||||||
| @dataclass | @dataclass | ||||||
| class Quadtree: | class Quadtree: | ||||||
|     node: QNode |     node: QNode | ||||||
|     subdivided = False |     subdivided = False | ||||||
|  |     direction: str = '' | ||||||
|     nw: Optional['Quadtree'] = None |     nw: Optional['Quadtree'] = None | ||||||
|     ne: Optional['Quadtree'] = None |     ne: Optional['Quadtree'] = None | ||||||
|     sw: Optional['Quadtree'] = None |     sw: Optional['Quadtree'] = None | ||||||
|     se: Optional['Quadtree'] = None |     se: Optional['Quadtree'] = None | ||||||
|  |     parent: Optional['Quadtree'] = None | ||||||
| 
 | 
 | ||||||
| @dataclass | @dataclass | ||||||
| class World: | class World: | ||||||
| @ -51,10 +53,10 @@ def qt_split(qt: Quadtree): | |||||||
|     ne = Rect(x + hw, y     , hw, hh) |     ne = Rect(x + hw, y     , hw, hh) | ||||||
|     sw = Rect(x     , y + hh, hw, hh) |     sw = Rect(x     , y + hh, hw, hh) | ||||||
|     se = Rect(x + hw, y + hh, hw, hh) |     se = Rect(x + hw, y + hh, hw, hh) | ||||||
|     qt.nw = Quadtree(QNode(nw)) |     qt.nw = Quadtree(QNode(nw), parent=qt, direction='NW') | ||||||
|     qt.ne = Quadtree(QNode(ne)) |     qt.ne = Quadtree(QNode(ne), parent=qt, direction='NE') | ||||||
|     qt.sw = Quadtree(QNode(sw)) |     qt.sw = Quadtree(QNode(sw), parent=qt, direction='SW') | ||||||
|     qt.se = Quadtree(QNode(se)) |     qt.se = Quadtree(QNode(se), parent=qt, direction='SE') | ||||||
|     qt.subdivided = True |     qt.subdivided = True | ||||||
|      |      | ||||||
| def qt_insert(qt: Quadtree, p): | def qt_insert(qt: Quadtree, p): | ||||||
| @ -82,6 +84,82 @@ def qt_insert(qt: Quadtree, p): | |||||||
|         qt.node.points.append(p) |         qt.node.points.append(p) | ||||||
|         return True |         return True | ||||||
| 
 | 
 | ||||||
|  | def qt_find_nearest_point(qt: Quadtree, point) -> Tuple[float, float]: | ||||||
|  |     closest_point = None | ||||||
|  |     closest_dist = None | ||||||
|  |     last_direction = None | ||||||
|  |     containing_qt = qt | ||||||
|  |     # Find the containing subnode | ||||||
|  |     while containing_qt.subdivided: | ||||||
|  |         if RL.check_collision_point_rec(point, qt.nw.node.aabb): | ||||||
|  |             containing_qt = qt.nw | ||||||
|  |         elif RL.check_collision_point_rec(point, qt.ne.node.aabb): | ||||||
|  |             containing_qt = qt.ne | ||||||
|  |         elif RL.check_collision_point_rec(point, qt.sw.node.aabb): | ||||||
|  |             containing_qt = qt.sw | ||||||
|  |         elif RL.check_collision_point_rec(point, qt.se.node.aabb): | ||||||
|  |             containing_qt = qt.se | ||||||
|  |      | ||||||
|  |     while containing_qt.parent is not None: | ||||||
|  |         # If it's greater than 1, then we  have a point inside we can compare to | ||||||
|  |         if len(containing_qt.node.points) > 1: | ||||||
|  |             for p in qt.node.points: | ||||||
|  |                 if p == point: | ||||||
|  |                     continue | ||||||
|  |                 if closest_dist is None or RL.vector_2distance(Vec2(*point), Vec2(*p)) < closest_dist: | ||||||
|  |                     closest_point = p | ||||||
|  |             last_direction = containing_qt.direction | ||||||
|  |             containing_qt = containing_qt.parent | ||||||
|  |         else: | ||||||
|  |             # If there aren't any other points in here, then we can't create a | ||||||
|  |             # closest_point or a closest_dist. We would have to handle that later on | ||||||
|  |             if not containing_qt.subdivided: | ||||||
|  |                 last_direction = containing_qt.direction | ||||||
|  |                 containing_qt = containing_qt.parent | ||||||
|  |             else: | ||||||
|  |                 # def search_for_nearest(child_qt: Quadtree): | ||||||
|  |                 # We have to generalize this code, most likely, because it feels like | ||||||
|  |                 # we have to do this recursively until we have exhausted all quadrants | ||||||
|  |                      | ||||||
|  |                 px, py = point | ||||||
|  |                 # This is where we check the surrounding nodes and try to discard nodes | ||||||
|  |                 if last_direction == 'NW': | ||||||
|  |                     xse, yse = containing_qt.se.node.aabb.x, containing_qt.se.node.aabb.y | ||||||
|  | 
 | ||||||
|  |                     ne_dist = containing_qt.ne.node.aabb.x - px | ||||||
|  |                     if ne_dist < closest_dist: | ||||||
|  |                         closest_dist = True | ||||||
|  |                         # Now we have to search inside, but we would have to do recursively | ||||||
|  |                         pass | ||||||
|  |                     sw_dist = containing_qt.sw.node.aabb.y - py | ||||||
|  |                     se_dist = RL.vector_2distance(Vec2(*point), Vec2(xse, yse))  | ||||||
|  |                     assert se_dist >= 0, 'ITS LESS THAN 0!!!!' | ||||||
|  |                 if last_direction == 'NE': | ||||||
|  |                     xsw, ysw = containing_qt.sw.node.aabb.x, containing_qt.sw.node.aabb.y | ||||||
|  | 
 | ||||||
|  |                     nw_dist = px - containing_qt.nw.node.aabb.x | ||||||
|  |                     sw_dist = RL.vector_2distance(Vec2(xsw, ysw), Vec2(*point)) | ||||||
|  |                     assert sw_dist >= 0, 'ITS LESS THAN 0!!!!' | ||||||
|  |                     se_dist = containing_qt.se.node.aabb.y - py | ||||||
|  |                 if last_direction == 'SW': | ||||||
|  |                     xne, yne = containing_qt.ne.node.aabb.x, containing_qt.ne.node.aabb.y | ||||||
|  | 
 | ||||||
|  |                     nw_dist = px - containing_qt.nw.node.aabb.x | ||||||
|  |                     ne_dist = RL.vector_2distance(Vec2(xne, yne), Vec2(*point)) | ||||||
|  |                     assert ne_dist >= 0, 'ITS LESS THAN 0!!!!' | ||||||
|  |                     se_dist = containing_qt.se.node.aabb.x - px | ||||||
|  |                 if last_direction == 'SE': | ||||||
|  |                     xnw, ynw = containing_qt.nw.node.aabb.x, containing_qt.nw.node.aabb.y | ||||||
|  | 
 | ||||||
|  |                     nw_dist = RL.vector_2distance(Vec2(xnw, ynw), Vec2(*point)) | ||||||
|  |                     ne_dist = py - containing_qt.nw.node.aabb.y | ||||||
|  |                     assert ne_dist >= 0, 'ITS LESS THAN 0!!!!' | ||||||
|  |                     sw_dist = px - containing_qt.se.node.aabb.x | ||||||
|  | 
 | ||||||
|  |                 last_direction = containing_qt.direction | ||||||
|  |                 containing_qt = containing_qt.parent | ||||||
|  |                  | ||||||
|  | 
 | ||||||
| def construct_quadtree(points): | def construct_quadtree(points): | ||||||
|     root_node = QNode(Rect(0, 0, screen_width, screen_height)) |     root_node = QNode(Rect(0, 0, screen_width, screen_height)) | ||||||
|     qt = Quadtree(root_node) |     qt = Quadtree(root_node) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user