def connect(self, nodelist, threshold=15.0): """ Connect the wire with nodes. For each end of the wire, check the distance between the end position and every node's vertex position. If the distance is under some threshold, consider this node is a neighbour and store it in a list. After checking with all the nodes in the nodelist, choose the node with least distance as the connection of this end. Finally in the connection attribute, each element will contain the connected node, the angle between the node and the end, and which end fo the wire this connection belongs to. Args: nodelist (list): A list of node objects including dots and morphisms, threshold (float): The threshold value of distance. Raise: Exception: The neighbour list could be blank if the wire doesn't connect with any nodes. """ for i, end in enumerate(self.ends): neighbours = [] for node in nodelist: distlist = [sp.dist(end, point) for point in node.pointlist] mindist = min(distlist) if mindist < threshold: neighbours.append([node, mindist]) try: mindist_idx = np.argmin(neighbours, axis=0)[ 1] # The index of the min distance in the neighbours list. connectnode = neighbours[mindist_idx][0] angle = self.calculateAngle(end, connectnode.centre) self.connections.append([connectnode, angle, i, 0]) yield [connectnode, angle, i, 0] except: pass
def get_ref_centre(nodelist): """Choose a node as the diagram centre and find the unit distance. Find the shortest distance between two nodes and use it as the unit distance of the diagram grid. Choose one of these two nodes as the diagram centre. Args: nodelist (list): A list of nodes Returns: The absolute position of the centre node and the unit distance of the diagram. """ centres = [node.centre for node in nodelist] min_d = sp.dist(centres[0], centres[1]) min_p0, min_p1 = centres[0], centres[1] for p0, p1 in itertools.combinations(centres, 2): d = sp.dist(p0, p1) if d < min_d: min_d = d min_p0, min_p1 = p0, p1 min_x = abs(min_p0[0] - min_p1[0]) min_y = abs(min_p0[1] - min_p1[1]) unit_d = max(min_x, min_y) return [min_p0, unit_d]
def matchPaths(path1, path2, threshold=10.0): """Get the match type of two paths. Each path has two ends. Calculate the distance of these ends. If some distance is lower than a threshold, then we consider these two path could be grouped together. The match type is how these two paths connected. Args: path1 (obj): The first path. Path2 (obj): The second path. threhold (float): The threshold number of distance. Returns: A list. The first element is the two paths. The second element is the matchtype. """ matchtype = [] d0 = sp.dist(path1.end1, path2.end1) d1 = sp.dist(path1.end1, path2.end2) d2 = sp.dist(path1.end2, path2.end1) d3 = sp.dist(path1.end2, path2.end2) for i, d in enumerate([d0, d1, d2, d3]): if d < threshold: matchtype.append(i) return [[path1, path2], matchtype]
def orientation(self): """Calculate the orientation of the polygon. This is a function for morphism nodes. Calculate the distance between the farthest vertex and the centroid. Divide the coordinate into 8 parts by x axis, y axis and two diagonals and use these 8 direction as the morphism orientation. Returns: An int range from 0 to 7. """ distances = [ sp.dist(self.centroid, boundpoint) for boundpoint in self.boundpoints ] cornerpoint = self.boundpoints[np.argmax(distances)] [dx, dy] = np.array(self.centroid) - np.array(cornerpoint) if dx < 0 and dy < 0: return 'origin' elif dx >= 0 and dy < 0: return 'hflip' elif dx > 0 and dy > 0: return 'hvflip' else: return 'vflip'