[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