CiscoTheProot/visual.py

266 lines
No EOL
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)]))