From df2e8632f108870eee9425e0d52dfe1a90ad7e19 Mon Sep 17 00:00:00 2001 From: Dinko Galetic Date: Thu, 03 Jun 2010 07:26:27 +0000 Subject: Added a Python script which draws the Sierpinski triangles. The difference between the existing example is that this one does it with pygame instead ASCII art. --- (limited to 'data') diff --git a/data/GSOC examples/Sierpinski - graphics b/data/GSOC examples/Sierpinski - graphics new file mode 100644 index 0000000..449277a --- /dev/null +++ b/data/GSOC examples/Sierpinski - graphics @@ -0,0 +1,146 @@ +# This example draws what is called the Sierpinski triangle. +# First, one black triangle is created. +# After that it is removed and in its place three smaller black triangles are created, +# which leaves a white hole (also shaped like a triangle, but upside down!) in the middle. +# +# This can continue for any number of steps - you can split the smaller +# triangles into even smaller ones and so on. +# We have, however, limited it to 8 to keep our computers from freezing due to +# too much calculations! If you change it to a higher number, that will probably happen. +# +# This code is similar to the code in "Koch snowflake" example so you +# could first go through that to understand this example better. + +import pippy, pygame, sys +from pygame.locals import * +from math import sin, cos +from math import pi as Pi + +class Triangle(object): + def __init__(self, first_vertex, length, displacement_angle = 0 ): + # remember your first vertex + self.A = first_vertex + # calculate the other two + self.B = self.A[0] + length * cos(Pi/3 + displacement_angle), \ + self.A[1] - length * sin(Pi/3 + displacement_angle) + self.C = self.A[0] + length * cos(displacement_angle), \ + self.A[1] - length * sin(displacement_angle) + # remember your length + self.length = length + # calculate the midpoints of each line + # m1 for AB, m2 for BC, m3 for CA + # m1 and m3 are calculated the same way as points B and C, but with + # half the length. + self.m1 = self.A[0] + length/2 * cos(Pi/3 + displacement_angle), \ + self.A[1] - length/2 * sin(Pi/3 + displacement_angle) + self.m3 = self.A[0] + length/2 * cos(displacement_angle), \ + self.A[1] - length/2 * sin(displacement_angle) + # m2 is 120 degrees (2*Pi/3) from C, half the length. + # ... but we don't actually need it for anything. + self.m2 = self.C[0] + length/2 * cos(2*Pi/3 + displacement_angle), \ + self.C[1] - length/2 * sin(2*Pi/3 + displacement_angle) + + # create three new triangles from yourself. + def split(self): + new_triangles = [] + new_triangles.append(Triangle(self.A, self.length/2)) + new_triangles.append(Triangle(self.m1, self.length/2)) + new_triangles.append(Triangle(self.m3, self.length/2)) + return new_triangles + + # This is how a triangle draws itself. + def draw(self, screen, color): + points = [self.A, self.B, self.C] + pygame.draw.polygon(screen, color, points) + +# always need to init first thing before drawing +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) + +# The font we'll use to display the current depth. +font_size = 36 +font = pygame.font.Font(None, font_size) + +black = (0, 0, 0) +white = (255, 255, 255) + +starting_point = (200, 750) +side_length = 800 + +t1 = Triangle(starting_point, side_length) +t2 = Triangle((800, 600), 150) + +depth = 0 + +all_triangles = [t1] +new_triangles = [] + +recalculate = False + +while pippy.pygame.next_frame(): + for event in pygame.event.get(): + if event.type == QUIT: + sys.exit() + # When R arrow is pressed, go one step further. + # This means splitting the existing triangle(s) into new ones. + # Note that all the triangles have to be recalculated before redrawn. + elif event.type == KEYDOWN and event.key == K_RIGHT and depth < 8: + depth += 1 + recalculate = True + # When L arrow is pressed, go one step back, reducing the number of + # triangles. + # Note that all the triangles have to be recalculated before redrawn. + elif event.type == KEYDOWN and event.key == K_LEFT and depth > 0: + depth -= 1 + recalculate = True + elif event.type == KEYDOWN: + sys.exit() + screen.fill(white) + # Display the current step. + msg = "Step: " + str(depth) + "/8" + text = font.render(msg , True, black) + text_box = text.get_rect() + text_box.top = 130 + text_box.left = 50 + # Display the instructions + text2 = font.render("Use left and right arrows.", True, black) + text_box2 = text2.get_rect() + text_box2.top = 100 + text_box2.left = 50 + # Write the instructions and the current step on the screen. + screen.blit(text, text_box) + screen.blit(text2, text_box2) + + # If the depth was changed (L or R pressed), recalculate everything so we can + # draw the change. + if recalculate == True: + # Delete the existing triangles. + all_triangles = [t1] + new_triangles = [] + # Keep splitting until the new value of "depth" variable is reached. + # (it can be one more (R key) or one less (L key) from the last value) + for step in range(depth): + for triangle in all_triangles: + new_triangles += triangle.split() + all_triangles = new_triangles + new_triangles = [] + recalculate = False + + # Draw the triangle on the screen. + for triangle in all_triangles: + triangle.draw(screen, black) + + # Refresh the screen. + pygame.display.flip() + + + + + + -- cgit v0.9.1