-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvisualizer.py
More file actions
100 lines (88 loc) · 3.45 KB
/
visualizer.py
File metadata and controls
100 lines (88 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import matplotlib
matplotlib.use('Agg') # no pop-up window
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import numpy as np
from grid import FREE, OBSTACLE, START, GOAL
# ── emoji mapping ─────────────────────────────────────────────
EMOJI = {
FREE: '⬜',
OBSTACLE: '🌳',
START: '🚗',
GOAL: '🏁',
'explored': '🟦',
'path': '🟨',
}
# ── colour mapping (RGB 0-1) ──────────────────────────────────
COLOR = {
FREE: (1.00, 1.00, 1.00),
OBSTACLE: (0.25, 0.25, 0.25),
START: (0.20, 0.80, 0.20),
GOAL: (0.90, 0.20, 0.20),
'explored': (0.60, 0.80, 1.00),
'path': (1.00, 0.85, 0.10),
}
# ── terminal emoji print ──────────────────────────────────────
def print_emoji_grid(grid, explored=(), path=()):
explored = set(explored)
path = set(path)
for r in range(grid.rows):
row = ''
for c in range(grid.cols):
pos = (r, c)
if pos == grid.start:
row += EMOJI[START]
elif pos == grid.goal:
row += EMOJI[GOAL]
elif pos in path:
row += EMOJI['path']
elif pos in explored:
row += EMOJI['explored']
elif grid.is_obstacle(r, c):
row += EMOJI[OBSTACLE]
else:
row += EMOJI[FREE]
print(row)
print()
# ── matplotlib frame renderer ─────────────────────────────────
def render_frame(grid, explored, path, save_path, title='A* Path Planning'):
explored = set(explored)
path = set(path)
rows, cols = grid.rows, grid.cols
data = np.ones((rows, cols, 3))
for r in range(rows):
for c in range(cols):
pos = (r, c)
if pos == grid.start:
data[r, c] = COLOR[START]
elif pos == grid.goal:
data[r, c] = COLOR[GOAL]
elif pos in path:
data[r, c] = COLOR['path']
elif pos in explored:
data[r, c] = COLOR['explored']
elif grid.is_obstacle(r, c):
data[r, c] = COLOR[OBSTACLE]
# else FREE → already white
fig, ax = plt.subplots(figsize=(5, 5))
ax.imshow(data, origin='upper', interpolation='nearest')
# grid lines
ax.set_xticks(np.arange(-0.5, cols, 1), minor=True)
ax.set_yticks(np.arange(-0.5, rows, 1), minor=True)
ax.grid(which='minor', color='gray', linewidth=0.5)
ax.tick_params(which='both', bottom=False, left=False,
labelbottom=False, labelleft=False)
ax.set_title(title, fontsize=11)
# legend
legend_items = [
mpatches.Patch(color=COLOR[START], label='Start'),
mpatches.Patch(color=COLOR[GOAL], label='Goal'),
mpatches.Patch(color=COLOR[OBSTACLE], label='Obstacle'),
mpatches.Patch(color=COLOR['explored'], label='Explored'),
mpatches.Patch(color=COLOR['path'], label='Path'),
]
ax.legend(handles=legend_items, loc='upper right',
fontsize=7, framealpha=0.8)
plt.tight_layout()
plt.savefig(save_path, dpi=80)
plt.close(fig)