from kandinsky import fill_rect from math import sin, cos, pi from time import sleep, monotonic from random import uniform, random BG = (0, 0, 0) CENTER_X = 160 CENTER_Y = 111 SCALE = 70 FPS = 0.02 PIXEL_SIZE = 3 def clear(): fill_rect(0, 0, 320, 222, BG) def draw_pixel(x, y, color): fill_rect(int(x), int(y), PIXEL_SIZE, PIXEL_SIZE, color) def project_point(x, y, z): fov = 200 factor = fov / (fov + z) px = CENTER_X + x * factor * SCALE py = CENTER_Y + y * factor * SCALE return int(px), int(py) def color_from_points(p1, p2, t): x1, y1 = p1 x2, y2 = p2 v = (x1 + y1 + x2 + y2) * 0.02 + t if int(now) % 4 == 0: return (255,255,0) r = int(180 + 70 * sin(v * 0.6)) g = int(180 + 70 * sin(v * 0.8 + 2)) b = int(180 + 70 * sin(v * 1.0 + 4)) return ( r, g, b) def draw_edge(p1, p2, t): color = color_from_points(p1, p2, t) x1, y1 = p1 x2, y2 = p2 steps = max(abs(x2 - x1), abs(y2 - y1)) // 12 + 1 for i in range(steps + 1): u = i / steps x = x1 + (x2 - x1) * u y = y1 + (y2 - y1) * u draw_pixel(x, y, color) vertices = [ (-1, -1, -1), ( 1, -1, -1), ( 1, 1, -1), (-1, 1, -1), (-1, -1, 1), ( 1, -1, 1), ( 1, 1, 1), (-1, 1, 1) ] edges = [ (0,1),(1,2),(2,3),(3,0), (4,5),(5,6),(6,7),(7,4), (0,4),(1,5),(2,6),(3,7) ] t0 = monotonic() rx, ry, rz = 0.0, 0.0, 0.0 vx, vy, vz = 0.02, 0.03, 0.015 while True: clear() now = monotonic() t = now - t0 vx += uniform(-0.002, 0.002) vy += uniform(-0.002, 0.002) vz += uniform(-0.002, 0.002) vx = max(min(vx, 0.05), -0.05) vy = max(min(vy, 0.05), -0.05) vz = max(min(vz, 0.05), -0.05) rx += vx ry += vy rz += vz cosx, sinx = cos(rx), sin(rx) cosy, siny = cos(ry), sin(ry) cosz, sinz = cos(rz), sin(rz) projected = [] for x, y, z in vertices: y2 = y * cosx - z * sinx z2 = y * sinx + z * cosx y, z = y2, z2 x2 = x * cosy + z * siny z2 = -x * siny + z * cosy x, z = x2, z2 x2 = x * cosz - y * sinz y2 = x * sinz + y * cosz x, y = x2, y2 projected.append(project_point(x, y, z)) for e in edges: p1 = projected[e[0]] p2 = projected[e[1]] draw_edge(p1, p2, t) sleep(FPS)