This homework assignment is also available in PDF.
Summary: In this assignment, you will further explore the creation of art via algorithm in the GIMP.
Purposes: To give you further experience using anonymous and higher-order procedures.
Expected Time: One to two hours.
Collaboration: You may work in a group of any size between one and four, inclusive. You may consult others outside your group, provided you cite those others. You need only submit one assignment per group.
Submitting: Email me your work, using a subject of CSC151 Homework 12.
Warning: So that this exercise is a learning assignment for everyone, I may spend class time publicly critiquing your work.
In a recent lab, you experimented with the creation of color grids that used an algorithm to choose the color at each position in the grid. In this assignment, you will rewrite the core color-grid procedure to permit different brushes and different grid spacing.
In case you're wondering, you should not rely on the code I wrote for the
color-grid procedure, since that code uses some control
structures you have not learned yet (in part, because they are specific
to Script-Fu). Rather, you will need to rewrite your procedure from
However, you may find it useful to consider the following procedure, which draws one point in the image.
(define draw-one-point (lambda (image x y redfunc greenfunc bluefunc) (set-fgcolor (list (mod (redfunc x y) 256) (mod (greenfunc x y) 256) (mod (bluefunc x y) 256))) (blot image x y)))
blot procedure draws a single spot with the current
paintbrush and the current foreground color at the specified location.
a. Write a procedure,
(draw-simple-grid image width height redfunc
greenfunc bluefunc) that draws an evenly spaced eleven-by-eleven
grid on the image, using the current paintbrush and choosing the
color at each position using the three functions. (You may call
draw-one-point for each point in the grid.) Note that I've
chosen an eleven-by-eleven grid because it is relatively easy to compute
the points on the grid. The first x value is 0. The next is 10% of the
width. The next is 20% of the width. And so on and so forth. The
eleventh is 100% of the width. Similarly, the first y value is 0. The
next is 10% of the height. And so on and so forth.
b. Grid based drawing can be more interesting when you permit multiple
draw-simple-grid to take an additional
brushfunc, as a parameter. This new parameter
should be a function of two integer parameters,
y, and should select a brush name based on x or y (or both).
For example, here's a very simple such procedure:
(define simple-brush (lambda (x y) (if (odd? (+ x y)) "Circle (09)" "Circle Fuzzy (07)")))
c. Test your new procedure with a variety of brush functions.
d. Some might criticize the images created by
draw-simple-grid for the stunning regularity of the
placement of dots. Add two more parameters,
yfun, each of which takes a number between 0 and 1 (representing
how far we are across the
grid) as a parameter and returns a number between 0 and 1 (representing how far across the grid we actually draw the point)
as a result. For example, for even spacing, you might use
(draw-simple-grid image 180 100 ; width, height func1 func2 func3 ; red, green, blue simple-brush ; brush (lambda (x) x) ; x coordinate (lambda (y) y)) ; y coordinate
For somewhat more interesting spacing, you might use
(lambda (x) (* x x)) for
xfunc. In that case, the x positions in the image would be computed as follows
e. Generate three interesting images using your procedure and send me the instructions for generating those images. (Do not clog my inbox with the images themselves.)
1. For the initial verison of
draw-simple-grid, you might want to
use a helper that draws a single row of the grid, and then call that
helper for each value of y.
2. Try to have some fun.
3. Some of you might need help thinking about how you recurse across an image
in percents. Here's a procedure that calls
along the major diagonal of the image, using the same percentage step
as suggested above.
(define draw-diagonal (lambda (image width height redfunc greenfunc bluefunc) (letrec ((kernel (lambda (percent) (if (<= percent 1.0) (let ((x (* percent width)) (y (* percent height))) (draw-one-point image x y redfunc greenfunc bluefunc) (kernel (+ percent .10))))))) (kernel 0))))
Here's a sample call to that proceudre:
(draw-diagonal img 180 100 (lambda (x y) (* x 2)) (lambda (x y) (* y 3)) (lambda (x y) (+ x y)))
4. As many of you have noted, Script-Fu is not a complete Scheme.
One thing that is missing is the set of procedures that convert reals to
integers, such as
draw-one-point seems to work fine with reals that include
fractional portions, such as 2.4.
Tuesday, 10 April 2007 [Samuel A. Rebelsky]
Thursady, 12 April 2007 [Samuel A. Rebelsky]
I usually create these pages
on the fly, which means that I rarely
proofread them and they may contain bad grammar and incorrect details.
It also means that I tend to update them regularly (see the history for
more details). Feel free to contact me with any suggestions for changes.
This document was generated by
Siteweaver on Wed Aug 29 08:59:27 2007.
The source to the document was last modified on Sun Jul 29 16:12:59 2007.
This document may be found at
You may wish to validate this document's HTML ; ;Samuel A. Rebelsky, firstname.lastname@example.org
http://creativecommons.org/licenses/by-nc/2.5/or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.