-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathCube.py
181 lines (155 loc) · 6.52 KB
/
Cube.py
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
from turtle import *
from math import *
from time import sleep
setup()
up()
# speed('normal') #probably redundant at this stage if using delay(0)
home()
tracer(0, 0) # make drawing faster. Comment this to see turtle drawings
hideturtle() # comment out to see turtle draw
# 'Sky' color as the background
bgcolor('darkblue')
# global position values for the cube
pos = [0.0, 0.0, 0.0]
rot = [0.0, 0.0, 0.0]
size = 20
Pos = pos
Rot = rot
# Let's set up original positions for all vertices
verts = [[1.0*size, 1.0*size, 1.0*size], [-1.0*size, 1.0*size, 1.0*size],
[-1.0*size, -1.0*size, 1.0*size], [1.0*size, -1.0*size, 1.0*size],
[1.0*size, 1.0*size, -1.0*size], [-1.0*size, 1.0*size, -1.0*size],
[-1.0*size, -1.0*size, -1.0*size], [1.0*size, -1.0*size, -1.0*size]]
# as well we will set up a list of normals based on the vert array indices
# this was the only way I knew to do it similar to an .obj 3D file? I read about
# this somewhere and I'm pretty sure this is how Unity generates meshes as well
# [Citation needed]
faces = [[0, 1, 2, 3], [5, 4, 7, 6], [4, 0, 3, 7],
[1, 5, 6, 2], [4, 5, 1, 0], [3, 2, 6, 7]]
# This was written using a lot of magic numbers because my 'camera' is set up
# as a static object and therefore there was a lot of errors in a few calculations.
# I basically changed random magic numbers on the go to try to get the best looking
# result.
def cull_faces(inverts=[], infaces=[]):
return_faces = []
# perform leet maths for face culling
for _ in range(len(infaces)):
# coordinates (easier to use in maths)
one = [verts[infaces[_][0]][0], verts[infaces[_][0]]
[1], verts[infaces[_][0]][2]]
two = [verts[infaces[_][1]][0], verts[infaces[_][1]]
[1], verts[infaces[_][1]][2]]
three = [verts[infaces[_][2]][0],
verts[infaces[_][2]][1], verts[infaces[_][2]][2]]
# calculate normals and normal lengths
tempnorm = [(one[0]-two[0]), (one[1]-two[1]), (one[2]-two[2])]
normlength = sqrt(((one[0]-two[0])**2.0) +
((one[1]-two[1])**2.0)+((one[2]-two[2])**2.0))
norm1 = [tempnorm[0]/normlength, tempnorm[1] /
normlength, tempnorm[2]/normlength]
tempnorm = [(three[0]-two[0]), (three[1]-two[1]), (three[2]-two[2])]
normlength = sqrt(
((three[0]-two[0])**2.0)+((three[1]-two[1])**2.0)+((three[2]-two[2])**2.0))
norm2 = [tempnorm[0]/normlength, tempnorm[1] /
normlength, tempnorm[2]/normlength]
crossvec = [(norm1[1]*norm2[2])-(norm1[2]*norm2[1]), (norm1[2]*norm2[0]) -
(norm1[0]*norm2[2]), (norm1[0]*norm2[1])-(norm1[1]*norm2[0])]
# probably the only important vectors in this code block for the faux camera's direction and the 'static directional light's normals
# changing any of these will result in a different lighting angle or camera angle (camera isn't really relevant since there's no other references)
cameravec = [0.0, 0.0, 1.0]
lightvec = [0, -0.45, 0.45]
# End important magic vectors
dot = (cameravec[0]*crossvec[0])+(cameravec[1]
* crossvec[1])+(cameravec[2]*crossvec[2])
if dot < -0.15:
brightness = (lightvec[0]*crossvec[0])+(lightvec[1]
* crossvec[1])+(lightvec[2]*crossvec[2])
return_faces.append(infaces[_])
return_faces.append(brightness)
return return_faces
def draw(infaces):
print(infaces, len(infaces)/2)
for _ in range(int(len(infaces)/2)):
# This color value can be changed to get a desired face colour in RGB (changing the magic numbers as a 'base lighting' value)
color((0, 0.4+(infaces[_*2+1])*0.4, 0))
up()
# important magic numbers here also
goto(verts[infaces[_*2][0]][0]*(5+verts[infaces[_*2][0]][2]/20.0),
verts[infaces[_*2][0]][1]*(5+verts[infaces[_*2][0]][2]/20.0))
begin_fill()
down()
goto(verts[infaces[_*2][1]][0]*(5+verts[infaces[_*2][1]][2]/20.0),
verts[infaces[_*2][1]][1]*(5+verts[infaces[_*2][1]][2]/20.0))
goto(verts[infaces[_*2][2]][0]*(5+verts[infaces[_*2][2]][2]/20.0),
verts[infaces[_*2][2]][1]*(5+verts[infaces[_*2][2]][2]/20.0))
goto(verts[infaces[_*2][3]][0]*(5+verts[infaces[_*2][3]][2]/20.0),
verts[infaces[_*2][3]][1]*(5+verts[infaces[_*2][3]][2]/20.0))
goto(verts[infaces[_*2][0]][0]*(5+verts[infaces[_*2][0]][2]/20.0),
verts[infaces[_*2][0]][1]*(5+verts[infaces[_*2][0]][2]/20.0))
end_fill()
up()
# These 3D numbers are calculated very roughly using not much accuracy,
# try not to hate on my magic number fairly accurate representations of vertices in
# 3D space ;P
update()
def rotate(xAxis=0, yAxis=0, zAxis=0):
# calculate for every angle
thetaX = radians(xAxis)
thetaY = radians(yAxis)
thetaZ = radians(zAxis)
csX = cos(thetaX)
snX = sin(thetaX)
csY = cos(thetaY)
snY = sin(thetaY)
csZ = cos(thetaZ)
snZ = sin(thetaZ)
for vert in range(len(verts)):
# calculate changes to Y axis
yx = float(verts[vert][0] * csY - verts[vert][2] * snY)
yz = float(verts[vert][0] * snY + verts[vert][2] * csY)
# rotate around Y axis
verts[vert][0] = yx
verts[vert][2] = yz
# calculate changes to X axis
xy = float(verts[vert][1] * csX - verts[vert][2] * snX)
xz = float(verts[vert][1] * snX + verts[vert][2] * csX)
verts[vert][1] = xy
verts[vert][2] = xz
# calculate changes to Z axis
zx = float(verts[vert][0] * csZ - verts[vert][1] * snZ)
zy = float(verts[vert][0] * snZ + verts[vert][1] * csZ)
# rotate around Z axis
verts[vert][0] = zx
verts[vert][1] = zy
def L():
clear()
rotate(0, 5, 0)
draw(cull_faces(verts, faces))
def R():
clear()
rotate(0, -5, 0)
draw(cull_faces(verts, faces))
def U():
clear()
rotate(-5, 0, 0)
draw(cull_faces(verts, faces))
def D():
clear()
rotate(5, 0, 0)
draw(cull_faces(verts, faces))
onkey(L, "Left")
onkey(R, "Right")
onkey(U, "Up")
onkey(D, "Down")
listen()
rotate(0, 20, 20)
width(2)
draw(cull_faces(verts, faces))
######################Important loop code##############################
# commenting this loop out only updates on arrow keys / rotations
#for count in range(5000):
#clear()
#rotate(10,0,0)
#draw(cull_faces(verts,faces))
#sleep(0.09)
done()