import math import numpy as np from src import plot def convex_hull(G): # gift wrapping algorithm pos = G.vp["pos"] x = [] y = [] for v in G.vertices(): # print(pos[v]) ver = pos[v] x.append(ver[0]) y.append(ver[1]) min_x = min(x) min_y = min(y) max_x = max(x) max_y = max(y) pos = np.stack((np.array(x), np.array(y)), axis=-1) convex_hull = [] hull_point = np.array([min_x,pos[np.argmin(x)][1]]) convex_hull.append(hull_point) endpoint = None i = 0 while not plot.Vector.eql(endpoint, convex_hull[0]): endpoint = pos[0] for point in pos: if plot.Vector.eql(endpoint, hull_point) or plot.Vector.cross_z(plot.Vector.vec(convex_hull[i], endpoint), plot.Vector.vec(convex_hull[i], point)) < 0: endpoint = point i += 1 hull_point = endpoint convex_hull.append(hull_point) return convex_hull def correct(G, centrality, m_opt, c0_opt, b_opt): """ Correct a given centrality through the calculated model. @param pos [Array-2d] Positions of points (i.e. `g.vp["pos"].get_2d_array()`) @param centrality [VertexPropertyMap] Result of a centrality calculation of `graph-tool` on graph G @param m_opt [Float] Model m value (slope of linear function) @param c0_opt [Float] Model c0 value (offset of linear function) @param b_opt [Float] Model b value (intersection point) @return [VertexPropertyMap] Corrected centrality values based on @param centrality """ corrected_metric = centrality pos = G.vp["pos"] x = [] y = [] for v in G.vertices(): # print(pos[v]) ver = pos[v] x.append(ver[0]) y.append(ver[1]) keys = iter(centrality.a) hull = convex_hull(G) points = np.stack((np.array(x), np.array(y)), axis=-1) for point in pos: min_distance = math.inf key = next(keys) for edge in hull: vector = plot.Vector.vec(point, edge) distance = plot.Vector.vec_len(vector) if distance < min_distance: min_distance = distance if min_distance <= b_opt: # requires correction value = centrality[key] delta = (m_opt * b_opt) - (m_opt * min_distance) corrected_metric[key] = value + delta else: # unaffected by boundary corrected_metric[key] = centrality[key] return corrected_metric