Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDinko Galetic <dgaletic@everflame.(none)>2010-06-03 07:26:27 (GMT)
committer Dinko Galetic <dgaletic@everflame.(none)>2010-06-03 07:26:27 (GMT)
commitdf2e8632f108870eee9425e0d52dfe1a90ad7e19 (patch)
tree34233c69958b9f216b668ba9d49269a8626dc735
parentac3ece85713b1c2b998801a51dca173cbc4216f2 (diff)
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.
-rw-r--r--data/GSOC examples/Sierpinski - graphics146
1 files changed, 146 insertions, 0 deletions
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()
+
+
+
+
+
+