import math import os import time class Point2D: x = 0 y = 0 def __init__(self, x, y, value = 0): self.x = x self.y = y def round(self): self.x = round(self.x) self.y = round(self.y) return self def __eq__(self, other): return (self.x, self.y) == (other.x, other.y) def print_grid_tight(grid): width, height = len(grid), len(grid[0]) for y in range(height): for x in range(width): if(grid[x][y] == 1): blockchar = u"\u2588" print((f"\033[38;5;{250}m{blockchar*2}"), end = "") else: print((" "), end = "") print() #def print_grid(grid): # width, height = len(grid[0]), len(grid) # for x in range(height): # print(("+" + "----") * width + "+") # print("|", end = "") # for y in range(width): # if(grid[x][y] == 1): # print((" " + u"\u2588" + u"\u2588" + " ")+ "|", end = "") # else: # print((" ") + "|", end = "") # if(y == width-1): # print() # print(("+" + "----") * width + "+") grid = [[0 for y in range(32)] for x in range(64)] def shift_right(grid): width, height = len(grid[0]), len(grid) for x in range(height): for y in range(width-1, 0, -1): grid[x][y] = grid[x][y-1] def shift_left(grid): width, height = len(grid[0]), len(grid) for x in range(height): for y in range(1, width): grid[x][y-1] = grid[x][y] def shift_down(grid): width, height = len(grid[0]), len(grid) for x in range(height-1, 0, -1): for y in range(width): grid[x][y] = grid[x-1][y] def shift_up(grid): width, height = len(grid[0]), len(grid) for x in range(1, height): for y in range(width): grid[x-1][y] = grid[x][y] # line drawing funtion def draw_line(grid, start: Point2D, end: Point2D, color): dx = abs(end.x - start.x) dy = abs(end.y - start.y) length = dx if dx > dy else dy # diagonal_distance if length > 0: for i in range(length+1): t = i / length x = start.x + int(t * (end.x - start.x)) # linear interpolation y = start.y + int(t * (end.y - start.y)) # linear interpolation grid[x][y] = color else: grid[start.x][start.y] = color # triangle drawing helper functions def fillBottomFlatTriangle(grid, point1, point2, point3, color): invslope1 = (point2.x - point1.x) / (point2.y - point1.y) invslope2 = (point3.x - point1.x) / (point3.y - point1.y) curx1 = point1.x curx2 = point1.x for scanlineY in range(point1.y, point2.y+1): draw_line(grid, Point2D(int(curx1), scanlineY), Point2D(int(curx2), scanlineY), color) curx1 += invslope1 curx2 += invslope2 def fillTopFlatTriangle(grid, point1, point2, point3, color): invslope1 = (point3.x - point1.x) / (point3.y - point1.y) invslope2 = (point3.x - point2.x) / (point3.y - point2.y) curx1 = point3.x curx2 = point3.x for scanlineY in range(point3.y, point1.y-1, -1): draw_line(grid, Point2D(int(curx1), scanlineY), Point2D(int(curx2), scanlineY), color) curx1 -= invslope1 curx2 -= invslope2 def sortPoints2DAscendingByY(points: tuple[Point2D]) -> tuple[Point2D]: return tuple(sorted(points, key=lambda point: point.y)) # triangle drawing function def draw_triangle(grid, point1: Point2D, point2: Point2D, point3: Point2D, color): # at first sort the three vertices by y-coordinate ascending so point1 is the topmost vertex (point1, point2, point3) = sortPoints2DAscendingByY((point1, point2, point3)) # here we know that point1.y <= point2.y <= point3.y # check for trivial case of bottom-flat triangle if point2.y == point3.y: fillBottomFlatTriangle(grid, point1, point2, point3, color) # check for trivial case of top-flat triangle elif point1.y == point2.y: fillTopFlatTriangle(grid, point1, point2, point3, color) else: # general case - split the triangle in a topflat and bottom-flat one point4 = Point2D( int(point1.x + ((float)(point2.y - point1.y) / (float)(point3.y - point1.y)) * (point3.x - point1.x)), point2.y) fillBottomFlatTriangle(grid, point1, point2, point4, color) fillTopFlatTriangle(grid, point2, point4, point3, color) def pos_on_circle(center: Point2D, radius: float, angle: float) -> Point2D: angle = angle * 3.14159 / 180 x = center.x + radius * math.cos(angle) y = center.y + radius * math.sin(angle) return Point2D(x, y) # function for getting all the points on a circle def get_circle_points(grid, center: Point2D, radius) -> list[Point2D]: points = list() for r in range(360): newPoint = pos_on_circle(center, radius, r).round() if not newPoint in points: points.append(newPoint) return points points: list[Point2D] = get_circle_points(grid, Point2D(16,16), 6) #flag is next step will be shift left direction = 0 hand = Point2D t = 0 # top left corner grid[0][0] = 1 grid[0][1] = 1 grid[1][0] = 1 # top right corner grid[62][0] = 1 grid[63][0] = 1 grid[63][1] = 1 # lower right corner grid[62][31] = 1 grid[63][31] = 1 grid[63][30] = 1 # lower left corner grid[1][31] = 1 grid[0][31] = 1 grid[0][30] = 1 draw_triangle(grid, Point2D(5,5), Point2D(5,10), Point2D(10,10), 1) #draw_triangle(grid, Point2D(13,4), Point2D(18,12), Point2D(20,4), 1) #draw_triangle(grid, Point2D(20,18), Point2D(29,14), Point2D(25,25), 1) print_grid_tight(grid) def next_tick_circle(): # clear screen os.system('cls||clear') #update state in a square movement #global direction #match direction: # case 3: # shift_up(grid) # direction = 0 # case 2: # shift_left(grid) # direction += 1 # case 1: # shift_down(grid) # direction += 1 # case 0: # shift_right(grid) # direction += 1 global hand global t global points hand = points[t] color = 0 if grid[hand.x][hand.y] is 0: color = 1 draw_line(grid, Point2D(16,16), hand, color) t = t+1 if t is len(points): t = 0 # print current state print_grid_tight(grid) while True: time.sleep(0.1) next_tick_circle() #grayscale from 232(black) to 255(white) print(f"\033[38;5;{250}m {num2} \033[0;0m\n") # printing colors # colorspep8.py def colors_16(color_): return("\033[2;{num}m {num} \033[0;0m".format(num=str(color_))) def colors_256(color_): num1 = str(color_) num2 = str(color_).ljust(3, ' ') if color_ % 16 == 0: return(f"\033[38;5;{num1}m {num2} \033[0;0m\n") else: return(f"\033[38;5;{num1}m {num2} \033[0;0m") print("The 16 colors scheme is:") print(' '.join([colors_16(x) for x in range(30, 38)])) print("\nThe 256 colors scheme is:") print(' '.join([colors_256(x) for x in range(256)]))