【python】通行网格地图四叉树化
受到Leecode 427题的启发,427. 建立四叉树
想将由0和1组成的网格地图绘制为四叉树地图,0表示可通行网格,1表示不可通行网格。
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np
from matplotlib import colors
class Node:
def __init__(self, x0, y0, w, h, data):
self.x0 = x0
self.y0 = y0
self.width = w
self.height = h
self.data = data
self.children = []
self.passable = np.sum(data == 1) / (w * h) <= 0.9 # 障碍物比例<= 0.2 可通行
class QuadTree:
def __init__(self, x, y, w, h, data):
self.root = Node(x, y, w, h, data)
self.root.passable = True
if self.root.passable:
self.subdivide(self.root)
def subdivide(self, node):
x, y, w, h = node.x0, node.y0, node.width // 2, node.height // 2
# Divide the node's data into quadrants
data_quadrants = [
node.data[0:h, 0:w],
node.data[h: node.height, 0:w],
node.data[0:h, w:node.width],
node.data[h:node.height, w:node.width]
]
for i, data in enumerate(data_quadrants):
width = w
height = h
if (i // 2):
width = node.width - w
if (i % 2):
height = node.height - h
child = Node(x + (i // 2) * w, y + (i % 2) * h, width, height, data)
node.children.append(child)
if len(np.unique(data)) > 1 and w > 1 and h > 1:
self.subdivide(child)
def draw(self, ax):
def _draw(node):
color = 'black' if not node.passable else 'white'
# ax.add_patch(patches.Rectangle((node.x0, node.y0), node.width, node.height, facecolor=color, edgecolor='black'))
ax.add_patch(
patches.Rectangle((node.x0, node.y0), node.width, node.height, facecolor=color, edgecolor='black'))
for child in node.children:
if child is not None:
_draw(child)
_draw(self.root)
def print_leaves(self, node=None):
if node is None:
node = self.root
if all(child is None for child in node.children):
print(
f"Leaf Node: x={node.x0}, y={node.y0}, width={node.width}, height={node.height}, passable={node.passable}")
else:
for child in node.children:
if child is not None:
self.print_leaves(child)
# Create a 32x32 grid map with random obstacles
map_data = np.loadtxt("./map_txt/Random_32x32_.2.txt")
width, height = map_data.shape
# Create a quadtree
qt = QuadTree(0, 0, width, height, map_data)
cmap = colors.ListedColormap(['white', 'black', ])
# Draw the original map
fig, axs = plt.subplots(1, 2, figsize=(10, 5))
axs[0].imshow(map_data, cmap=cmap, origin='lower')
axs[0].set_title('Original Map')
# Draw the quadtree
axs[1].set_xlim(0, width)
axs[1].set_ylim(0, height)
qt.draw(axs[1])
axs[1].set_title('Quadtree Map')
plt.show()
运行结果