Track text overlaps¶
We need to test that the words don’t overlap before plotting them. To do this we create a grid covering the plot area and zero it everywhere. Then, whenever we plot anything, we set this coverage grid to one everywhere we have plotted. We can then test if a new phrase overlaps with an existing one by checking if the coverage grid is non-zero at any point along the path of the new phrase.
# Functions to check for plot collisions
# Set up a grid covering the plot field, and flag each grid-square where something has been plotted.
# We can use this to check if a new plot element will overlap with an existing one
# (as long as we have the x,y coordinates of the plot elements in the same units as the grid).
import numpy as np
# Collision cube is a iris cube
# x, y are the coordinates of the plot element
def collision_check(collision_cube, x, y, update=True):
xc = collision_cube.coords()[1].points
xmin = np.min(xc)
xmax = np.max(xc)
yc = collision_cube.coords()[0].points
ymin = np.min(yc)
ymax = np.max(yc)
i = np.array(
(((x - xmin) / (xmax - xmin)) * collision_cube.data.shape[1]).astype(int)
)
j = np.array(
(((y - ymin) / (ymax - ymin)) * collision_cube.data.shape[0]).astype(int)
)
i[i >= collision_cube.data.shape[1] - 1] = collision_cube.data.shape[1] - 2
j[j >= collision_cube.data.shape[0] - 1] = collision_cube.data.shape[0] - 2
i[i < 1] = 1
j[j < 1] = 1
if np.sum(collision_cube.data[j, i]) != 0:
return True
else:
if update:
for k in range(-1, 2):
for l in range(-1, 2):
collision_cube.data[j + k, i + l] = 1
return False
# Shorten the x and y to remove trailing colliding points
def collision_cut(collision_cube, x, y):
xc = collision_cube.coords()[1].points
xmin = np.min(xc)
xmax = np.max(xc)
yc = collision_cube.coords()[0].points
ymin = np.min(yc)
ymax = np.max(yc)
i = np.array(
(((x - xmin) / (xmax - xmin)) * collision_cube.data.shape[1]).astype(int)
)
j = np.array(
(((y - ymin) / (ymax - ymin)) * collision_cube.data.shape[0]).astype(int)
)
i[i >= collision_cube.data.shape[1] - 1] = collision_cube.data.shape[1] - 2
j[j >= collision_cube.data.shape[0] - 1] = collision_cube.data.shape[0] - 2
i[i < 1] = 1
j[j < 1] = 1
if np.sum(collision_cube.data[j, i]) != 0:
nonzero_indices = np.nonzero(collision_cube.data[j, i])[0]
x = x[: nonzero_indices[0]]
y = y[: nonzero_indices[0]]
return x, y
else:
return x, y