-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmap_utils.py
More file actions
151 lines (111 loc) · 4.01 KB
/
map_utils.py
File metadata and controls
151 lines (111 loc) · 4.01 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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import numpy as np
from tree_builder import Cell
def update_map(map: np.ndarray, observation: set):
for obs in observation:
map[obs[0], obs[1]] = Cell.OBSERVED.value
def segment_map(fragment, copies):
"""
Creates a dictionary mapping each index pair to its corresponding copy.
Only indices inside a copy appear in the keys.
"""
segmentation = {}
height, width = len(fragment), len(fragment[0])
for copy in copies:
tl_i, tl_j = copy["top left"]
if copy["rotations"] % 2 == 1:
cp_height = width
cp_width = height
else:
cp_height = height
cp_width = width
for del_i in range(cp_height):
for del_j in range(cp_width):
i, j = tl_i + del_i, tl_j + del_j
# map del_i, del_j to offsets in original fragment
mask = np.zeros((cp_height, cp_width))
mask[del_i,del_j] = 1
mask = np.rot90(mask, -copy["rotations"])
if copy["reflect"]:
mask = np.flip(mask, 1)
base_i,base_j = np.where(mask)
base_i,base_j = int(base_i[0]),int(base_j[0])
segmentation[(i,j)] = (copy, base_i, base_j)
return segmentation
def fragment_to_map_coords(fragment, copy):
"""
Returns a dictionary mapping every index of the fragment
to its global indices in the map. This is essentially an inverse
of segment_map.
"""
height, width = len(fragment),len(fragment[0])
indices = np.indices((height, width))
if copy["reflect"]:
# the first dimension is now the index type,
# so we flip one dimension later than normal.
indices = np.flip(indices, 2)
indices = np.rot90(indices, copy["rotations"], (1,2))
frag_to_map = {}
tl_i, tl_j = copy["top left"]
for i in range(indices.shape[1]):
for j in range(indices.shape[2]):
frag_to_map[(int(indices[0,i,j]), int(indices[1,i,j]))] = (i+tl_i, j+tl_j)
return frag_to_map
def get_observation(map: list[list[int, int]], pos: tuple[int, int]):
"""
Returns a set of coordinates of all new rooms observed from the current pos
"""
observations = set()
(r, c) = pos
# 1st quadrant
c_left = 0
for r_ in range(r, -1, -1):
columns = []
for c_ in range(c, c_left-1, -1):
if map[r_][c_] == Cell.WALL.value:
break
columns.append(c_)
if map[r_][c_] == Cell.UNOBSERVED.value:
observations.add((r_, c_))
if not columns:
break
c_left = columns[-1]
# 2nd quadrant
c_right = map.shape[1] - 1
for r_ in range(r, -1, -1):
columns = []
for c_ in range(c, c_right+1):
if map[r_][c_] == Cell.WALL.value:
break
columns.append(c_)
if map[r_][c_] == Cell.UNOBSERVED.value:
observations.add((r_, c_))
if not columns:
break
c_right = columns[-1]
# 3rd quadrant
c_left = 0
for r_ in range(r, map.shape[0]):
columns = []
for c_ in range(c, c_left-1, -1):
if map[r_][c_] == Cell.WALL.value:
break
columns.append(c_)
if map[r_][c_] == Cell.UNOBSERVED.value:
observations.add((r_, c_))
if not columns:
break
c_left = columns[-1]
# 4th quadrant
c_right = map.shape[1] - 1
for r_ in range(r, map.shape[0]):
columns = []
for c_ in range(c, c_right+1):
if map[r_][c_] == Cell.WALL.value:
break
columns.append(c_)
if map[r_][c_] == Cell.UNOBSERVED.value:
observations.add((r_, c_))
if not columns:
break
c_right = columns[-1]
return observations