;;; File: ;;; random-drawing-lab.scm ;;; Authors: ;;; Janet Davis ;;; Samuel A. Rebelsky ;;; Jerod Weinman ;;; YOUR NAME HERE ;;; Summary: ;;; Code for the lab entitled "Randomized Drawing" ; +--------------+------------------------------------------------------ ; | Rolling Dice | ; +--------------+ ;;; Procedure: ;;; roll-a-die ;;; Parameters: ;;; None ;;; Purpose: ;;; To simulate the rolling of one six-sided die. ;;; Produces: ;;; An integer between 1 and 6, inclusive. ;;; Preconditions: ;;; [None] ;;; Postconditions: ;;; Returns an integer between 1 and 6, inclusive. ;;; It should be difficult (or impossible) to predict which ;;; number is produced. (define roll-a-die (lambda () (+ (random 6) ; a value in the range [0 .. 5] 1))) ; now in the range [1 .. 6] ;;; Procedure: ;;; roll-dice ;;; Parameters: ;;; n, an integer ;;; Purpose: ;;; Roll n six-sided dice and make a list of their values. ;;; Produces: ;;; rolls, a list of integers ;;; Preconditions: ;;; [No additional] ;;; Postconditions: ;;; (length rolls) = n ;;; Each element of rolls is a value between 1 and 6. ;;; The values in rolls are reasonably evenly distributed. ;;; The values in rolls are difficult to predict. (define roll-dice (lambda (n) (if (zero? n) null (cons (roll-a-die) (roll-dice (- n 1)))))) ; +------------------+-------------------------------------------------- ; | Random Utilities | ; +------------------+ ;;; Procedure: ;;; list-random-element ;;; Parameters: ;;; values, a list ;;; Purpose: ;;; Randomly select an element of values. ;;; Produces: ;;; value, a value ;;; Preconditions: ;;; values is nonempty. ;;; Postconditions: ;;; value is an element of values. ;;; value is equally likely to be any element of values. ;;; It is difficult to predict which value it is. ;;; Problems: ;;; If values has only one element, it's not so difficult to predict ;;; which value is returned. (define list-random-element (lambda (values) (list-ref values (random (length values))))) ; +----------------+---------------------------------------------------- ; | Random Drawing | ; +----------------+ ;;; Procedure: ;;; random-rainbow-color ;;; Parameters: ;;; [None] ;;; Purpose: ;;; Picks a "random" (unpredictable) color from the basic colors ;;; of the rainbow. ;;; Produces: ;;; color, a string ;;; Preconditions: ;;; [None] ;;; Postconditions: ;;; color is a color. ;;; It is difficult for someone to predict what color random-color ;;; will return. (define random-rainbow-color (let ((rainbow (map color->rgb (list "red" "orange" "yellow" "green" "blue" "indigo" "violet")))) (lambda () (list-ref rainbow (random (length rainbow)))))) ;;; Procedure: ;;; random-color ;;; Parameters: ;;; (none) ;;; Purpose: ;;; Selects and returns a random color. ;;; Produces: ;;; color, a color. ;;; Postconditions: ;;; It is difficult to predict color. (define random-color (lambda () (rgb-new (random 256) (random 256) (random 256)))) ;;; Procedure: ;;; randomly-select-brush! ;;; Parameters: ;;; brushes, a list of strings ;;; Purpose: ;;; Select one of brushes. ;;; Produces: ;;; (nothing) ;;; Preconditions: ;;; All the strings in brushes name valid brushes. ;;; Postconditions: ;;; The current brush is an element of brushes. ;;; It is equally likely that each element of brushes is now the ;;; active brush ;;; It is difficult to predict which brush will be selected. (define randomly-select-brush! (lambda (brushes) (context-set-brush! (list-random-element brushes)))) ;;; Procedure ;;; select-random-brush! ;;; Parameters: ;;; (none) ;;; Purpose: ;;; Select one of the brushes. ;;; Produces: ;;; (nothing) ;;; Postconditions: ;;; It is difficult to predict the brush. (define select-random-brush! (lambda () (randomly-select-brush! (context-list-brushes)))) ;;; Procedure: ;;; random-blue ;;; Parameters: ;;; [None] ;;; Purpose: ;;; Selects a color with blue in its name. ;;; Produces: ;;; some-blue, an RGB color ;;; Preconditions: ;;; [None] ;;; Postconditions: ;;; some-blue is a color whose name includes "blue". ;;; It is difficult to predict which blue it is. (define random-blue (let ((colors-blues (map color-name->rgb (context-list-colors "blue")))) (lambda () (list-random-element colors-blues)))) ;;; Procedure: ;;; draw-random-line! ;;; Parameters: ;;; image, an image ;;; Purpose: ;;; Draw a random line in the image, assuming that its width ;;; and height are as specified. ;;; Produces: ;;; (nothing) ;;; Postconditions: ;;; A new line has been added to image, using the current color ;;; and brush. (define draw-random-line! (lambda (image) (image-draw-line! image (random (image-width image)) (random (image-height image)) (random (image-width image)) (random (image-height image))))) ;;; Procedure: ;;; draw-sin-with-parallel-lines! ;;; Parameters: ;;; image, an image ;;; n, an integer ;;; offset, an integer ;;; start-col, an integer ;;; mid-row, an integer ;;; Purpose: ;;; Draw a sequence of parallel lines, with the height of the ;;; parallel line dependent on the column. ;;; Produces: ;;; [Nothing, called for the side effect.] (define draw-sin-with-parallel-lines! (lambda (image n offset start-col mid-row) (cond ((> n 0) (image-draw-line! image start-col mid-row start-col (+ mid-row (* mid-row (sin (* n pi 0.01))))) (draw-sin-with-parallel-lines! image (- n 1) offset (+ start-col offset) mid-row))))) ;;; Procedure: ;;; draw-parallel-lines-with-decreasing-spacing! ;;; Parameters: ;;; image, an image ;;; col, an integer ;;; start-row, an integer ;;; end-row, an integer ;;; spacing ;;; close-enough ;;; Purpose: ;;; Draw a sequence of vertical lines (each running from start-row ;;; to end-row) starting at col, then spaced by spacing from col, ;;; then by spacing/2 from that column, then spacing/4 from that ;;; column, and so on and so forth until the distance between columns ;;; is less than or equal to close-enough. ;;; Produces: ;;; [Nothing. Called for the side effects.] (define draw-parallel-lines-with-decreasing-spacing! (lambda (image col start-row end-row spacing close-enough) (image-draw-line! image col start-row col end-row) (if (> spacing close-enough) (draw-parallel-lines-with-decreasing-spacing! image (+ col spacing) start-row end-row (/ spacing 2) close-enough)))) ;;; Procedure: ;;; splat! ;;; Parameters: ;;; image, an image ;;; Purpose: ;;; Draw a line between random points, using a random color and ;;; a random brush. ;;; Produces: ;;; (nothing) ;;; Postconditions: ;;; The foreground color may have changed. ;;; The brush may have changed. ;;; The image now contains another line. ;;; It should be difficult to predict what that line will look like. (define splat! (lambda (image) (context-set-fgcolor! (random-color)) (select-random-brush!) (draw-random-line! image) (context-update-displays!) image))