def getSphereBloom(radius): #This function returns a dictionary of x, y, and z indices in a nested dictionary and list format #dictionary[y coordinate][x coordinate] = list of z integer values for respective x and y integer values #this is used as a lookup table when searching for candidates for nearest neighbor searches global sphereBloomValues try: return sphereBloomValues[radius] except: pass sphereKeys = GetSphereKeys(radius) sphereBloomValues[radius] = dict() bloomDict = sphereBloomValues[radius] small_set = ([0, 1]) def getValSet(a): if a > 0: a_set = set([1]) elif a < 0: a_set = set([-1]) else: a_set = set([-1, 1]) return set(a + (i1 * i2) for i1 in small_set for i2 in a_set) for x, y_dict in sphereKeys.items(): x_val_set = getValSet(x) for x_val in x_val_set: if x_val not in bloomDict: bloomDict[x_val] = dict() for y, z_list in y_dict.items(): y_val_set = getValSet(y) for x_val in x_val_set: for y_val in y_val_set: if y_val not in bloomDict[x_val]: bloomDict[x_val][y_val] = set() for z in z_list: z_val_set = getValSet(z) combolist = deepListPermutations([x_val_set, y_val_set, z_val_set]) combolist.remove([x, y, z]) for x_val, y_val, z_val in combolist: bloomDict[x_val][y_val].update([z_val]) return sphereBloomValues[radius]
def GetSphereKeys(radius): #This function generates a dictionary of spherical index keys that cover the volume between integer radius r and r + 1. #Format of returned keys will be circleDict[y][x] = list(Z Values) global sphereKeyDict try: return sphereKeyDict[radius] except: pass circle_Dict = sphereKeyDict[radius] = dict() #Define the inner and outer radii for this search sphere radius_Squared_Max = (radius + 1) ** 2 radius_Squared_Min = radius ** 2 #max_Y = radius #Now iterate through every valid value along the y axis and determine the valid range of x values for a given slice for x in range(0, radius + 1): x_set = set([x, -x]) x_squared = x ** 2 for idx in x_set: circle_Dict[idx] = dict() for y in range(0, radius + 1): y_squared = y ** 2 radius_squared_xy = x_squared + y_squared if radius_squared_xy >= radius_Squared_Max: break y_set = set([y, -y]) x_y_permutation_list = deepListPermutations([x_set, y_set]) for i_x, i_y in x_y_permutation_list: circle_Dict[i_x][i_y] = set() for z in range(0, radius + 1): z_squared = z ** 2 radius_squared_xyz = radius_squared_xy + z_squared if radius_squared_xyz < radius_Squared_Min: continue if radius_squared_xyz >= radius_Squared_Max: break z_set = set([z, -z]) #print z_set for i_x, i_y in x_y_permutation_list: circle_Dict[i_x][i_y].update(z_set) continue #key_list_A = set(circle_Dict.keys()) #key_dict_B = dict([(keyA, set(valA.keys())) for keyA, valA in circle_Dict.items()]) #for keyA, valB in circle_Dict.items(): # for keyB, listC in valB.items(): # this_list = sorted(list(listC)) # valB[keyB] = this_list #sphereKeyDict[(radius, 'KEY_A')] = key_list_A #sphereKeyDict[(radius, 'KEY_B')] = key_dict_B return sphereKeyDict[radius]