[020] K-dimension Tree
[020] K-dimension Tree
[42h] Binary Tree Algorithm for Quick Searching
[Jan 24] 02h - Nearest Neighbor Search [Jan 25] 06h - 8 Letter Seed / Naive Search [Jan 26] 05h - Binary Search Tree [Jan 27] 11h - Tree Data Structures [Jan 28] 04h - K-d Tree Search [Jan 29] 04h - K-d Tree Review [Jan 30] 04h - K-d Tree UI [Jan 31] 05h - K-d Tree Upload [Feb 02] 01h - K-d Tree Fix - learned how to generate and load RNG seed - K-d Tree is good searching static positions - requires to be rebuild if things moved - building is expensive due to sorting and finding the middle - it's a trade-off based on the number of points - naive searching is quicker in lower number of points - K-d Tree is better in higher number of points Pseudocode: # youtu.be/Glp7THUpGow var _root_node: TreeNode var _nearest_node: TreeNode var _k_dimention: int = 2 class TreeNode: var data: Vector2 var parent: TreeNode var left: TreeNode var right: TreeNode func _ready() -> void: _root_node = _build_kd_tree_helper(_root_node, _tree_node_array) _nearest_node = _nearest_neighbor(_root_node, get_global_mouse_position()) func _build_kd_tree_helper(parent: TreeNode, tree_node_array: Array[TreeNode], depth: int = 0) -> TreeNode: var current_axis: int = depth % _k_dimention var sorted_array: Array[TreeNode] if current_axis == 0: sorted_array = _array_insertion_sort_x(tree_node_array) elif current_axis == 1: sorted_array = _array_insertion_sort_y(tree_node_array) var middle_index: int = (int)(sorted_array.size() / 2) var left_array: Array[TreeNode] = sorted_array.slice(0, middle_index) var right_array: Array[TreeNode] = sorted_array.slice(middle_index + 1) if parent != null: sorted_array[middle_index].parent = parent if left_array.size() != 0: sorted_array[middle_index].left = _build_kd_tree_helper(sorted_array[middle_index], left_array, depth + 1) if right_array.size() != 0: sorted_array[middle_index].right = _build_kd_tree_helper(sorted_array[middle_index], right_array, depth + 1) return sorted_array[middle_index] func _array_insertion_sort_x(tree_node_array: Array[TreeNode]) -> Array[TreeNode]: # insertion sort var index_i: int = 1 var index_j: int = 0 var temp: TreeNode for i in tree_node_array.size() - 1: # loop, skip first item temp = tree_node_array[index_i] index_j = index_i - 1 while index_j >= 0 && tree_node_array[index_j].data.x > temp.data.x: tree_node_array[index_j + 1] = tree_node_array[index_j] index_j -= 1 tree_node_array[index_j + 1] = temp index_i += 1 return tree_node_array func _array_insertion_sort_y(tree_node_array: Array[TreeNode]) -> Array[TreeNode]: # insertion sort var index_i: int = 1 var index_j: int = 0 var temp: TreeNode for i in tree_node_array.size() - 1: # loop, skip first item temp = tree_node_array[index_i] index_j = index_i - 1 while index_j >= 0 && tree_node_array[index_j].data.y > temp.data.y: tree_node_array[index_j + 1] = tree_node_array[index_j] index_j -= 1 tree_node_array[index_j + 1] = temp index_i += 1 return tree_node_array func _nearest_neighbor(parent: TreeNode, target: Vector2, depth: int) -> TreeNode: if parent == null: return null var current_axis: int = depth % _k_dimention var next_node: TreeNode var other_node: TreeNode if current_axis == 0: # x-axis if target.x < parent.data.x: next_node = parent.left other_node = parent.right else: next_node = parent.right other_node = parent.left else: # y-axis if target.y < parent.data.y: next_node = parent.left other_node = parent.right else: next_node = parent.right other_node = parent.left var temp: TreeNode = _nearest_neighbor(next_node, target, depth + 1) var best: TreeNode = _closer_node(target, temp, parent) var best_distance: float = target.distance_to(best) var parent_distance: float if current_axis == 0: parent_distance = absf(target.x - parent.data.x) else: parent_distance = absf(target.y - parent.data.y) if best_distance >= parent_distance * parent_distance: temp = _nearest_neighbor(other_node, target, depth + 1) best = _closer_node(target, temp, parent) return best func _closer_node(target: Vector2, node_a: TreeNode, node_b: TreeNode) -> TreeNode: if node_a == null: return node_b if node_b == null: return node_a var distance_a: float = target.distance_to(node_a) var distance_b: float = target.distance_to(node_b) if distance_a < distance_b: return node_a else: return node_b
Status | Released |
Platforms | HTML5 |
Author | QuietGodot |
Made with | Godot |
Leave a comment
Log in with itch.io to leave a comment.