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)
Exemple #2
0
 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)
Exemple #3
0
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
Exemple #4
0
    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)
Exemple #5
0
    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)
Exemple #6
0
def circumfrence(poly):
    return sum(dist(i, j) for i, j in pairwise(poly))