[Sugar-devel] [PATCH] Pippy example - Sierpinski triangle

Dinko Galetic dinko.galetic at gmail.com
Thu Jun 3 04:29:52 EDT 2010


This Python script draws the Sierpinski triangle.

As with my Koch snowflake example, the user can modify the number of
triangles using left and right arrows.

diff --git a/data/GSOC examples/Sierpinski - graphics b/data/GSOC
examples/Sierp
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 c
+# which leaves a white hole (also shaped like a triangle, but upside down!)
in
+#
+# 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
probabl
+#
+# 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 c
+    # 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()
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.sugarlabs.org/archive/sugar-devel/attachments/20100603/7d7a3180/attachment.htm 


More information about the Sugar-devel mailing list