-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrotatingcube
More file actions
executable file
·118 lines (104 loc) · 2.97 KB
/
rotatingcube
File metadata and controls
executable file
·118 lines (104 loc) · 2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/bin/python3
import curses
import time
import math
import argparse
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] ]
def chooseChar(angle):
chars = ('/','-','\\','|','/','-','\\','|')
angle += 2.5*math.pi - 0.125
angle %= math.pi*2
for i in range(8):
if math.pi*i/4 < angle and angle < math.pi*(i+1)/4:
return chars[i]
def drawLine(window, x0, y0, x1, y1): # Bresenham's line algorithm
char = chooseChar(math.atan2(y1-y0, x1-x0))
dx = abs(x1 - x0)
dy = abs(y1 - y0)
x, y = x0, y0
sx = -1 if x0 > x1 else 1
sy = -1 if y0 > y1 else 1
if dx > dy:
err = dx / 2.0
while x != x1:
window.addch(y, x, char)
err -= dy
if err < 0:
y += sy
err += dx
x += sx
else:
err = dy / 2.0
while y != y1:
window.addch(y, x, char)
err -= dx
if err < 0:
x += sx
err += dy
y += sy
def drawEdges(window):
height, width = stdscr.getmaxyx()
for e1, e2 in edges:
v1 = vertices[e1]
v2 = vertices[e2]
xOff = width / 2
yOff = height / 2
scale = min(width/2, height) * 0.28
drawLine(
window,
int(v1[1]*2*scale+xOff),
int(v1[2]*scale+yOff),
int(v2[1]*2*scale+xOff),
int(v2[2]*scale+yOff)
)
def rotateX(value):
for i in range(len(vertices)):
newAngle = math.atan2(vertices[i][2], vertices[i][1]) + value;
distance = math.sqrt(vertices[i][1] ** 2 + vertices[i][2] ** 2)
vertices[i][1] = distance * math.cos(newAngle)
vertices[i][2] = distance * math.sin(newAngle)
def rotateY(value):
for i in range(len(vertices)):
newAngle = math.atan2(vertices[i][2], vertices[i][0]) + value;
distance = math.sqrt(vertices[i][0] ** 2 + vertices[i][2] ** 2)
vertices[i][0] = distance * math.cos(newAngle)
vertices[i][2] = distance * math.sin(newAngle)
def rotateZ(value):
for i in range(len(vertices)):
newAngle = math.atan2(vertices[i][1], vertices[i][0]) + value;
distance = math.sqrt(vertices[i][0] ** 2 + vertices[i][1] ** 2)
vertices[i][0] = distance * math.cos(newAngle)
vertices[i][1] = distance * math.sin(newAngle)
def main(stdscr, auto=False, fps=60):
while True:
key = stdscr.getch()
if key == 27: # ESC
return
rotSpeed = 1 / 128
if key == curses.KEY_LEFT:
rotateZ(2*math.pi*rotSpeed)
elif key == curses.KEY_RIGHT:
rotateZ(-2*math.pi*rotSpeed)
elif key == curses.KEY_UP:
rotateY(2*math.pi*rotSpeed)
elif key == curses.KEY_DOWN:
rotateY(-2*math.pi*rotSpeed)
if auto:
rotSpeed = 1 / 512
rotateY(2*math.pi*rotSpeed / 2)
rotateZ(2*math.pi*rotSpeed)
stdscr.clear()
drawEdges(stdscr)
stdscr.refresh()
time.sleep(1 / fps)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--auto", "-a", action="store_true", help="Rotate automatically")
args = parser.parse_args()
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
stdscr.nodelay(True)
stdscr.keypad(True)
curses.wrapper(main, args.auto)