Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions source/campo/op_experimental/move_closest_dest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import numpy as np
import random
from pathlib import Path
import sys
import campo
from sklearn.neighbors import NearestNeighbors
import math
import matplotlib.pyplot as plt

def find_closest_dest (field_pset, boolean_fieldprop, point_pset_orX, pidx_orY):
''' find closest point complying to the boolean fieldprop, from a point
if point_pset and pidx is inavailable, point_pset may be a xcoordinate and pidx may be the ycoordinate
of the point of which a new destination needs to be found
parameters:
boolean_fieldprop: a boolean map, either as a field-agent property or as a numpy array, describing with 1s the destination
poi'''
if isinstance(point_pset_orX, campo.propertyset.PropertySet):
point_x = point_pset_orX.space_domain.xcoord [pidx_orY]
point_y = point_pset_orX.space_domain.ycoord [pidx_orY]
elif isinstance (point_pset_orX, (np.int64, int, np.float64, float)):
point_x = point_pset_orX
point_y = pidx_orY
else:
raise TypeError('make sure third and fourth argument give enough information to substract coordinates, by being a propertyset or integers describing coordinates')

for fidx,area in enumerate(field_pset.space_domain):
# Get bounding box of field
nr_cols = int(area[5]) #
minX = area [0]
minY = area [1]
resolution = math.fabs(area[2] - minX) / nr_cols

ix = math.floor((point_x - minX) / resolution) # needs to be rouned down since we define it by the minimum and therefore lower border
iy = math.floor((point_y - minY) / resolution)
point = np.array([iy, ix]) # in indexes as in the field , with first row = y, column = x

# field proerty may be of type property or the values of such a property
if isinstance (boolean_fieldprop, campo.property.Property):
field_array = np.flip(boolean_fieldprop.values()[0])

elif isinstance (boolean_fieldprop, np.ndarray):
field_array = np.flip (boolean_fieldprop, axis=0)
else:
raise TypeError ('boolean_fieldprop needs to be of type campo.property or of a numpy array with same dimensions as field property values')
boolean_array = np.where (field_array == 0, 0, 1) # in case it was not boolean yet
# Generate a list with all potential destinations, also accommodates for a clump field in which all possible destinations are not 0
potential_dest_idxs = np.argwhere (boolean_array)

# Convert indices to a 2D array of points
# Use NearestNeighbors to find the closest '1'
nbrs = NearestNeighbors (n_neighbors= 1, algorithm='ball_tree').fit(potential_dest_idxs)
distances, indices = nbrs.kneighbors([point])
# these indices are based on the flipped point, so the terugvertaling naar punt gaat dan niet meer, omdat het nu dus een geflipt punt is
# the flip operation however has to be performed, otherwise the topological relation is not correctly established
new_yidx, new_xidx= tuple(potential_dest_idxs[indices[0][0]]) # but now what do these indices mean on the non flipped array
xcoord = new_xidx*resolution + minX
ycoord = new_yidx*resolution + minY
travel_distance = float(distances [0][0])*resolution
return xcoord, ycoord, travel_distance

def move_directed (field_pset, dest_boolean_fieldprop, boolean_clump_fieldprop, point_pset, pidx):
'''boolean_clump_fieldprop = the current clump as a boolean map (is all available area for the current location of the pointagent)'''
# Find closest spawning area pixel destination
closest_destX, closest_destY, dist1 = find_closest_dest(field_pset, dest_boolean_fieldprop, point_pset, pidx)
# from this pixel, find closest clump pixel , which will be in the right direction
xcoord, ycoord, dist2 = find_closest_dest(field_pset, boolean_clump_fieldprop, closest_destX, closest_destY)

initialX = point_pset.space_domain.xcoord[pidx]
initialY = point_pset.space_domain.ycoord[pidx]
travel_distance = np.sqrt((xcoord - initialX)**2 +(ycoord - initialY)**2)
return xcoord, ycoord, travel_distance