266 lines
7.1 KiB
Python
266 lines
7.1 KiB
Python
|
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)]))
|