from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from numpy import *
class Turtle:
def __init__(self,x, y, theta):
self.x = x
self.y = y
self.t = theta
self.pen = 0
self.trail = []
""" Move forward 'distance' units """
def forward(self,distance):
line = [(self.x,self.y)]
self.x += distance * cos(radians(self.t))
self.y += distance * sin(radians(self.t))
line.append( (self.x, self.y) )
if self.pen == 1: self.trail.append(line)
glutPostRedisplay()
""" Move right 'angle' degrees. Note that 'angle' is POSITIVE to move right """
def right(self,angle):
self.t -= angle
glutPostRedisplay()
""" Turn left 'angle' degrees """
def left(self,angle):
self.t += angle
glutPostRedisplay()
""" Set pen on or off (1/0) """
def pen(self,position):
self.pen = position
""" Flip pen bit """
def flip_pen(self):
self.pen = self.pen ^ 1
""" Use data to produce the current image """
def draw(self):
""" shape x points """
polys = [[(1.0, -0.99999999999999989),
(1.5000000000000002, -2.5),
(2.0, -1.9999999999999998)],
[(-0.99999999999999989, -1.0),
(-1.4999999999999998, -2.5),
(-1.9999999999999998, -2.0)],
[(-1.0, 0.99999999999999989),
(-1.5000000000000002, 2.5),
(-2.0, 1.9999999999999998)],
[(0.99999999999999989, 1.0),
(1.4999999999999998, 2.5),
(1.9999999999999998, 2.0)]]
""" circle x ( [points] x radius) """
circles = [[[(0.0, 0.0)], 2], [[(2.2000000000000002, 1.3471114790620887e-16)], 1]]
""" trail """
glColor3f(0.5, 0.3, 0.1)
map(lambda x: self.draw_shape(GL_LINES, x), self.trail)
glColor3f(0.0, 0.8, 0.0)
""" Convert points into matricies and multiply """
def rotate(x):
C = matrix([
[cos(radians(self.t)), -sin(radians(self.t)), 0],
[sin(radians(self.t)), cos(radians(self.t)), 0],
[0,0,1]
])
p = matrix(list(x)+[0])
p.shape = (3,1)
p = C*p
p = p.tolist()
return (p[0][0],p[1][0])
polys = map(lambda x: map(lambda t: rotate(t), x), polys)
circles = map(lambda x: [map(lambda y: rotate(y), x[0])] + [x[1]], circles)
""" Movement: """
move = lambda y: map(lambda x:(x[0]+self.x, x[1]+self.y), y)
polys = map(lambda t: move(t), polys)
circles = map(lambda x: [move(x[0]), x[1]], circles)
""" Drawing: """
map(lambda x: self.draw_shape(GL_POLYGON, x), polys)
map(lambda x: self.circle(x[0][0][0], x[0][0][1], x[1]), circles)
""" Abstract shape drawing """
def draw_shape(self,id,shape):
translated = map(lambda x: x, shape)
glBegin(id)
map(lambda x: glVertex2f(x[0], x[1]), translated)
glEnd()
""" Draws a circle at x,y, radius in size. """
def circle(self, x, y, radius):
self.draw_circle(x,y,radius,0.5)
"""
Draws a circle at x,y, radius in size.
Taken from: http://www.allegro.cc/forums/thread/588625
"""
def draw_circle(self,x,y,radius,accuracy):
glDisable(GL_TEXTURE_2D)
da = min( (2.0 * math.asin(1.0/radius)/accuracy), 0.5)
glBegin(GL_TRIANGLE_FAN)
glVertex2d(x,y)
t = arange(0,2*pi,da)
map(lambda a: glVertex2d(x + cos(a) * radius, y + sin(a) * radius), t)
glVertex2d(x + radius, y)
glEnd()
class TurtleClient:
def __init__(self):
self.main()
def display(self):
glClear (GL_COLOR_BUFFER_BIT)
glPushMatrix()
self.turt.draw()
glPopMatrix()
glutSwapBuffers()
def reshape(self, w, h):
glViewport (0, 0, w, h)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(-40.0, 40.0, -40.0, 40.0, -1.0, 1.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def keyboard(self, key, x, y):
if (key == 'q' or key == 'Q'): exit(0)
def special_key(self, key, x, y):
if key == GLUT_KEY_LEFT: self.turt.left(10)
if key == GLUT_KEY_RIGHT: self.turt.right(10)
if key == GLUT_KEY_UP: self.turt.forward(2)
if key == GLUT_KEY_DOWN: self.turt.flip_pen()
def main(self):
self.turt = Turtle(0, 0, 0)
glutInit()
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB)
glutInitWindowSize (500, 500)
glutInitWindowPosition (100, 100)
glutCreateWindow("o hai!")
glClearColor(0.0, 0.0, 0.0, 0.0)
glShadeModel(GL_FLAT)
glutDisplayFunc(self.display)
glutReshapeFunc(self.reshape)
glutKeyboardFunc(self.keyboard)
glutSpecialFunc(self.special_key)
glutMainLoop()
tc = TurtleClient()