#---------------------------------------------------------------------- # Randomness and the Sierpinski Gasket # See page 261 of the Computer Science Companion # # Copyright (C) February 17, 2017 -- Dr. William T. Verts # # Once the random library has been imported: # import random # then a whole bunch of functions become available: # random.random() returns a float >= 0.0 and < 1.0 # random.randrange(N) returns an int >= 0 and < N # random.randint(M,N) returns an int >= M and <= N # random.choice(L) returns a value from the list L # random.seed(N) restarts the random sequence at N # # I wish to create a drawing using randomness. First, pick three 2D # points P0, P1, and P2, where each has an X and Y value. For example, # point P0 would be defined by variables P0X and P0Y. Initially, the # three points are placed at the top center of the canvas, lower left # corner, and lower right corner. The three points don't move. # # Pick a fourth point PP that will move around the screen. Start it # at P0. In an infinite loop: pick one of the three fixed points at # random, then move PP to a point halfway between its current position # and the selected point, drop a dot on screen at PP's new position, # repaint the screen. # # Will the triangle between P0-P1-P2 eventually fill in? NO! # The figure formed is a fractal called a Sierpinski Gasket. #---------------------------------------------------------------------- import random def Main1(): W = 800 H = 600 Canvas = makeEmptyPicture(W,H) show(Canvas) P0X = W / 2 P0Y = 0 P1X = 0 P1Y = H - 1 P2X = W - 1 P2Y = H - 1 PPX = P0X PPY = P0Y while (True): N = random.randrange(3) if (N == 0): PPX = (PPX + P0X) / 2 PPY = (PPY + P0Y) / 2 MyColor = red elif (N == 1): PPX = (PPX + P1X) / 2 PPY = (PPY + P1Y) / 2 MyColor = green else: PPX = (PPX + P2X) / 2 PPY = (PPY + P2Y) / 2 MyColor = blue PX = getPixel(Canvas,PPX,PPY) setColor(PX, MyColor) repaint(Canvas) return #---------------------------------------------------------------------- # The screen updates far too slowly. That's because the repaint is # called after every pixel. To refresh the screen only after every # 1000 pixels, you'll need a counter variable that starts at 1000 and # counts down every pass through the loop - when it reaches zero the # screen is refreshed and the counter reinitialized. #---------------------------------------------------------------------- def Main2(): W = 800 H = 600 Canvas = makeEmptyPicture(W,H) show(Canvas) P0X = W / 2 P0Y = 0 P1X = 0 P1Y = H - 1 P2X = W - 1 P2Y = H - 1 PPX = P0X PPY = P0Y Counter = 1000 while (True): N = random.randrange(3) if (N == 0): PPX = (PPX + P0X) / 2 PPY = (PPY + P0Y) / 2 MyColor = red elif (N == 1): PPX = (PPX + P1X) / 2 PPY = (PPY + P1Y) / 2 MyColor = green else: PPX = (PPX + P2X) / 2 PPY = (PPY + P2Y) / 2 MyColor = blue PX = getPixel(Canvas,PPX,PPY) setColor(PX, MyColor) Counter = Counter - 1 if (Counter == 0): repaint(Canvas) Counter = 1000 return #---------------------------------------------------------------------- # Colors can be either selected at random or synthesized at random. # Here the lower-left triangle pixels are chosen from the list # containing green, blue, and cyan. The pixels in the lower-right # triangle are synthesized by picking random values for each of the # three primary colors (R, G, and B). #---------------------------------------------------------------------- def Main3(): W = 800 H = 600 Canvas = makeEmptyPicture(W,H) show(Canvas) P0X = W / 2 P0Y = 0 P1X = 0 P1Y = H - 1 P2X = W - 1 P2Y = H - 1 PPX = P0X PPY = P0Y Counter = 1000 while (True): N = random.randrange(3) if (N == 0): PPX = (PPX + P0X) / 2 PPY = (PPY + P0Y) / 2 MyColor = red elif (N == 1): PPX = (PPX + P1X) / 2 PPY = (PPY + P1Y) / 2 MyColor = random.choice([green,blue,cyan]) else: PPX = (PPX + P2X) / 2 PPY = (PPY + P2Y) / 2 R = random.randrange(256) G = random.randrange(256) B = random.randrange(256) MyColor = makeColor(R,G,B) PX = getPixel(Canvas,PPX,PPY) setColor(PX, MyColor) Counter = Counter - 1 if (Counter == 0): repaint(Canvas) Counter = 1000 return #---------------------------------------------------------------------- # Finally, the three corners of the triangle can themselves be # placed at random around the canvas. #---------------------------------------------------------------------- def Main4(): W = 800 H = 600 Canvas = makeEmptyPicture(W,H) show(Canvas) P0X = random.randrange(W) P0Y = random.randrange(H) P1X = random.randrange(W) P1Y = random.randrange(H) P2X = random.randrange(W) P2Y = random.randrange(H) PPX = P0X PPY = P0Y Counter = 1000 while (True): N = random.randrange(3) if (N == 0): PPX = (PPX + P0X) / 2 PPY = (PPY + P0Y) / 2 MyColor = red elif (N == 1): PPX = (PPX + P1X) / 2 PPY = (PPY + P1Y) / 2 MyColor = random.choice([green,blue,cyan]) else: PPX = (PPX + P2X) / 2 PPY = (PPY + P2Y) / 2 R = random.randrange(256) G = random.randrange(256) B = random.randrange(256) MyColor = makeColor(R,G,B) PX = getPixel(Canvas,PPX,PPY) setColor(PX, MyColor) Counter = Counter - 1 if (Counter == 0): repaint(Canvas) Counter = 1000 return #---------------------------------------------------------------------- # CHALLENGE FOR NEXT CLASS # # By rethinking the problem, can you rewrite the program to be # significantly shorter and use fewer variables? (You may need # to write a helper function!) #----------------------------------------------------------------------