def divide_into_apartments(P, level, corridor): common, splits = geometry.split_overlapping_rectangles(level, corridor) center_rects = [split for split in splits if common.is_touching(split)] corner_rects = list(set(splits).difference(set(center_rects))) corner_center_map = {} for corner in corner_rects: for center in center_rects: if corner.is_touching(center): corner_center_map.setdefault(corner,[]).append(center) lumps ={} for center in center_rects: lumps.setdefault(center,[]) for corner, centers in corner_center_map.iteritems(): center = P.pick(centers) lumps[center].append(corner) rm = geometry.RectangleMerger() apartments = [] for center, lump in lumps.iteritems(): lump.append(center) polys = rm.merge(lump) ortho_poly = polys[0] data = ortho_poly.SplitData(ortho_poly) apartment = ortho_poly._get_rectangles(data).pop() apartments.append(((apartment.min_x(),apartment.min_y()),(apartment.max_x(),apartment.max_y()))) return apartments
def skyapt_plan(self, sector_length, sector_width, road_gap, plan): chooser = lambda min, max: self.picker.pick((min,max)) if plan == 'sky': height_width_ratio = 8. build_height = self.picker.pick((100,300)) build_width = build_height/height_width_ratio build_length = self.picker.pick((build_width, build_width*2)) else: build_length = self.picker.pick((50,70)) build_width = self.picker.pick((50,70)) build_height = chooser(1,2) build_length = int(round(build_length)) build_width = int(round(build_width)) x = sector_length - build_length y = sector_width - build_width x = int(round(x)) y = int(round(y)) if x <= 5 or y <= 5: return None, None x = chooser(5, x) y = chooser(5, y) build_origin = (x, y, 0) sky_apt = None if plan == 'sky': self.subgen('building', build_origin, build_length, build_width, height=build_height) sky_apt = build_origin else: a,b,c = build_origin base = draw.makePolygon([build_origin,(a+build_length,b,0), (a+build_length,b+build_width,0), (a,b+build_width,0),build_origin]) sky_apt = base.extrude((0,0,3)) self.add_geom(sky_apt) build_start = (x, y) build_end = (x+build_length, y+build_width) build_rect = geometry.AxisAligned2DRectangle(build_start, build_end) sector_rect = geometry.AxisAligned2DRectangle((0,0), (sector_length, sector_width)) common, layouts = geometry.split_overlapping_rectangles(sector_rect, build_rect) for layout in layouts: (x1, y1), (x2, y2) = layout.point1, layout.point2 layout_length = abs(x2 - x1) - road_gap layout_width = abs(y2 - y1) - road_gap dummy, sub_layouts = self.skyapt_plan(layout_length, layout_width, road_gap, plan) if not sub_layouts: origin = (layout.min_x(), layout.min_y(), 0) if plan == 'sky': plot_gap = 5 height_width_ratio = 8. building_range = self.picker.random() if building_range <= 0.4: building_height = self.picker.pick((15,75)) height_range = (15,75) else: building_height = self.picker.pick((3,15)) height_range = (3,15) plot_width = building_height/height_width_ratio if plot_width < 5: plot_width = 5 plot_length = (plot_width,plot_width*2) else: plot_gap = 8 height_width_ratio = 6. building_height = self.picker.pick((3,50)) height_range = (3,50) plot_width = building_height/height_width_ratio if plot_width < 5: plot_width = 5 plot_length = (plot_width,plot_width*3) self.subgen('celllayout', origin, layout_length, layout_width, [plot_length], plot_width, road_gap, [height_range], plot_gap) return sky_apt, layouts
def generate(self, config): C = config flat_rect = ((0, 0), (C.length, C.width)) flat_rect = geometry.AxisAligned2DRectangle(*flat_rect) center = C.length/2, C.width/2 print flat_rect ps = self.get_surrounding((0,0,0,C.length,C.width,0)) geoms = ps.get_geoms(tag='door') door = geoms[0] bb = door.BoundBox print bb (x1,y1,z1,x2,y2,z2) = (round(bb.XMin),round(bb.YMin),round(bb.ZMin), round(bb.XMax),round(bb.YMax),round(bb.ZMax)) door_width = x2 - x1 door_center = x1 + door_width/2 len_center = C.length/2 wid_center = C.width/2 door_gap = 2 # main_door_wall is 'left' if x1 == 0 or x2 == 0: print 'left' if door_center > wid_center: hall_edge = (0,y1-door_gap) other_edge = (C.length/2, C.width) else : hall_edge = (0,y1+door_gap) other_edge = (C.length/2, 0) hall_edge = (0,y1-door_gap) if door_center > wid_center else (0,y1+door_gap) # main_door_wall is 'right' elif x1 == C.length or x2 == C.length: print 'right' if door_center > wid_center: hall_edge = (C.length,y1-door_gap) other_edge = (C.length/2, C.width) else : hall_edge = (C.length,y1+door_gap) other_edge = (C.length/2, 0) # main_door_wall is 'down' elif y1 == 0 or y2 == 0: print 'down' if door_center > len_center: hall_edge = (x1-door_gap,0) other_edge = (C.length, C.width/2) else : hall_edge = (x2+door_gap,0) other_edge = (0, C.width/2) # main_door_wall is 'up' elif y1 == C.width or y2 == C.width: print 'up' if door_center > len_center: hall_edge = (x1-door_gap,C.width) other_edge = (C.length, C.width/2) else : hall_edge = (x2+door_gap,C.width) other_edge = (0, C.width/2) hall_rect = geometry.AxisAligned2DRectangle(hall_edge, other_edge) common, rooms = geometry.split_overlapping_rectangles(flat_rect, hall_rect) fused = None for room in rooms: (x1, y1), (x2, y2) = room.point1, room.point2 li = [(x1, y1), (x2, y2)] li.sort() (x1, y1), (x2, y2) = li[0], li[1] room_length = abs(x2 - x1) room_width = abs(y2 - y1) thickness = C.inner_wall_thickness p = draw.makePlane(room_length, room_width) p1 = draw.makePlane(room_length-thickness*2, room_width-thickness*2, (thickness,thickness,0)) p = p.cut(p1) p = p.Faces[0] p = draw._wrap_value(p) p = p.extrude((0, 0, C.height)) p.translate((x1, y2, 0)) if fused: fused = fused.fuse(p) else: fused = p self.add_geom(fused)