def _concave(points, alpha): if len(points) <= 3: return points # Create delaunay triangulation. tri = DelaunayTri(points) # For each edge, count the number of faces that reference it. edge_counts = Counter() for (i, j, k) in tri.vertices: d1 = dist(tri.points[i], tri.points[j]) < alpha d2 = dist(tri.points[i], tri.points[k]) < alpha d3 = dist(tri.points[j], tri.points[k]) < alpha if (d1) and (d2) and (d3): edge_counts[tuple(sorted((i, j)))] += 1 edge_counts[tuple(sorted((i, k)))] += 1 edge_counts[tuple(sorted((j, k)))] += 1 perim_edges = defaultdict(list) # Store vertices on perimeter. for (i, j), count in edge_counts.items(): # If edge has one reference, it is on the perimeter. if count == 1: perim_edges[i].append(j) perim_edges[j].append(i) for i, vl in perim_edges.items(): if len(vl) != 2: raise InvalidHullException() start_v = list(perim_edges.keys())[0] ordered_verts = [start_v] next_v = perim_edges[start_v][0] prev_v = start_v while next_v != start_v: ordered_verts.append(next_v) if perim_edges[next_v][0] != prev_v: prev_v = next_v next_v = perim_edges[next_v][0] else: prev_v = next_v next_v = perim_edges[next_v][1] perim_edges[prev_v].remove(next_v) return ordered_verts, (tri, edge_counts)
def add_edge(self, i, j, **kwargs): length = dist(self.vertices[i], self.vertices[j]) if 'length' not in kwargs: kwargs['length'] = length if 'between_fixed' not in kwargs: kwargs['between_fixed'] = False if 'outside' not in kwargs: kwargs['outside'] = False # if 'directed' not in kwargs: # kwargs['directed'] = None if 'width' not in kwargs: kwargs['width'] = 0 super(FloorPlan, self).add_edge(i, j, weight=length, **kwargs)
def resolution_subdivide(point_list, n): new_points = [] for i, p1 in enumerate(point_list): p2 = point_list[(i + 1) % len(point_list)] new_points.append(p1) d = dist(p1, p2) num_div = int(d // n) step_x = (p2[0] - p1[0]) / num_div step_y = (p2[1] - p1[1]) / num_div for j in range(num_div - 1): new_p = ((p1[0] + step_x * (j + 1)), (p1[1] + step_y * (j + 1))) new_points.append(new_p) return new_points
def add_adjacent_room_edges(self, others): """ For rooms of the same type that also share a wall, connect with door """ for i, j, data in self.edges(data=True): # Find the two rooms that this door connects rl = self.get_edge_rooms(i, j) if len(rl) == 2 and data['width'] == 0: r1, r2 = rl c1, c2 = self.room_centers[r1], self.room_centers[r2] v1, v2 = self.vertices[c1], self.vertices[c2] if self.room_names[r1] == self.room_names[r2] and dist(v1, v2) > 4: self.add_edge(c1, c2, width=4, inner=True, outside=False) for ID1, ID2 in others: self.add_edge(self.room_centers[ID1], self.room_centers[ID2], width=4, inner=True, outside=False)
def create_door_locations(self, hallway_polygon): self.door_locations = [] room_centers = set(self.room_centers.values()) center_to_room = {c: ID for ID, c in self.room_centers.items()} for n1, n2, data in self.edges(data=True): if data['inner'] and data['width'] > 0: n1_center = n1 in room_centers n2_center = n2 in room_centers if n1_center and n2_center: # If a room-to-room door. n3, n4, d = self.get_rooms_edge(center_to_room[n1], center_to_room[n2]) v1, v2 = self.vertices[n3], self.vertices[n4] if dist(v1, v2) > 4: # Need 4 feet for door angle = (geometry.angle_between(v1, v2) + math.pi / 2 ) # % 2*pi pos = ((v1[0] + v2[0]) / 2, (v1[1] + v2[1]) / 2) self.door_locations.append((pos, angle, False)) elif n1_center and n2 in self.outside_verts or n2_center and n1 in self.outside_verts: # Door to outside. n_out, n_cent = (n2, n1) if n1_center else (n1, n2) if len(self.vert_to_room[n_cent]) == 1: v1, v2 = self.vertices[n_out], self.vertices[n_cent] angle = geometry.angle_between(v1, v2) - math.pi / 2 self.door_locations.append((v1, angle, True)) else: # A room to hallway door v1, v2 = self.vertices[n1], self.vertices[n2] for poly in hallway_polygon: for i, v3 in enumerate(poly): v4 = poly[i - 1] if geometry.segment_intersect(v1, v2, v3, v4): pos = ((v3[0] + v4[0]) / 2, (v3[1] + v4[1]) / 2) dl = (pos, geometry.angle_between(v4, v3), True) self.door_locations.append(dl)
def circumfrence(poly): return sum(dist(i, j) for i, j in pairwise(poly))