mirror of https://github.com/VLSIDA/OpenRAM.git
163 lines
4.0 KiB
Python
163 lines
4.0 KiB
Python
# See LICENSE for licensing information.
|
|
#
|
|
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
|
# (acting for and on behalf of Oklahoma State University)
|
|
# All rights reserved.
|
|
#
|
|
"""
|
|
Some utility functions for sets of grid cells.
|
|
"""
|
|
|
|
import debug
|
|
import math
|
|
from direction import direction
|
|
from vector3d import vector3d
|
|
|
|
|
|
def increment_set(curset, direct):
|
|
"""
|
|
Return the cells incremented in given direction
|
|
"""
|
|
offset = direction.get_offset(direct)
|
|
|
|
newset = set()
|
|
for c in curset:
|
|
newc = c+offset
|
|
newset.add(newc)
|
|
|
|
return newset
|
|
|
|
|
|
def remove_border(curset, direct):
|
|
"""
|
|
Remove the cells on a given border.
|
|
"""
|
|
border = get_border(curset, direct)
|
|
curset.difference_update(border)
|
|
|
|
|
|
def get_upper_right(curset):
|
|
ur = None
|
|
for p in curset:
|
|
if ur == None or (p.x>=ur.x and p.y>=ur.y):
|
|
ur = p
|
|
return ur
|
|
|
|
def get_lower_left(curset):
|
|
ll = None
|
|
for p in curset:
|
|
if ll == None or (p.x<=ll.x and p.y<=ll.y):
|
|
ll = p
|
|
return ll
|
|
|
|
def get_border( curset, direct):
|
|
"""
|
|
Return the furthest cell(s) in a given direction.
|
|
"""
|
|
|
|
# find direction-most cell(s)
|
|
maxc = []
|
|
if direct==direction.NORTH:
|
|
for c in curset:
|
|
if len(maxc)==0 or c.y>maxc[0].y:
|
|
maxc = [c]
|
|
elif c.y==maxc[0].y:
|
|
maxc.append(c)
|
|
elif direct==direct.SOUTH:
|
|
for c in curset:
|
|
if len(maxc)==0 or c.y<maxc[0].y:
|
|
maxc = [c]
|
|
elif c.y==maxc[0].y:
|
|
maxc.append(c)
|
|
elif direct==direct.EAST:
|
|
for c in curset:
|
|
if len(maxc)==0 or c.x>maxc[0].x:
|
|
maxc = [c]
|
|
elif c.x==maxc[0].x:
|
|
maxc.append(c)
|
|
elif direct==direct.WEST:
|
|
for c in curset:
|
|
if len(maxc)==0 or c.x<maxc[0].x:
|
|
maxc = [c]
|
|
elif c.x==maxc[0].x:
|
|
maxc.append(c)
|
|
|
|
newset = set(maxc)
|
|
return newset
|
|
|
|
def expand_border(curset, direct):
|
|
"""
|
|
Expand the current set of sells in a given direction.
|
|
Only return the contiguous cells.
|
|
"""
|
|
border_set = get_border(curset, direct)
|
|
next_border_set = increment_set(border_set, direct)
|
|
return next_border_set
|
|
|
|
def expand_borders(curset):
|
|
"""
|
|
Return the expansions in planar directions.
|
|
"""
|
|
north_set=expand_border(curset,direction.NORTH)
|
|
south_set=expand_border(curset,direction.SOUTH)
|
|
east_set=expand_border(curset,direction.EAST)
|
|
west_set=expand_border(curset,direction.WEST)
|
|
|
|
return(north_set, east_set, south_set, west_set)
|
|
|
|
def inflate_cell(cell, distance):
|
|
"""
|
|
Expand the current cell in all directions and return the set.
|
|
"""
|
|
newset = set(cell)
|
|
|
|
if distance==0:
|
|
return(newset)
|
|
|
|
# recursively call this based on the distance
|
|
for offset in direction.all_offsets():
|
|
# FIXME: If distance is large this will be inefficient, but it is like 1 or 2
|
|
newset.update(inflate_cell(cell+offset,distance-1))
|
|
|
|
return newset
|
|
|
|
def inflate_set(curset, distance):
|
|
"""
|
|
Expand the set in all directions by the given number of grids.
|
|
"""
|
|
if distance<=0:
|
|
return curset
|
|
|
|
newset = curset.copy()
|
|
# Add all my neighbors
|
|
for c in curset:
|
|
newset.update(direction.all_neighbors(c))
|
|
# Recurse with less depth
|
|
return inflate_set(newset,distance-1)
|
|
|
|
def flatten_set(curset):
|
|
"""
|
|
Flatten until we have a set of vector3d objects.
|
|
"""
|
|
newset = set()
|
|
for c in curset:
|
|
if isinstance(c,vector3d):
|
|
newset.add(c)
|
|
else:
|
|
newset.update(flatten_set(c))
|
|
return newset
|
|
|
|
|
|
|
|
def distance_set(coord, curset):
|
|
"""
|
|
Return the distance from a coordinate to any item in the set
|
|
"""
|
|
min_dist = math.inf
|
|
for c in curset:
|
|
min_dist = min(coord.euclidean_distance(c), min_dist)
|
|
|
|
return min_dist
|
|
|