diff options
Diffstat (limited to 'data')
-rw-r--r-- | data/GSOC examples/rotate polygon | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/data/GSOC examples/rotate polygon b/data/GSOC examples/rotate polygon new file mode 100644 index 0000000..fdd3222 --- /dev/null +++ b/data/GSOC examples/rotate polygon @@ -0,0 +1,194 @@ +# This code creates a polygon and then rotates it around one of its points. +# Two static polygons are here so you can experiment with them, but you'll +# have to uncomment them first. + +# Practice: +# When you start this example, the two lines of text will be too close to each other. +# How could that be fixed? +# +# Also, the starting shape is kinda small. We can increase it with our Up arrow, +# but can you find what should be changed in this example so that that shape +# starts larger by default? + + +import pippy, pygame, sys
+from pygame.locals import *
+from random import *
+from math import cos, sin +from math import pi as Pi + +# always need to init first thing
+pygame.init()
+ +# XO screen is 1200x900
+size = width, height = 1200, 800
+
+# create the window and keep track of the surface
+# for drawing into
+screen = pygame.display.set_mode(size)
+
+# turn off the cursor
+pygame.mouse.set_visible(False) + +# This is used to define how our shapes (polygons) look like and behave. +# By default, a polygon will have three sides (a triangle), each 300 in length. +class Polygon(object): + # If you don't specify the number of sides and length you with your + # polygon to have, it will take these values as default. + def __init__(self, n = 3, length = 300): + if n < 3: + print "Number of points cannot be less than three" + return + self.n_sides = n + self.side_length = length + self.points = [] + starting_point = (0, 0) + self.points.append(starting_point) + for i in range(n-1): + point = self.points[i][0] + cos(2 * Pi * i/n) * length, \ + self.points[i][1] - sin(2 * Pi * i/n) * length + self.points.append(point) + + # This defines how our polygon will draw itself on a surface we give it. + # The surface variable is called "screen" in this example. + # Variable "start" defines the point from which we'll start drawing it, and + # then later rotating it. By default, it's the middle of the screen. + # + def draw(self, screen, start = (screen.get_width() / 2, \ + screen.get_height() / 2) ): + real_coordinates = [] + for point in self.points: + real_point = point[0] + start[0], point[1] + start[1] + real_coordinates.append(real_point) + # draw a line between each two neighbouring points + for i in range(len(real_coordinates)-1): + pygame.draw.line(screen, (0, 255, 0), real_coordinates[i], real_coordinates[i+1]) + # another line between the last point and the first one to close the polygon + pygame.draw.line(screen, (0, 255, 0), real_coordinates[i+1], real_coordinates[0]) + + # This rotates the polygon around its starting point. + # It doesn't draw anything - it recalculates where all the other vertices + # will be when the triangle is rotated. + def rotate(self, angle): + # delete everything but the starting point, since we need to + # calculate all the other points again + self.points = [(0,0)] + for i in range(self.n_sides-1): + point = self.points[i][0] + cos(angle + 2 * Pi * i/self.n_sides) * self.side_length, \ + self.points[i][1] - sin(angle + 2 * Pi * i/self.n_sides) * self.side_length + self.points.append(point) + +# OK, let's create out polygon! +# Set some values it will use.. (practice hint here!) +side_length = 50 +number_of_sides = 5 +rotation_angle = 0 +speed_factor = 0 + +poly1 = Polygon(number_of_sides, side_length) + +# Commented out is the code which creates two more polygons. You could +# uncomment it to try it out. Code: +# poly2 = Polygon(number_of_sides, side_length) +# triangle1 = Polygon(length) + +# Background color will be black. +bgcolor = (0, 0, 0) + +# for displaying the instructions and rotation speed +font_size = 36 +font_colour = (0, 250, 0) +font = pygame.font.Font(None, font_size) + +# Conversion from degrees to radians. For us, it represents the smallest amount +# of rotation possible. If you wish to understand it better, it has to do with +# math (trigonometry) so you can try finding some information about it. +degree = Pi / 180 + +# While L or R arrow is pressed and held, these variables will change so that +# our program knows to keep increasing the speed of the rotation. +# Left arrow increases the rotation in the counter clockwise direction (+) and +# the right one clockwise (-). +less = False +more = False + +# for controling the polygon size when U or D arrow is pressed +size_changed = False + +while pippy.pygame.next_frame(): + for event in pygame.event.get(): + if event.type == QUIT: + sys.exit() + # right arrow makes it rotate clockwise + elif event.type == KEYDOWN and event.key == K_RIGHT: + less = True + # left arrow makes it rotate counterclockwise + elif event.type == KEYDOWN and event.key == K_LEFT: + more = True + # when a key is lifted, stop changing speed + elif event.type == KEYUP and event.key == K_RIGHT: + less = False + elif event.type == KEYUP and event.key == K_LEFT: + more = False + + # Changing the size of our polygon with up and down keys. + # TODO: Report that my up arrow doesn't work in Sugar. + # Practice: Unlike L and R keys, this does not keep changing size + # while the keys are pressed. Could you make it so? Look to L and R + # examples to understand how it's done. + elif event.type == KEYDOWN and event.key == K_UP: + side_length += 5 + size_changed = True + elif event.type == KEYDOWN and event.key == K_DOWN and side_length > 5: + side_length -= 5 + size_changed = True + elif event.type == KEYDOWN: + sys.exit() + + screen.fill(bgcolor) + + # display instructions, speed and size + msg = "Use left and right arrows for controling speed. Speed: " + msg = msg + str(speed_factor) + msg2 = "Use up and down arrows for controling size. Size : " + str(side_length) + text1 = font.render(msg , True, font_colour) + text_box1 = text1.get_rect() + text_box1.top = 5 + text2 = font.render(msg2 , True, font_colour) + text_box2 = text2.get_rect() + text_box2.top = 20 + + # if the L or R arrow is pressed (and held), keep adjusting speed + # You'll have to click it real fast if you with to change the speed by + # only one! + if less == True: + speed_factor = speed_factor - 1 + if more == True: + speed_factor = speed_factor + 1 + + # The new angle by which our polygone is turned is the previous angle + the + # change in rotation due to speed_factor being changed by L or R keys. + rotation_angle = rotation_angle + degree * speed_factor + + # If the size was changed (with up and down keys), create a new polygon + # with that size. + if size_changed == True: + poly1 = Polygon(number_of_sides, side_length) + size_changed = False + poly1.rotate(rotation_angle) + poly1.draw(screen) + + # This should also be uncommented if you with to see some other polygons + # we've prepared for you. + # Practice: Uncomment the code and change some values. What happend? + # Code to uncomment: + # poly2.draw(screen) + # triangle1.rotate(30 * Pi / 180) + # triangle1.draw(screen, (800, 650)) + + # draw the text + screen.blit(text1, text_box1) + screen.blit(text2, text_box2) + + # refresh the screen + pygame.display.flip() |