View difference between Paste ID: xhGSnBFz and
SHOW:
|
|
- or go back to the newest paste.
1 | - | |
1 | + | import random |
2 | import sys | |
3 | import pygame | |
4 | ||
5 | class MondrianRectangle(object): | |
6 | def __init__(self, rect, colour = (255, 255, 255)): | |
7 | self.rect = rect | |
8 | self.colour = colour | |
9 | ||
10 | def __getitem__(self, key): | |
11 | return self.rect[key] | |
12 | ||
13 | def __setitem__(self, key, value): | |
14 | self.rect[key] = value | |
15 | ||
16 | def draw(self, surface): | |
17 | surface.fill(self.colour, self.rect) | |
18 | ||
19 | ||
20 | class MondrianLine(object): | |
21 | def __init__(self, direction = "horizontal", start_pos = (0, 0), end_pos = (0, 0), width = 0): | |
22 | self.direction = direction | |
23 | self.start_pos = start_pos | |
24 | self.end_pos = end_pos | |
25 | self.width = width | |
26 | ||
27 | def draw(self, surface): | |
28 | pygame.draw.line(surface, (0, 0, 0), self.start_pos, self.end_pos, self.width) | |
29 | ||
30 | ||
31 | def generate_random_line(): | |
32 | width = 5 | |
33 | if random.random() > 0.5: | |
34 | line_pos = random.randint(0, 1024) | |
35 | return MondrianLine("vertical", (line_pos, 0), (line_pos, 768), width) | |
36 | else: | |
37 | line_pos = random.randint(0, 768) | |
38 | return MondrianLine("horizontal", (0, line_pos), (1024, line_pos), width) | |
39 | ||
40 | ||
41 | def split_rectangles(rectangles, line): | |
42 | new_rectangles = [] | |
43 | for j, rectangle in enumerate(rectangles): | |
44 | if (line.direction == "horizontal" and | |
45 | rectangle[1] < line.start_pos[1] < rectangle[3] and | |
46 | min(line.start_pos[0], line.end_pos[0]) <= rectangle[0] and | |
47 | max(line.start_pos[0], line.end_pos[0]) >= rectangle[2] | |
48 | ): | |
49 | new_rectangles.extend([ | |
50 | MondrianRectangle((rectangle[0], rectangle[1], rectangle[2], line.start_pos[1])), | |
51 | MondrianRectangle((rectangle[0], line.start_pos[1], rectangle[2], rectangle[3])) | |
52 | ]) | |
53 | ||
54 | elif (line.direction == "vertical" and | |
55 | rectangle[0] < line.start_pos[0] < rectangle[2] and | |
56 | min(line.start_pos[1], line.end_pos[1]) <= rectangle[1] and | |
57 | max(line.start_pos[1], line.end_pos[1]) >= rectangle[3] | |
58 | ): | |
59 | new_rectangles.extend([ | |
60 | MondrianRectangle((rectangle[0], rectangle[1], line.start_pos[0], rectangle[3])), | |
61 | MondrianRectangle((line.start_pos[0], rectangle[1], rectangle[2], rectangle[3])) | |
62 | ]) | |
63 | ||
64 | else: | |
65 | new_rectangles.append(rectangle) | |
66 | ||
67 | return new_rectangles | |
68 | ||
69 | ||
70 | def main(): | |
71 | screen = pygame.display.set_mode((1024, 768)) | |
72 | ||
73 | # Step 1 | |
74 | lines = [] | |
75 | rectangles = [MondrianRectangle((0, 0, 1024, 768))] | |
76 | for i in range(random.randint(5, 10)): | |
77 | line = generate_random_line() | |
78 | lines.append(line) | |
79 | rectangles = split_rectangles(rectangles, line) | |
80 | ||
81 | #Step 2 | |
82 | horizontal_lines = [line for line in lines if line.direction == "horizontal"] | |
83 | vertical_lines = [line for line in lines if line.direction == "vertical"] | |
84 | ||
85 | for i in range(random.randint(1, 10)): | |
86 | if random.random() > 0.5 and len(horizontal_lines) >= 2: | |
87 | lines_to_join = random.sample(horizontal_lines, 2) | |
88 | line_pos = random.randint(0, 1024) | |
89 | new_line = MondrianLine( | |
90 | "vertical", | |
91 | start_pos = (line_pos, lines_to_join[0].start_pos[1]), | |
92 | end_pos = (line_pos, lines_to_join[1].start_pos[1]), | |
93 | width = 5 | |
94 | ) | |
95 | rectangles = split_rectangles(rectangles, new_line) | |
96 | lines.append(new_line) | |
97 | elif len(vertical_lines) >= 2: | |
98 | lines_to_join = random.sample(vertical_lines, 2) | |
99 | line_pos = random.randint(0, 768) | |
100 | new_line = MondrianLine( | |
101 | "horizontal", | |
102 | start_pos = (lines_to_join[0].start_pos[0], line_pos), | |
103 | end_pos = (lines_to_join[1].start_pos[0], line_pos), | |
104 | width = 5 | |
105 | ) | |
106 | rectangles = split_rectangles(rectangles, new_line) | |
107 | lines.append(new_line) | |
108 | ||
109 | #Step 3 | |
110 | for rectangle in random.sample(rectangles, random.randint(1, 10)): | |
111 | rectangle.colour = ( | |
112 | random.randint(0, 255), | |
113 | random.randint(0, 255), | |
114 | random.randint(0, 255) | |
115 | ) | |
116 | ||
117 | while True: | |
118 | screen.fill((255, 255, 255)) | |
119 | for event in pygame.event.get(): | |
120 | if event.type == pygame.QUIT: sys.exit() | |
121 | [rectangle.draw(screen) for rectangle in rectangles] | |
122 | [line.draw(screen) for line in lines] | |
123 | pygame.display.flip() | |
124 | ||
125 | ||
126 | if __name__ == "__main__": | |
127 | main() |