|
import matplotlib.pyplot as plt |
|
import numpy as np |
|
from matplotlib.patches import Polygon |
|
from matplotlib.collections import PatchCollection |
|
|
|
|
|
def pol2car(rho, pi, xi, yi): |
|
x = rho * np.cos(pi) + xi |
|
y = rho * np.sin(pi) + yi |
|
return (x, y) |
|
|
|
def plot_isovist(isovists, show_axis=False, s=0.1, figsize=(5,5)): |
|
|
|
|
|
plt.switch_backend('agg') |
|
fig = plt.figure(figsize=figsize) |
|
points = [] |
|
res = np.pi/90 |
|
isovist = isovists |
|
for j, rho in enumerate(isovist): |
|
if rho < 1.0: |
|
pt = pol2car(rho, j*res, 0, 0) |
|
points.append(pt) |
|
x = [i[0] for i in points] |
|
y = [i[1] for i in points] |
|
ax = fig.add_subplot(111) |
|
ax.set_aspect('equal') |
|
ax.set_xlim(-1,1) |
|
ax.set_ylim(-1,1) |
|
if not show_axis: |
|
ax.axis('off') |
|
ax.scatter(x, y, s, 'black') |
|
return fig |
|
|
|
|
|
def isovist_to_cartesian_a(isovist, x, y, scale): |
|
points = [] |
|
xy = (x, y) |
|
res = np.pi/len(isovist)*2 |
|
isovist = isovist * scale |
|
for j, rho in enumerate(isovist): |
|
pt = pol2car(rho, j*res, xy[0], xy[1]) |
|
points.append(pt) |
|
points = np.stack(points) |
|
return(points) |
|
|
|
|
|
def isovist_to_cartesian_segment_a(isovist, x, y, scale, max=0.98, min = 0.1, d=0.1): |
|
points = [] |
|
segment = [] |
|
xy = (x, y) |
|
res = np.pi/len(isovist)*2 |
|
isovist = isovist * scale |
|
p_rho = isovist[-1] |
|
for j, rho in enumerate(isovist): |
|
delta = abs(p_rho-rho) |
|
if j == 0: |
|
first_rho = rho |
|
if rho < max * scale and rho > min * scale and delta < d * scale: |
|
pt = pol2car(rho, j*res, xy[0], xy[1]) |
|
segment.append(pt) |
|
else: |
|
points.append(segment) |
|
segment = [] |
|
p_rho = rho |
|
if first_rho < max * scale and first_rho > min * scale and abs(rho-first_rho)< d * scale : |
|
if len(points) > 0: |
|
segment.extend(points[0]) |
|
points[0]=segment |
|
else: |
|
points.append(segment) |
|
else: |
|
points.append(segment) |
|
segments = [] |
|
for i in range(len(points)): |
|
if len(points[i])>0: |
|
segment = np.stack(points[i]) |
|
segments.append(segment) |
|
return(segments) |
|
|
|
|
|
def index_to_loc_grid(idx, d): |
|
if idx == 0: |
|
return np.array((0., 0.), dtype=np.float32) |
|
elif idx == 1: |
|
return np.array((d, 0.), dtype=np.float32) |
|
elif idx == 2: |
|
return np.array((d, d), dtype=np.float32) |
|
elif idx == 3: |
|
return np.array((0., d), dtype=np.float32) |
|
elif idx == 4: |
|
return np.array((-d, d), dtype=np.float32) |
|
elif idx == 5: |
|
return np.array((-d, 0.), dtype=np.float32) |
|
elif idx == 6: |
|
return np.array((-d, -d), dtype=np.float32) |
|
elif idx == 7: |
|
return np.array((0., -d), dtype=np.float32) |
|
elif idx == 8: |
|
return np.array((d, -d), dtype=np.float32) |
|
else: |
|
raise NameError('Direction unknown') |
|
|
|
|
|
|
|
|
|
def seq_show_grid(locs, isovists, d=0.2, figsize=(8, 8), center=False, lim=1.5, alpha=0.02, rad=0.9, b_width=1.0, calculate_lim=False): |
|
|
|
p_loc = np.array((0, 0)) |
|
b_segments = [] |
|
b_points = [] |
|
isovists_pts = [] |
|
res = np.pi/128 |
|
cartesian_locs = [] |
|
for loc, isovist in zip(locs, isovists): |
|
rel_pos = index_to_loc_grid(loc, d) + p_loc |
|
for j, rho in enumerate(isovist): |
|
if rho < rad : |
|
pt = pol2car(rho, j*res, rel_pos[0], rel_pos[1]) |
|
b_points.append(pt) |
|
segments = isovist_to_cartesian_segment_a(isovist, rel_pos[0], rel_pos[1], 1.0) |
|
b_segments.extend(segments) |
|
isovists_pts.append(isovist_to_cartesian_a(isovist, rel_pos[0], rel_pos[1], 1.0)) |
|
cartesian_locs.append(rel_pos) |
|
p_loc = rel_pos |
|
|
|
if len(b_points) > 0: |
|
b_points = np.stack(b_points) |
|
else: |
|
b_points =[] |
|
isovists_pts = np.stack(isovists_pts) |
|
|
|
cartesian_locs = np.stack(cartesian_locs) |
|
|
|
|
|
isovist_path_width = 0.1 |
|
isovist_path_pt1 = 6.0 |
|
isovist_path_pt2 = 10.0 |
|
isovist_boundary_pt = 0.05 |
|
|
|
if center == True: |
|
|
|
bbox = get_bbox(b_points) |
|
center_pt = get_center_pts(bbox, np_array=True) |
|
b_points = [ pt - center_pt for pt in b_points] |
|
isovists_pts = [ pt - center_pt for pt in isovists_pts] |
|
b_segments = [ pt - center_pt for pt in b_segments] |
|
cartesian_locs = [ pt - center_pt for pt in cartesian_locs] |
|
|
|
|
|
if calculate_lim == True: |
|
if bbox is not None: |
|
max = np.max(np.abs(bbox)) |
|
else: |
|
max = 2.0 |
|
if max > 2.0: |
|
lim = ((max // 0.5) + 1) * 0.5 |
|
isovist_path_width *= 2.0/lim |
|
isovist_path_pt1 *= 2.0/lim |
|
isovist_path_pt2 *= 2.0/lim |
|
isovist_boundary_pt *= 2.0/lim |
|
|
|
|
|
fig, ax = plt.subplots(1,1, figsize=figsize, dpi=96) |
|
|
|
|
|
|
|
|
|
isovist_poly = [] |
|
for isovist_pts in isovists_pts: |
|
isovist_poly.append(Polygon(isovist_pts, True)) |
|
r = PatchCollection(isovist_poly) |
|
r.set_facecolor('#00aabb') |
|
r.set_edgecolor(None) |
|
r.set_alpha(alpha) |
|
ax.add_collection(r) |
|
|
|
|
|
|
|
|
|
q = PatchCollection([Polygon(cartesian_locs, False)]) |
|
q.set_facecolor('none') |
|
q.set_edgecolor('red') |
|
q.set_linewidth(isovist_path_width) |
|
|
|
ax.add_collection(q) |
|
|
|
|
|
ax.scatter([x[0] for x in cartesian_locs[:1]], [x[1] for x in cartesian_locs[:1]], s = isovist_path_pt1, c='k', marker='s') |
|
|
|
|
|
ax.scatter([x[0] for x in cartesian_locs[1:-1]], [x[1] for x in cartesian_locs[1:-1]], s = isovist_path_pt1, c='red') |
|
|
|
|
|
ax.scatter([x[0] for x in cartesian_locs[-1:]], [x[1] for x in cartesian_locs[-1:]], s = isovist_path_pt2, c='k', marker='x') |
|
|
|
|
|
edge_patches = [] |
|
for segment in b_segments: |
|
if len(segment) > 5: |
|
polygon = Polygon(segment, False) |
|
edge_patches.append(polygon) |
|
p = PatchCollection(edge_patches) |
|
p.set_facecolor('none') |
|
p.set_edgecolor('#000000') |
|
p.set_linewidth(b_width) |
|
ax.scatter([x[0] for x in b_points], [x[1] for x in b_points], s = isovist_boundary_pt, c='#000000',) |
|
|
|
|
|
|
|
|
|
ax.set_aspect('equal') |
|
lim = lim |
|
ax.set_xlim(-lim,lim) |
|
ax.set_ylim(-lim,lim) |
|
ax.set_xticks([]) |
|
ax.set_yticks([]) |
|
ax.axis('off') |
|
|
|
return fig |
|
|
|
|
|
def plot_isovist_sequence_grid(locs, isovists, figsize=(8,8), center=False, lim=1.5, alpha=0.02, rad=0.9, b_width=1.0, calculate_lim=False): |
|
fig = seq_show_grid(locs, isovists, figsize=figsize, center=center, lim=lim, alpha=alpha, rad=rad, b_width=b_width, calculate_lim=calculate_lim) |
|
|
|
fig.canvas.draw() |
|
data = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8) |
|
w, h = fig.canvas.get_width_height() |
|
im = data.reshape((int(h), int(w), -1)) |
|
im = im.transpose((2, 0, 1)) |
|
plt.close() |
|
return im |
|
|
|
def get_bbox(pts): |
|
if len(pts) > 0: |
|
if type(pts) is list: |
|
pts = np.stack(pts) |
|
bbox = np.min(pts[:, 0]), np.max(pts[:, 0]), np.min(pts[:, 1]), np.max(pts[:, 1]) |
|
return bbox |
|
else: |
|
return None |
|
|
|
def get_center_pts(bbox, np_array = False): |
|
if bbox is not None: |
|
center = 0.5*(bbox[0] + bbox[1]), 0.5*(bbox[2] + bbox[3]) |
|
if np_array: |
|
center = np.asarray(center) |
|
else: |
|
center = np.asarray([0,0]) |
|
return center |