/
KochPyramid.py
executable file
·213 lines (165 loc) · 7 KB
/
KochPyramid.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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# -*- coding: utf-8 -*-
"""
Created on Sat Feb 14 15:43:06 2015
@author: Michael
"""
from __future__ import division
import sys
try:
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
except:
print('ERROR: PyOpenGL not installed properly.')
sys.exit()
from ModelViewWindow import *
from GLDrawHelper import *
from numpy import arccos as acos
from numpy import pi
class KochPyramid(Model):
def init(self):
'''
This init method gets called after OpenGL context creation. This is
because glut doesn't create opengl context until a window is actually
created. On the other hand python's __init__ gets called during object
instantiation which might happen before opengl context is created.
'''
Model.init(self) # since we are overriding Model.init by creating an init() function
# we need to first let Model.init initialize itself (basically creates display list)
initGL()
def draw_scene(self):
'''
View class takes care of setting the projection matrix and lookat.
Adding them here would override those calls and won't let mouse/keyboard
to work...because the mouse and keyboard functions only know about the View's api.
'''
#'''
# The light source position should be defined here so that it is in world
# coordinates and undergoes the same transformation as the pyramid.
glLightfv(GL_LIGHT0,GL_POSITION,[ -0.2, -0.1, 1., 1. ] )
glPushMatrix()
glTranslate(0, 0, .5) #
glScalef(1/16.0, 1/16.0, 1/16.0)
# Show a little shiny sphere in the scene so that you can get a better sense of where
# the light source is.
gluSphere(self.pQuadric,.5, 20, 20)
glPopMatrix()
#'''
glPushMatrix()
glTranslate(-1./2, -sqrt(3)/4, 0)
self.drawKochPyramid(3) # You may change this line to draw the Koch pyramid to different levels.
glPopMatrix()
def basicTriangle(self): # has one vertex at origin, one at (1,0,0), ...
glNormal3f(0, 0, 1)
glVertex(0, 0, 0)
glVertex(1.0, 0, 0)
glVertex( 1/2.0, sqrt(3)/2.0, 0)
'''
Helper method!
Draws the pyramid's faces.
'''
def drawFaces(self, level):
glPushMatrix()
glRotatef(180, 0, 0, 1) # let these be the upper face of pyramid
glRotatef(acos(1.0/3.0)*(180.0/pi), 1,0,0) # apply the dihedral angle
self.drawKochPyramid(level - 1)
glPopMatrix()
glPushMatrix()
glTranslate(-1,0,0)
glRotatef(300, 0, 0, 1) # let these be the upper face of pyramid
glRotatef(acos(1.0/3.0)*(180.0/pi), 1,0,0) # apply the dihedral angle
self.drawKochPyramid(level - 1)
glPopMatrix()
glPushMatrix()
glTranslate(-1/2.0, -sqrt(3)/2.0, 0)
glRotatef(420, 0, 0, 1) # let these be the lower right face of pyramid
glRotatef(acos(1.0/3.0)*(180.0/pi), 1,0,0) # apply the dihedral angle
self.drawKochPyramid(level - 1)
glPopMatrix()
def drawKochPyramid(self, level):
if (level == 0):
glBegin(GL_TRIANGLES)
self.basicTriangle()
glEnd()
else:
#TODO --------------- BEGIN SOLUTION: ADD YOUR CODE HERE ------------------------------
glPushMatrix()
glScalef(1.0/3.0, 1.0/3.0, 1.0/3.0)
# first, draw the non-pyramidal faces
self.drawKochPyramid(level-1)
glPushMatrix()
glTranslate(1/2.0, sqrt(3)/2.0, 0)
self.drawKochPyramid(level-1)
glTranslate(1/2.0, sqrt(3)/2.0, 0)
self.drawKochPyramid(level-1)
glPopMatrix()
glPushMatrix()
glTranslate(1.0, 0, 0)
self.drawKochPyramid(level-1)
glPushMatrix()
glTranslate(1.0, 0, 0)
self.drawKochPyramid(level-1)
glPopMatrix()
glTranslate(1/2.0, sqrt(3)/2.0, 0)
self.drawKochPyramid(level-1)
glPopMatrix()
# next, draw the pyramids
glPushMatrix()
# start with the lower left pyramid and draw its three faces
glTranslate(1/2.0 + 1, sqrt(3)/2.0, 0)
self.drawFaces(level) # see helper method
# do the upper pyramid
glPushMatrix()
glTranslate(1/2.0, sqrt(3)/2.0, 0)
self.drawFaces(level)
glPopMatrix()
# do the lower right pyramid
glTranslate(1, 0, 0)
self.drawFaces(level)
glPopMatrix()
glPopMatrix()
# --------------- END SOLUTION ------------------------------
def initGL():
glClearColor(1.0, 1.0, 1.0, 1.0) # defines background color when you run glClear(GL_COLOR_BUFFER_BIT)
glClearDepth(1) # defines background depth when you run glClear(GL_DEPTH_BUFFER_BIT)
glDisable(GL_CULL_FACE)
glEnable(GL_LIGHTING)
glEnable(GL_NORMALIZE)
glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE)
glLightfv(GL_LIGHT0,GL_POSITION,[ 0.4, 0.5, 1., 1. ] )
glLightfv(GL_LIGHT0,GL_AMBIENT,[ 1.0, 1.0, 1.0, 1.0 ])
glLightfv(GL_LIGHT0,GL_DIFFUSE,[ 1.0, 1.0, 1.0, 1.0 ])
glLightfv(GL_LIGHT0,GL_SPECULAR,[ 1.0, 1.0, 1.0, 1.0 ])
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, [0, 0, 1])
'''
glLightf( GL_LIGHT0, GL_SPOT_EXPONENT, 80.0)
glLightf( GL_LIGHT0, GL_SPOT_CUTOFF, 4.0)
'''
glLightf( GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1)
glLightf( GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0)
glLightf( GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.05)
glEnable(GL_LIGHT0)
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LESS)
glShadeModel(GL_SMOOTH)
matColor = [0.0, 0.9, 0.9, 1.0]
specColor = [.9, 0.0, 0.0, 1.0]
ambColor = [0.1, 0.1, 0.1, 1.0]
nshininess = [128, 128.0, 128, 1 ]
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matColor)
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor)
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambColor)
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, nshininess)
def main():
# glutInit and glutInitDisplayMode needs to be called because GLUTWindow
# only deals with inidividual windows
glutInit()
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
cam_spec = {'eye' : [0, -1, 1.5], 'center' : [0, 0, 0], 'up' : [0, 1, 0],
'fovy': 40, 'aspect': 1.0, 'near' : 0.01, 'far' : 200.0}
kp = KochPyramid()
cam = View(kp, cam_spec)
GLUTWindow('Koch Pyramid', cam, window_size = (512, 512), window_pos =(520, 0))
glutMainLoop()
if __name__ == '__main__':
main()