Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # tk_spiraled_square.py
- import tkinter as tk
- import math
- from collections import defaultdict
- WW = HH = 600
- N = 15
- cell_size = HH // N
- flipped = False
- root = tk.Tk()
- root.geometry("+10+10")
- root.title("# tk_spiraled_square.py")
- canvas = tk.Canvas(root, width=WW, height=HH, bg='white')
- canvas.pack()
- def rotate_str(matrix):
- rotated = []
- for col in range(N-1, -1, -1):
- new_row = []
- for row in range(N):
- new_row.append(matrix[row][col])
- rotated.append(''.join(new_row))
- return rotated
- def replace_zeros(s):
- index = s.find("100")
- if index == -1:
- return s
- before_10 = s[:index + 2]
- after_10 = s[index + 2:]
- index = after_10.find("X")
- old = after_10[:index + 1]
- after_10 = after_10.replace(old, 'X' + '1' * index)
- return before_10 + after_10
- def generate_fixed_matrix(N):
- matrix = ['0' * N for _ in range(N)]
- matrix[0] = '1' * N
- matrix[-1] = '0X' + '1' * (N - 2)
- matrix = rotate_str(matrix)
- matrix[0] = '1' * N
- while True:
- for i in range(N):
- if 'X' in matrix[i]:
- prev = matrix[i]
- matrix[i] = replace_zeros(matrix[i])
- break
- if matrix[i] == prev:
- matrix[i] = prev.replace('X', '1')
- return matrix
- matrix = rotate_str(matrix)
- spirals = generate_fixed_matrix(N)
- def get_boundary_segments(matrix, target):
- segments = []
- rows = len(matrix)
- cols = len(matrix[0])
- for i in range(rows):
- for j in range(cols):
- if matrix[i][j] == target:
- x = j * cell_size
- y = i * cell_size
- if i == 0 or matrix[i-1][j] != target:
- segments.append(((x, y), (x+cell_size, y)))
- if i == rows-1 or matrix[i+1][j] != target:
- segments.append(((x+cell_size, y+cell_size), (x, y+cell_size)))
- if j == 0 or matrix[i][j-1] != target:
- segments.append(((x, y+cell_size), (x, y)))
- if j == cols-1 or matrix[i][j+1] != target:
- segments.append(((x+cell_size, y), (x+cell_size, y+cell_size)))
- return segments
- def join_segments(segments):
- neighbors = defaultdict(list)
- for a, b in segments:
- neighbors[a].append(b)
- neighbors[b].append(a)
- start = next(iter(neighbors))
- polygon = [start]
- prev = None
- current = start
- while True:
- nbs = neighbors[current]
- if prev is None:
- next_v = nbs[0]
- else:
- next_v = nbs[0] if nbs[0] != prev else nbs[1]
- if next_v == start:
- polygon.append(start)
- break
- polygon.append(next_v)
- prev, current = current, next_v
- return polygon
- def get_polygon_for_color(matrix, target):
- segments = get_boundary_segments(matrix, target)
- poly = join_segments(segments)
- return poly
- def rotate_polygon(polygon, angle):
- cx, cy = WW // 2, HH // 2
- radians = math.radians(angle)
- cos_a = math.cos(radians)
- sin_a = math.sin(radians)
- rotated_poly = []
- for x, y in polygon:
- x -= cx
- y -= cy
- x_new = x * cos_a - y * sin_a + cx
- y_new = x * sin_a + y * cos_a + cy
- rotated_poly.append((x_new, y_new))
- return rotated_poly
- def flip_polygon_vertically(polygon):
- return [(x, HH - y) for x, y in polygon]
- angle = 0
- def update_rotation():
- global angle
- angle += 90
- draw_pattern()
- root.after(1000, update_rotation)
- def flip_polygons(event):
- global flipped
- flipped = not flipped
- draw_pattern()
- def draw_pattern():
- global angle, flipped
- canvas.delete("all")
- blue_poly = get_polygon_for_color(spirals, '1')
- orange_poly = get_polygon_for_color(spirals, '0')
- blue_poly = rotate_polygon(blue_poly, angle)
- orange_poly = rotate_polygon(orange_poly, angle)
- if flipped:
- blue_poly = flip_polygon_vertically(blue_poly)
- orange_poly = flip_polygon_vertically(orange_poly)
- canvas.create_polygon(blue_poly, fill='blue', outline='black')
- canvas.create_polygon(orange_poly, fill='orange', outline='black')
- canvas.create_text(WW // 2, 60, text="Press Spacebar To Flip", font=("Arial", 18), fill="black")
- root.bind("<space>", flip_polygons)
- draw_pattern()
- update_rotation()
- root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement