CPSC 120: Project 2

Due on Saturday, 04/12/2014

Home | Calendar | Announcements | Assignments | Example Code | Notes

Version 1.2 (added additional tutorial material)


Drawing Pad

Build a program that allows the user to draw on the screen by clicking and dragging the mouse.

Minimum Requirements

  1. The program should display a white window of 800 by 700 pixels in width.

  2. There should be a white rectangle drawn (with a visible outline of some color), which takes up most but not all of the space in the window. This rectangle is the "drawing window", where pictures can be placed.

  3. There should be a small square, drawn somewhere outside of the drawing window, displaying the current drawing color. When the program starts, the current color should be black.

  4. The program must support drawing in any one of 8 colors: red, green, blue, yellow, cyan, magenta, black, and gray. The current color is set by pressing a key:

  5. When the user clicks and drags the cursor across the drawing window, small circles should be drawn, in the current color, where the mouse is moved. When the mouse is not being clicked, movement has no effect.

  6. When the space bar is pressed, the drawing is erased.

How to do this

Setting the current color

All of this task can be handled in a definition of keyPressed(). The value of the key that was pressed is stored in the built-in (i.e. global) variable key. See http://www.processing.org/reference/key.html.

Storing a drawing

The idea is to keep track of a number of "pixels" in your drawing window. Conceptually, this means dividing up the drawing window section into a grid. As the mouse is dragged over one of the squares in the grid, a "dot" is drawn in that square:

This means tracking: the x-coordinate, the y-coordinate, and current color. Use arrays for this.

The x and y coordinates and the total number of these pixels that you want to draw in the drawing window depends on the drawing window size and the desired size of each pseudo-pixel. For example, the images included in this document illustrate a drawing window/rectangle of 600 x 420 pixels (real pixels, not pseudo-pixels), with a top left corner at (100,50). The size of each pseudo-pixel is 60 real pixels, which means that we need arrays that can represent

(600/60) * (420/60) = 10 * 7 = 70

pixels. Each row in this window will have 10 pseudo-pixels, and each column will have 7 pseudo-pixels, which gives a "pseudo-width" (wid) of 10 and "height" (hgt) of 7.

To position the pseudo-pixels, you'll need to do a little math with the value of wid, using the remainder operator and int division operators, % and /. The first 10 pseudo-pixels should be in "row" 0, the next 10 in row 1, and so on. Hence, we can calculate position of any pixel i with

x = i % wid
y = i / wid

In our example here—with pixel size 60, wid 10, and hgt 7—the top left corner of the 0th pseudo-pixel will be at coordinates

(100+((0%10)*60),50+((0/10)*60)) = (100+(0*60),50+(0*60)) =(100,50)

the 1st pseudo-pixel will be at

(100+((1%10)*60),50+((1/10)*60)) = (100+(1*60),50+(0*60)) = (160,50)

Similarly, the 62nd pseudo-pixel will be at

(100+(62%10)*60),50+((62/10)*60)) = (100+(2*60),50+(6*60)) = (220,410)

Recording drawing actions

Determining when to update the drawing from a mouse click or drag is easy: just add definitions for the mousePressed() and mouseDragged() event handlers.

The hard part of this is how: converting the mouseX and mouseY coordinates to the appropriate pseudo-pixel. The following code should help. Let's suppose we're storing the upper left and bottom right corners of the drawing window in the variables (WIN_XUL,WIN_YUL) and (WIN_XLR,WIN_YLR), respectively. Suppose also that the size of our pseudo-pixels is stored in the variable PIXEL_SZ, and that the colors of each pseudo-pixel are kept in the arrays pseudoPixelsR, pseudoPixelsG, and pseudoPixelsB. Finally, we'll suppose that the RGB values of the current drawing color are in the variables, curR, curG, and curB. The following code will compute the correct index in the pseudoPixel array(s):

if (mouseX >= WIN_XUL && mouseX <= WIN_XLR
     && mouseY >= WIN_YUL && mouseY <= WIN_YLR) {
    // Have we clicked inside the drawing window?

    int dx = mouseX - WIN_XUL; // distance from the left edge of drawing window
    int dy = mouseY - WIN_YUL; // distance from the top edge of drawing window
    int scrX = dx / PIXEL_SZ;  // conversion to the drawing window's "x-coordinate"
    int scrY = dy / PIXEL_SZ;  // conversion to the "y-coordinate"

    int i = (wid * scrY) + scrX;

    pseudoPixelR[i] = curR;
    pseudoPixelG[i] = curG;
    pseudoPixelB[i] = curB;
}

Turn In:

Submit the folder containing your Processing sketch and your documentation. This should be a single folder named "project2", which will contain all source code files. Again, the turnin directory is

/afs/afs.hws.edu/classes/cs120/username

Standards

Other Criteria

  1. Your work will be assessed in part on the elegance and clarity of your code, that is, the clarity and simplicity with which you accomplish complicated tasks. This is a somewhat subjective criterion, but it mainly boils down to the idea that there should be exactly as much code as you need to get a job done, neither more nor less, and what's there should be comprehensible to an independent reader.

    As a partial (but not complete list):

  2. Work whose visual presentation reflects a particularly thoughtful attention to grace, detail, and coherence of presentation will count favorably, and vice-versa.

  3. Your source code file must begin with a "header" comment of the following form:

    /*
       <file name> ( < n > of < number of files > )
       Author: <your name>
       CPSC 120, Project 2
       Last modified:  < the date > 
    */
    
  4. Extra credit may be given for the incorporation of ideas you learn on your own that we have not covered in this class. Be sure to document these.


John H. E. Lasseter