In my book I showed the easy way to draw one by making a turtle do it, but there's a little more complicated way that involves another famous triangle. It was known to the Chinese and Indians while we Europeans were still hiding from the Vikings, but we like to call it Pascal's Triangle after a more recent French mathematician.
The numbers can be generated by adding the numbers in the row above, but using a computer it's quicker to use the combination formula.
Here's the (Python 2) code I copied and pasted from dheerosaur on Stack Overflow:
import operator as op
...
def ncr(n, r):
r = min(r, n-r)
if r == 0: return 1
numer = reduce(op.mul, xrange(n, n-r, -1))
denom = reduce(op.mul, xrange(1, r+1))
return numer//denom
(To convert it to Python 3, just change "xrange" to "range" and add "from itertools import reduce" to the imports.)
The 1st row and column are really the 0th, so the "20" in row 7 is actually row 6, column 3:
>>> ncr(6,3)
20
How could you possibly get The Sierpinski Sieve from Pascal's Triangle? Let's use Pygame.
I use a template I found at Professor Craven's excellent Pygame tutorial. This sets up the screen and the colors and the display loop. All I have to do is draw shapes; it even updates the display and quits for me. I have to create a function to draw a triangle where I want it and what size I want it. The number (calculated with ncr above) will determine whether it's filled with color or not:
def triangle(x,y,size,filled):
'''draw an equilateral triangle'''
#if the number isn't a multiple of 2, color it in.
if filled % 2 != 0:
pygame.draw.polygon(screen,VIOLET,[[x,y],
[x-size/2.,y+1.732*size/2.],
[x+size/2.,y+1.732*size/2.]],
0)
else: thick = 0 #leave multiples of 2 empty
The "gasket" function will draw the triangles at the right spots:
def gasket(rows):
size = 400./rows #resize depending on the number of rows
for i in range(rows):
for j in range(i+1):
y = 1.732*i*size/2. #height of equilateral triangle
x = -i*size/2. + j * size + WIDTH/2. #width of triangle
triangle(x,y,size,ncr(i,j)) #draw the triangle
Now running "gasket(50)" will get you 50 rows of Pascal's triangle, with the multiples of 2 left empty:
Look familiar? You can change one digit in the "triangle" function to leave out the multiples of 3 instead:
Or the multiples of 8. The pattern of empty triangles changes every time. Try other numbers!
This blog entry has been brought to you by O'Reilly books.:-)
does not work for me python error is trown because WIDITH is not incialized.
ReplyDeleteHow to fix it?
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
in ()
----> 1 gasket(50)
in gasket(rows)
14 for j in range(i+1):
15 y = 1.732*i*size/2. #height of equilateral triangle
---> 16 x = -i*size/2. + j * size + WIDTH/2. #width of triangle
17 triangle(x,y,size,ncr(i,j)) #draw the triangle
NameError: name 'WIDTH' is not defined
If I put some value for WIDITH there is another error for pygame
ReplyDeletegasket(50)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
in ()
----> 1 gasket(50)
in gasket(rows)
16 y = 1.732*i*size/2. #height of equilateral triangle
17 x = -i*size/2. + j * size + WIDTH/2. #width of triangle
---> 18 triangle(x,y,size,ncr(i,j)) #draw the triangle
in triangle(x, y, size, filled)
3 #if the number isn't a multiple of 2, color it in.
4 if filled % 2 != 0:
----> 5 pygame.draw.polygon(screen,VIOLET,[[x,y],
6 [x-size/2.,y+1.732*size/2.],
7 [x+size/2.,y+1.732*size/2.]],
NameError: name 'pygame' is not defined