Assignment 4: Exploring Colors

Due: 10:30 p.m., Tuesday, 2 October 2012

Summary: In this assignment, you will explore a variety of issues pertaining to colors. In doing so, you will draw upon the “drawings as values” model, lists and the map operation, and the RGB color model.

Purposes: To give you experience working with the RGB color operations. To help you think more about colors. To give you more experience working with map, lists, and anonymous procedures. To give you the opportunity to combine a variety of techniques in one solution.

Expected Time: Two to three hours.

Collaboration: We encourage you to work in groups of size three. You may, however, work in a group of size two or one.

Submitting: Email your answer to . The title of your email should have the form CSC151-02 Assignment 4: Exploring Colors and should contain your answers to all parts of the assignment. Scheme code should be in the body of the message.

Warning: So that this assignment is a learning experience for everyone, we may spend class time publicly critiquing your work.

Part 1: Visualizing Colors

As you saw in your initial exploration of RGB colors in GIMP and MediaScript, there are a wide range of of colors possible. You may have also discovered that it is difficult to figure out what color a particular RGB triple, such as (18,223,51) represents. It is also useful to see how a variety of colors relate to each other.

It can thefore be helpful to build tools to help you understand colors and their relationships. We will start by building such a tool.

The Problem

Write a procedure, (visualize-colors list-of-colors number-of-colors), that produces a simple visualization of a list of colors by making a list of copies of some simple shape, each colored with a different color, and each shifted slightly from the last. You may choose the shape, size, and amount to shift subsequent shapes.

An Example

For example, consider the following command

> (visualize-colors 
   (list "red" "orange" "yellow" "green" "blue" "indigo" "violet")

If we use circles of diameter 20, with each subsequent circle starting 15 units to the right of the previous circle, we should get something like the following.

Similarly, we can visualize a variety of shades that start with pink using the following.

> (visualize-colors 
   (list RGB-PINK
         (rgb-darker RGB-PINK)
         (rgb-darker (rgb-darker RGB-PINK))
         (rgb-darker (rgb-darker (rgb-darker RGB-PINK)))
         (rgb-darker (rgb-darker (rgb-darker (rgb-darker RGB-PINK)))))

Using the same visualization technique (circles of radius 20, spaced by 15 units), we would get the following image.

Some Notes

You will find it easier to do this assignment if you break the problem down in to steps.

  • Create some basic shape. (We shifted the unit circle by 0.5 and then scaled it by 20.)
  • Make a list (of the appropriate size) of multiple copies of that shape. In the first case, we made a list of seven circles; in the second, we made a list of five circles.
  • Make a list of offsets. (We made the list (0 15 30 45 ...).)
  • Use map (along with an appropriate procedure) to offset your shapes.
  • Use map (along with an appropriate procedure) to color your shapes.
  • Turn that list of shapes into an image.
  • Show that image.

Part 2: Blending Colors

A common effect in digital graphics is a color blend, in which colors range more or less smoothly from one color to another. What tools does one need to blend RGB colors? You must know how to manipulate the red, green, and blue components of colors used in digital images. And you know how to do that. In particular, you can extract the red, green, and blue components of a color using rgb-red, rgb-green, and rgb-blue, and you can construct an RGB color using rgb-new. Along with basic mathematical operations this is enough to let you construct small color blends.

The Problem

Write and document a procedure, (rgb-blend weight rgb1 rgb2), that takes a weight between 0 and 1 and two RGB colors, and computes the RGB color made up of weight parts of color1 and (- 1 weight) parts of rgb2.


We can, of course, start looking at this procedure in how it works with the RGB components of some individual colors.

> (rgb->string (rgb-blend 0.5 RGB-BLUE RGB-RED))
> (rgb->string (rgb-blend 0.5 RGB-BLUE RGB-BLACK))
> (rgb->string (rgb-blend 0.5 RGB-BLUE RGB-GREY))
> (rgb->string (rgb-blend 0.2 RGB-BLUE RGB-RED))
> (rgb->string (rgb-blend 0.8 RGB-BLUE RGB-RED))

However, it is probably more enlightening to visualize the colors in a blend.

> (visualize-colors
   (map (lambda (weight) (rgb-blend weight RGB-RED RGB-BLUE))
        (map (r-s / 10) (reverse (iota 11))))
> (visualize-colors
   (map (lambda (weight) (rgb-blend weight RGB-BLUE RGB-WHITE))
        (map (r-s / 10) (reverse (iota 11))))
> (visualize-colors
   (map (lambda (weight) (rgb-blend weight RGB-RED RGB-AQUA))
        (map (r-s / 20) (reverse (iota 21))))

Thinking About the Problem

It is probably easiest to think about this procedure in terms of particular components. Suppose the red component of rgb1 is 0 and the red component of rgb2 is 120. If weight is 0.2, then the red component of the weighted average will be 96 (that is, 0.2*0 + 0.8*120). If weight is 0.75, then the red component of the weighted average will be 30 (that is, 0.75*0 + 0.25*120).

For another example, suppose the green component of rgb1 is 200 and the green component of rgb2 is 0. If weight is 0.2, then the green component of the weighted average will be 40 (that is 0.2*200 + 0.8*0). Similarly, if weight is 0.75, then the green component of the weighted average will be 150 (that is 0.75*200 + 0.25*0).

What if the components are both non-zero? Suppose the blue component of rgb1 is 120 and the blue component of rgb2 is 180. If weight is 0.2, then the green component of the weighted average will be 168 (0.2*120+0.8*180 = 24+144). If weight is 0.75, then the green component of the weighted average will be 135 (you can do the math).

Part 3: Visualizing Blends

After completing part one, you are able to visualize lists of colors. After completing part two, you are able to make blends of colors. It's now time to put those to techniques together.

Write a procedure, (visualize-blend rgb1 rgb2 steps), that visualizes a blend from rgb1 to rgb2 in steps increments. (E.g., if rgb1 is red, rgb2 is blue, and steps is 4, we'll get a visualization involving five shapes, the first of which will be red, the second a blend that is 75% red and 25% blue, the third a blend that is 50% red and 50% blue, the fourth a blend that is 25% red and 75% blue, and the last blue.

Hint: Pay close attention to the examples in Part 2 and think about how to generalize them for a procedure in Part 3.

Part 4: Beyond Visualization

You've now built a variety of tools for exploring colors. Hopefully, those have helped you understand colors and some Scheme techniques a bit better. Now it's time to put that understanding into practice.

As you've observed, the blends we've created so far are interesting insofar as they are blends, but a bit straightforward, in that the shapes used to render them appear just in a straight line. In a number of recent labs, you've explored ways to vary shapes, changing their size, vertical position, and horizonal position.

Write a procedure, (fun-with-blends rgb1 rgb2) that makes an appealing image by grouping of three sequences of shapes (you can choose the length of each sequence, but each sequence must have at least five shapes) in which the colors of the shapes in each sequence represent a blend from rgb1 to rgb2 or from rgb2 to rgb1.

Here are two examples of “interesting” images that blend blue and red.

If you find it useful to write some helper procedures as you write fun-with-blends, you may certainly do so. Please give those helper procedures informative names.

Important Evaluation Criteria

We intend to evaluate your assignment on the correctness, elegance, and clarity of your solutions. That is, we will check whether your procedures do what they are intended to do, whether they are reasonably concise, and whether you have chosen a technique that is clear and easy to understand.

Jerod Weinman

Copyright 2007-2012 Janet Davis, Matthew Kluber, Samuel A. Rebelsky, and Jerod Weinman. (Selected materials copyright by John David Stone and Henry Walker and used by permission.)

This material is based upon work partially supported by the National Science Foundation under Grant No. CCLI-0633090. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.

Creative Commons License This work is licensed under a Creative Commons Attribution-NonCommercial 2.5 License .