geokdtree.core

  1def kdtree(points, depth, axis_count):
  2    """
  3    Function:
  4
  5    - Build a KDTree from a list of points.
  6
  7    Required Arguments:
  8
  9    - `points`
 10        - Type: list of tuples
 11        - What: A list of points to build the KDTree from
 12
 13    Optional Arguments:
 14
 15    - `depth`
 16        - Type: int
 17        - What: The current depth in the tree (used for axis selection)
 18    - `axis_count`
 19        - Type: int
 20        - What: The number of dimensions in the points (default is 2 for 2D points)
 21
 22    Returns:
 23
 24    - The constructed KDTree as a tuple in the format (point, axis, left, right).
 25    - Where left and right are subtrees.
 26    """
 27    if not points:
 28        return 0
 29    axis = depth % axis_count
 30    points.sort(key=lambda p: p[axis])
 31    median = len(points) // 2
 32    return (
 33        points[median],
 34        axis,
 35        kdtree(points=points[:median], depth=depth + 1, axis_count=axis_count),
 36        kdtree(
 37            points=points[median + 1 :], depth=depth + 1, axis_count=axis_count
 38        ),
 39    )
 40
 41
 42def squared_distance(p1, p2, axis_count=2):
 43    """
 44    Function:
 45
 46    - Calculate the squared distance between two points.
 47
 48    Required Arguments:
 49
 50    - `p1`
 51        - Type: tuple
 52        - What: The first point
 53    - `p2`
 54        - Type: tuple
 55        - What: The second point
 56
 57    Optional Arguments:
 58
 59    - `axis_count`
 60        - Type: int
 61        - What: The number of dimensions in the points
 62        - Default: 2 (for 2D points)
 63
 64    Returns:
 65
 66    - The squared distance between the two points.
 67    """
 68    return sum([(p1[i] - p2[i]) ** 2 for i in range(axis_count)])
 69
 70
 71def closest_point(node, point, best=None, axis_count=2, best_dist=float("inf")):
 72    """
 73    Function:
 74
 75    - Find the closest point in the KDTree to a given point.
 76
 77    Required Arguments:
 78
 79    - `node`
 80        - Type: tuple
 81        - What: The node of the KDTree
 82    - `point`
 83        - Type: tuple
 84        - What: The point to find the closest point to
 85
 86    Optional Arguments:
 87
 88    - `best`
 89        - Type: tuple or None
 90        - What: The best point found so far (default is None)
 91    - `axis_count`
 92        - Type: int
 93        - What: The number of dimensions in the points (default is 2 for 2D points)
 94    - `best_dist`
 95        - Type: float
 96        - What: The best distance found so far (default is infinity)
 97
 98    Returns:
 99
100    - The closest point found in the KDTree to the given point.
101    """
102    if node == 0:
103        return best, best_dist
104    # Get the median node and its distance
105    median_node = node[0]
106    median_node_dist = squared_distance(
107        point, median_node, axis_count=axis_count
108    )
109    # Update the best point and distance if necessary
110    if best is None or median_node_dist < best_dist:
111        best = median_node
112        best_dist = median_node_dist
113    # Calculate the difference for node selection given the current axis
114    axis = node[1]
115    diff = point[axis] - median_node[axis]
116    # Choose side to search
117    close, away = (node[2], node[3]) if diff < 0 else (node[3], node[2])
118    # Search the close side first
119    best, best_dist = closest_point(
120        close,
121        point,
122        best,
123        axis_count=axis_count,
124        best_dist=best_dist,
125    )
126    # Check the other side if needed
127    if diff**2 < best_dist:
128        best, best_dist = closest_point(
129            away,
130            point,
131            best,
132            axis_count=axis_count,
133            best_dist=best_dist,
134        )
135    return best, best_dist
def kdtree(points, depth, axis_count):
 2def kdtree(points, depth, axis_count):
 3    """
 4    Function:
 5
 6    - Build a KDTree from a list of points.
 7
 8    Required Arguments:
 9
10    - `points`
11        - Type: list of tuples
12        - What: A list of points to build the KDTree from
13
14    Optional Arguments:
15
16    - `depth`
17        - Type: int
18        - What: The current depth in the tree (used for axis selection)
19    - `axis_count`
20        - Type: int
21        - What: The number of dimensions in the points (default is 2 for 2D points)
22
23    Returns:
24
25    - The constructed KDTree as a tuple in the format (point, axis, left, right).
26    - Where left and right are subtrees.
27    """
28    if not points:
29        return 0
30    axis = depth % axis_count
31    points.sort(key=lambda p: p[axis])
32    median = len(points) // 2
33    return (
34        points[median],
35        axis,
36        kdtree(points=points[:median], depth=depth + 1, axis_count=axis_count),
37        kdtree(
38            points=points[median + 1 :], depth=depth + 1, axis_count=axis_count
39        ),
40    )

Function:

  • Build a KDTree from a list of points.

Required Arguments:

  • points
    • Type: list of tuples
    • What: A list of points to build the KDTree from

Optional Arguments:

  • depth
    • Type: int
    • What: The current depth in the tree (used for axis selection)
  • axis_count
    • Type: int
    • What: The number of dimensions in the points (default is 2 for 2D points)

Returns:

  • The constructed KDTree as a tuple in the format (point, axis, left, right).
  • Where left and right are subtrees.
def squared_distance(p1, p2, axis_count=2):
43def squared_distance(p1, p2, axis_count=2):
44    """
45    Function:
46
47    - Calculate the squared distance between two points.
48
49    Required Arguments:
50
51    - `p1`
52        - Type: tuple
53        - What: The first point
54    - `p2`
55        - Type: tuple
56        - What: The second point
57
58    Optional Arguments:
59
60    - `axis_count`
61        - Type: int
62        - What: The number of dimensions in the points
63        - Default: 2 (for 2D points)
64
65    Returns:
66
67    - The squared distance between the two points.
68    """
69    return sum([(p1[i] - p2[i]) ** 2 for i in range(axis_count)])

Function:

  • Calculate the squared distance between two points.

Required Arguments:

  • p1
    • Type: tuple
    • What: The first point
  • p2
    • Type: tuple
    • What: The second point

Optional Arguments:

  • axis_count
    • Type: int
    • What: The number of dimensions in the points
    • Default: 2 (for 2D points)

Returns:

  • The squared distance between the two points.
def closest_point(node, point, best=None, axis_count=2, best_dist=inf):
 72def closest_point(node, point, best=None, axis_count=2, best_dist=float("inf")):
 73    """
 74    Function:
 75
 76    - Find the closest point in the KDTree to a given point.
 77
 78    Required Arguments:
 79
 80    - `node`
 81        - Type: tuple
 82        - What: The node of the KDTree
 83    - `point`
 84        - Type: tuple
 85        - What: The point to find the closest point to
 86
 87    Optional Arguments:
 88
 89    - `best`
 90        - Type: tuple or None
 91        - What: The best point found so far (default is None)
 92    - `axis_count`
 93        - Type: int
 94        - What: The number of dimensions in the points (default is 2 for 2D points)
 95    - `best_dist`
 96        - Type: float
 97        - What: The best distance found so far (default is infinity)
 98
 99    Returns:
100
101    - The closest point found in the KDTree to the given point.
102    """
103    if node == 0:
104        return best, best_dist
105    # Get the median node and its distance
106    median_node = node[0]
107    median_node_dist = squared_distance(
108        point, median_node, axis_count=axis_count
109    )
110    # Update the best point and distance if necessary
111    if best is None or median_node_dist < best_dist:
112        best = median_node
113        best_dist = median_node_dist
114    # Calculate the difference for node selection given the current axis
115    axis = node[1]
116    diff = point[axis] - median_node[axis]
117    # Choose side to search
118    close, away = (node[2], node[3]) if diff < 0 else (node[3], node[2])
119    # Search the close side first
120    best, best_dist = closest_point(
121        close,
122        point,
123        best,
124        axis_count=axis_count,
125        best_dist=best_dist,
126    )
127    # Check the other side if needed
128    if diff**2 < best_dist:
129        best, best_dist = closest_point(
130            away,
131            point,
132            best,
133            axis_count=axis_count,
134            best_dist=best_dist,
135        )
136    return best, best_dist

Function:

  • Find the closest point in the KDTree to a given point.

Required Arguments:

  • node
    • Type: tuple
    • What: The node of the KDTree
  • point
    • Type: tuple
    • What: The point to find the closest point to

Optional Arguments:

  • best
    • Type: tuple or None
    • What: The best point found so far (default is None)
  • axis_count
    • Type: int
    • What: The number of dimensions in the points (default is 2 for 2D points)
  • best_dist
    • Type: float
    • What: The best distance found so far (default is infinity)

Returns:

  • The closest point found in the KDTree to the given point.