Source for: lesson4.py [raw]

  1class Box():
  2
  3    def __init__(self, x=0, y=0, w=1, h=1):
  4        """Accept arguments to define our box, and store them."""
  5        self.x = x
  6        self.y = y
  7        self.w = w
  8        self.h = h
  9
 10    def __repr__(self):
 11        return "Box(%s, %s, %s, %s)" % (self.x, self.y, self.w, self.h)
 12
 13
 14many_boxes = [Box() for i in range(5000)]
 15
 16pages = [Box(0, i * 55, 30, 50) for i in range(10)]
 17
 18# We add a "separation" constant so you can see the boxes individually
 19separation = .2
 20
 21
 22def layout(_boxes):
 23    # Because we modify the box list, we will work on a copy
 24    boxes = _boxes[:]
 25    # We start at page 0
 26    page = 0
 27    # The 1st box should be placed in the correct page
 28    previous = boxes.pop(0)
 29    previous.x = pages[page].x
 30    previous.y = pages[page].y
 31    while boxes:
 32        # We take the new 1st box
 33        box = boxes.pop(0)
 34        # And put it next to the other
 35        box.x = previous.x + previous.w + separation
 36        # At the same vertical location
 37        box.y = previous.y
 38        # But if it's too far to the right...
 39        if (box.x + box.w) > (pages[page].x + pages[page].w):
 40            # We go all the way left and a little down
 41            box.x = pages[page].x
 42            box.y = previous.y + previous.h + separation
 43
 44        # But if we go too far down
 45        if box.y + box.h > pages[page].y + pages[page].h:
 46            # We go to the next page
 47            page += 1
 48            # And put the box at the top-left
 49            box.x = pages[page].x
 50            box.y = pages[page].y
 51
 52        previous = box
 53
 54
 55layout(many_boxes)
 56
 57import svgwrite
 58
 59
 60def draw_boxes(boxes, fname, size):
 61    dwg = svgwrite.Drawing(fname, profile="full", size=size)
 62    # Draw the pages
 63    for page in pages:
 64        dwg.add(
 65            dwg.rect(
 66                insert=(f"{page.x}cm", f"{page.y}cm"),
 67                size=(f"{page.w}cm", f"{page.h}cm"),
 68                fill="lightblue",
 69            )
 70        )
 71    # Draw all the boxes
 72    for box in boxes:
 73        dwg.add(
 74            dwg.rect(
 75                insert=(f"{box.x}cm", f"{box.y}cm"),
 76                size=(f"{box.w}cm", f"{box.h}cm"),
 77                fill="red",
 78            )
 79        )
 80    dwg.save()
 81
 82
 83draw_boxes(many_boxes, "lesson4.svg", ("100cm", "100cm"))
 84
 85pages = [Box(i * 35, 0, 30, 50) for i in range(10)]
 86layout(many_boxes)
 87draw_boxes(many_boxes, "lesson4_side_by_side.svg", ("100cm", "50cm"))
 88
 89
 90from random import randint
 91
 92pages = [
 93    Box(i * 35, 0, 30 - randint(0, 10), 50 - randint(0, 30))
 94    for i in range(10)
 95]
 96layout(many_boxes)
 97draw_boxes(many_boxes, "lesson4_random_sizes.svg", ("100cm", "50cm"))
 98
 99many_boxes = [Box(w=1 + randint(-5, 5) / 10) for i in range(5000)]
100layout(many_boxes)
101draw_boxes(
102    many_boxes, "lesson4_random_box_sizes.svg", ("100cm", "50cm")
103)
104