Posted by phlyingpenguin on Fri 12 Sep 20:30 (modification of post by phlyingpenguin view diff)
report abuse | download | new post
- 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.rotate(-angle)
- """ Turn left 'angle' degrees """
- def left(self,angle):
- self.rotate(angle)
- def rotate(self, angle):
- self.t += angle
- if self.t > 360: self.t -= 360
- if self.t < -360: self.t += 360
- 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
- def get_loc(self):
- return (self.x, self.y)
- def get_dir(self):
- return self.t
- """ 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()
- sys.setrecursionlimit(100000000)
- class TurtleClient:
- framerate = 33
- def __init__(self):
- self.main()
- def display(self):
- glClear (GL_COLOR_BUFFER_BIT)
- glPushMatrix()
- self.turt.draw()
- glRectf(29, 29, 26, 26)
- self.turt2.draw()
- self.turt3.draw()
- glPopMatrix()
- glutSwapBuffers()
- def turt2_timer(self, e):
- if self.turt2.x >= 32 and self.turt2.y >= 32 or self.turt2.x >= 32 and self.turt2.y <= 23 or self.turt2.x <= 23 and self.turt2.y <= 23 or self.turt2.x <= 23 and self.turt2.y >= 32:
- self.turt2.right(90)
- self.turt2.forward(1)
- glutTimerFunc(self.framerate, self.turt2_timer, 0)
- def turt3_timer(self, e):
- p0 = self.t3_p
- count = self.t3_c
- v1 = self.v[random.randint(0, 3)]
- if count==0:
- self.turt3_poop_dot_at(v1[0] + 5, v1[1]+5)
- return
- p1 = ( (p0[0] + v1[0])/2, (p0[1] + v1[1])/2 )
- self.turt3_poop_dot_at(p1[0], p1[1])
- self.t3_c = count-1
- glutTimerFunc(self.framerate, self.turt3_timer, 0)
- def turt3_poop_dot_at(self, x, y):
- loc = self.turt3.get_loc()
- direction = self.turt3.get_dir()
- x0, y0 = x-loc[0], y-loc[1]
- d = sqrt(x0**2 + y0**2)
- if x0 == 0: angle = 0
- else: angle = degrees(arctan(y0 / x0))
- if x0 < 0 and y0 > 0: angle += 180
- if x0 < 0 and y0 < 0: angle += 180
- if x0 > 0 and y0 < 0: angle += 360
- t = angle-direction
- self.turt3.left(t)
- self.turt3.forward(d)
- self.turt3.flip_pen()
- self.turt3.forward(0.4)
- self.turt3.flip_pen()
- self.t3_p = self.turt3.get_loc()
- 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(-16, 16, 0)
- self.turt2 = Turtle(32, 32, 0)
- self.turt3 = Turtle(-30, -30, 0)
- self.t3_p = (-30, -30)
- self.t3_c = 600
- self.v = [(-30, -30), (-15,0), (0,-30)]
- 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)
- glutTimerFunc(self.framerate, self.turt2_timer, 0)
- glutTimerFunc(self.framerate, self.turt3_timer, 0)
- glutMainLoop()
- tc = TurtleClient()
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.