plotille:rotating_cube
문서의 이전 판입니다!
Plotille: rotating cube
- rotating_cube.py
#!/usr/bin/env python # -*- coding: utf-8 -*- # original: https://github.com/asciimoo/drawille/blob/master/examples/rotating_cube.py # drawille의 rotating cube를 plotille를 사용하도록 포팅 import sys import math import time from IPython import embed import random import numpy as np import plotille from plotille import Canvas class Screen: def __init__(self, width, height, fps=20): super().__init__() self.width = width self.height = height self.fps = fps def clear(self): sys.stdout.write('\x1b[2j\n\033c\n\x1bc') # clear sys.stdout.write('\u001b[1000D') # 커서 왼쪽으로 이동 sys.stdout.write(f'\u001b[1000A') # 커서 위로 이동 sys.stdout.flush() def write(self, content): sys.stdout.write('\u001b[1000D') # 커서 왼쪽으로 이동 sys.stdout.write(f'\u001b[{self.height}A') # 커서 위로 이동 sys.stdout.write(content) sys.stdout.flush() # 화면에 출력 time.sleep(1 / self.fps) class Point3D: def __init__(self, x, y, z): self.x, self.y, self.z = float(x), float(y), float(z) def transform(self, trans): p = np.ones(4) p[0] = self.x p[1] = self.y p[2] = self.z p_prime = trans @ p.reshape(-1, 1) # 변환 self.x = p_prime[0, 0] self.y = p_prime[1, 0] self.z = p_prime[2, 0] def project(self, win_width, win_height, fov, viewer_distance): """ Transforms this 3D point to 2D using a perspective projection. """ x = self.x - 0.5 y = self.y - 0.5 z = self.z factor = fov / (viewer_distance + z) x = x * factor + win_width / 2 y = -y * factor + win_height / 2 return Point3D(x / win_width, y / win_height, 1) def __repr__(self): return f'{self.x:.2f}-{self.y:.2f}-{self.z:.2f}' def T(dx, dy, dz): " 이동 변환 " T = np.eye(4) T[0, 3] = dx T[1, 3] = dy T[2, 3] = dz return T def R(ax, ay, az): " 회전변환 " # X rad = np.radians(ax) cosa = math.cos(rad) sina = math.sin(rad) RX = np.eye(4) RX[1, 1] = cosa RX[1, 2] = -sina RX[2, 1] = sina RX[2, 2] = cosa # y rad = np.radians(ay) cosa = math.cos(rad) sina = math.sin(rad) RY = np.eye(4) RY[0, 0] = cosa RY[0, 2] = -sina RY[2, 0] = sina RY[2, 2] = cosa # z rad = np.radians(az) cosa = math.cos(rad) sina = math.sin(rad) RZ = np.eye(4) RZ[0, 0] = cosa RZ[0, 1] = sina RZ[1, 0] = -sina RZ[1, 1] = cosa return RZ @ RY @ RX vs = [ Point3D(0.25, 0.75, 0.25), # Point3D(-20,20,-20), Point3D(0.75, 0.75, 0.25), # Point3D(20,20,-20), Point3D(0.75, 0.25, 0.25), # Point3D(20,-20,-20), Point3D(0.25, 0.25, 0.25), # Point3D(-20,-20,-20), Point3D(0.25, 0.75, 0.75), # Point3D(-20,20,20), Point3D(0.75, 0.75, 0.75), # Point3D(20,20,20), Point3D(0.75, 0.25, 0.75), # Point3D(20,-20,20), Point3D(0.25, 0.25, 0.75), # Point3D(-20,-20,20) ] # Define the vertices that compose each of the 6 faces. These numbers are # indices to the vertices list defined above. faces = [ (0, 1, 2, 3), (1, 5, 6, 2), (5, 4, 7, 6), (4, 0, 3, 7), (0, 4, 5, 1), (3, 2, 6, 7) ] if __name__ == '__main__': screen = Screen(height=20, width=40, fps=20) screen.clear() projection = False # 변환 행렬 TR = T(0.5, 0.5, 0.5) @ R(2, 3, 5) @ T(-0.5, -0.5, -0.5) while True: canvas = Canvas(height=screen.height, width=screen.width) t = list() for i, v in enumerate(vs): # Rotate the point around X axis, then around Y axis, and finally around Z axis. v.transform(TR) if projection: # Transform the point from 3D to 2D v = v.project( win_width=50, win_height=50, fov=50, viewer_distance=1 ) t.append(v) for f in faces: canvas.line(t[f[0]].x, t[f[0]].y, t[f[1]].x, t[f[1]].y) canvas.line(t[f[1]].x, t[f[1]].y, t[f[2]].x, t[f[2]].y) canvas.line(t[f[2]].x, t[f[2]].y, t[f[3]].x, t[f[3]].y) canvas.line(t[f[3]].x, t[f[3]].y, t[f[0]].x, t[f[0]].y) screen.write(canvas.plot())
plotille/rotating_cube.1592325826.txt.gz · 마지막으로 수정됨: (바깥 편집)