2024-04-14 14:38:11 +00:00
|
|
|
# Alexander Bass
|
|
|
|
# Created 4/10/24
|
2024-06-05 16:27:03 +00:00
|
|
|
# Last Edited 6/5/24
|
2024-04-14 14:38:11 +00:00
|
|
|
import time
|
2024-06-05 16:27:03 +00:00
|
|
|
from math import sin
|
2024-04-14 14:38:11 +00:00
|
|
|
from point import Point, Rotator
|
|
|
|
from grass_donut import DonutEntity
|
|
|
|
from real_donut import RealDonutEntity
|
2024-06-05 16:27:03 +00:00
|
|
|
from entity import PointBlobEntity
|
2024-04-14 14:38:11 +00:00
|
|
|
from util import to_rad
|
|
|
|
|
|
|
|
WIDTH = 150
|
|
|
|
HEIGHT = 100
|
|
|
|
DEPTH = WIDTH
|
|
|
|
HALF_WIDTH = WIDTH / 2
|
|
|
|
HALF_HEIGHT = HEIGHT // 2
|
|
|
|
HALF_DEPTH = DEPTH // 2
|
|
|
|
|
|
|
|
NEGATIVE_DEPTH = -DEPTH
|
|
|
|
|
|
|
|
|
|
|
|
def world_to_screen(p_x, p_y, p_z):
|
|
|
|
s_x = round(p_x + HALF_WIDTH)
|
|
|
|
s_y = round(p_y + HALF_HEIGHT)
|
|
|
|
s_z = (p_z + HALF_DEPTH) / DEPTH
|
|
|
|
return s_x, s_y, s_z
|
|
|
|
|
|
|
|
|
|
|
|
def format_grid(entities, screen):
|
|
|
|
for x in range(WIDTH):
|
|
|
|
for y in range(HEIGHT):
|
|
|
|
screen[y][x] = None
|
|
|
|
|
|
|
|
for entity in entities:
|
|
|
|
for p in entity.get_points():
|
|
|
|
p_x, p_y, p_z = p.get_xyz()
|
|
|
|
s_x, s_y, s_z = world_to_screen(p_x, p_y, p_z)
|
|
|
|
if s_x in range(WIDTH) and s_y in range(HEIGHT):
|
|
|
|
val = screen[s_y][s_x]
|
|
|
|
if val is None:
|
|
|
|
red, green, blue = p.get_rgb()
|
|
|
|
screen[s_y][s_x] = (red, green, blue, s_z)
|
|
|
|
elif val[3] < s_z:
|
|
|
|
red, green, blue = p.get_rgb()
|
|
|
|
screen[s_y][s_x] = (red, green, blue, s_z)
|
|
|
|
|
|
|
|
s = ""
|
|
|
|
last_color = (0, 0, 0)
|
|
|
|
for y in range(HEIGHT):
|
|
|
|
for x in range(WIDTH):
|
|
|
|
cell = screen[y][x]
|
|
|
|
if cell is None or 0 > cell[3] > 255:
|
|
|
|
s += " "
|
|
|
|
continue
|
|
|
|
|
|
|
|
red, green, blue, depth = cell
|
|
|
|
scale = depth
|
|
|
|
red *= scale
|
|
|
|
green *= scale
|
|
|
|
blue *= scale
|
|
|
|
if (red, green, blue) != last_color:
|
|
|
|
s += f"\033[38;2;{round(red)};{round(green)};{round(blue)}m"
|
|
|
|
last_color = (red, green, blue)
|
|
|
|
s += "██"
|
|
|
|
s += "\n"
|
|
|
|
return s
|
|
|
|
|
|
|
|
|
|
|
|
def update_entities(entities, t):
|
|
|
|
for e in entities:
|
|
|
|
e.update(t)
|
|
|
|
|
|
|
|
|
|
|
|
class AxisEntity(PointBlobEntity):
|
|
|
|
def __init__(self):
|
|
|
|
self.points = []
|
|
|
|
for x in range(WIDTH // 2 + 1):
|
|
|
|
tx = x - WIDTH / 4
|
|
|
|
for y in range(WIDTH // 2 + 1):
|
|
|
|
ty = y - WIDTH / 4
|
|
|
|
self.add_point(Point().set_xyz(0, tx, ty).set_color(1, 1, 0))
|
|
|
|
|
|
|
|
r = (
|
|
|
|
Rotator()
|
|
|
|
.rotate_z(to_rad(80))
|
|
|
|
.rotate_y(to_rad(30))
|
|
|
|
.rotate_x(to_rad(30))
|
|
|
|
.build()
|
|
|
|
)
|
|
|
|
|
|
|
|
self.rotate(r)
|
|
|
|
|
|
|
|
self.rotor = Rotator().rotate_z(to_rad(0.6)).rotate_y(to_rad(0.06)).build()
|
|
|
|
|
|
|
|
def update(self, t):
|
|
|
|
t = t + 6 * 30
|
|
|
|
|
|
|
|
self.rotate(self.rotor)
|
|
|
|
for p in self.points:
|
|
|
|
x, y, z = p.get_xyz()
|
|
|
|
x, y = abs(x), abs(y)
|
|
|
|
p.set_color(255 * abs(sin(x * t / 99)), 255 * abs(sin(y * t / 100)), 0)
|
|
|
|
|
|
|
|
|
|
|
|
class Origin(PointBlobEntity):
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__()
|
|
|
|
self.points = [Point().set_xyz(0, 0, 0).set_color(255, 0, 0)]
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
entities = []
|
|
|
|
# entities.append(AxisEntity())
|
|
|
|
# entities.append(Origin())
|
|
|
|
entities.append(RealDonutEntity())
|
|
|
|
entities.append(DonutEntity())
|
|
|
|
t = 1
|
|
|
|
last_time = time.time()
|
|
|
|
dt = 0
|
|
|
|
|
|
|
|
grid = [[None for x in range(WIDTH)] for y in range(HEIGHT)]
|
|
|
|
while True:
|
|
|
|
print("\033c", end="")
|
|
|
|
print(format_grid(entities, grid))
|
|
|
|
|
|
|
|
update_entities(entities, t)
|
|
|
|
current_time = time.time()
|
|
|
|
dt = current_time - last_time
|
|
|
|
wait = 1 / 45 - dt
|
|
|
|
last_time = current_time
|
|
|
|
time.sleep(max(wait, 0))
|
|
|
|
|
|
|
|
t += 1 + 1 / 45 - dt
|
|
|
|
|
|
|
|
|
|
|
|
main()
|