Topics:

1. Drawing a "complicated" object (smiley face)
   - creating procedures to carry out meaningful tasks (e.g. draw a smiley face)
   - calculating relative coordinates

Drawing a complicated object (smiley face)

The goal is to create the following drawing:
(click to enlarge)
In this example we used the capabilities of the graphics library and created our own procedure for drawing a smiley face. This procedure allows us to draw smiley faces of different sizes while scaling appropriately the features of the face, so that small faces have relatively small features and bigger faces have relatively bigger features. In our setup we had the following requirements: - the radius of each eye is 1/3 of the face radius - the horizontal (x) distance between the face center and each eye is 1/3 of the face radius - the vertical (y) distance the face center and the eye line is 1/3 of the face radius Finally we have the following problem:
Goal: Given a pair of (x, y) coordinates and a radius value draw a smiley face centered at 
the given (x,y) location and of the given size (radius) such that the smiley face features 
are spaced and sized as indicated above.
Drawing the smiley We first setup the description of the procedure that does the actual drawing: - it returns nothing -- thus we use the keyword void - it is named drawSmiley (any appropriate name would work) - it takes three inputs: x, y, radius all of which are numbers the Java keyword double indicates that an input is expected to be a number Here is the skeleton of the procedure. For clarity instead of x, y, radius we have used the slightly longer names faceX, faceY, faceRadius for the inputs. Also later there will be many position and size components, so the new names are chosen to be specific to the thing we are drawing.
void drawSmiley( double faceX, double faceY, double faceRadius )
{

}
Note: For now the meaning of void is that we are creating a new command/procedure.

Note: The keyword double indicates that the variable/PostIt is a number.
Drawing the smiley -- the face only We worked in stages. First we made sure we can draw appropriately sized yellow blobs at the specified locations.
void drawSmiley( double faceX, double faceY, double faceRadius )
{   
    // draw the face                                        
    canvas.drawCircle( faceX, faceY, faceRadius, "yellow" );
}
Here is the final code for the smiley along with sample test cases:
public class SmileyApp
{
    void drawSmiley( double faceX, double faceY, double faceRadius )
    {
        canvas.drawCircle( faceX, faceY, faceRadius, "yellow" );
    }

    public void run()
    {
        drawSmiley( 150, 200, 60 );
        drawSmiley( 10, 20, 8 );
        drawSmiley( 300, 350, 70 );
    }
}
Drawing the smiley -- adding the left eye Next we added the left eye. We had a design that specified how to compute the location and size of the eye from the face information. Java allows us to create PostIt notes on which to write/compute new information. To draw an eye need to know its (x,y) position and size/radius, so we created three PostIts eyeX, eyeY, eyeRadius and wrote on each the corresponding formula from our design above. eyeX = faceX + 0.3*faceRadius eyeY = faceY - 0.3*faceRadius (in our case "above" means subtract) eyeRadius = 0.2*faceRadius Note that a person's eye is placed at a distance relative to that person's nose and this is what the formulas above indicate. For example: start at nose plus short distance away ----- -------------- eyeX = faceX + 0.3*faceRadius Here is the code for the left eye. Note that to go up in Y direction we have to subtract:
void drawSmiley( double faceX, double faceY, double faceRadius )
{
    // draw the face
    canvas.drawCircle( faceX, faceY, faceRadius, "yellow" );
    
    // draw the left eye                                
    double eyeX = faceX + 0.3*faceRadius;               
    double eyeY = faceY - 0.3*faceRadius;               
    double eyeRadius = 0.2*faceRadius;                  
    canvas.drawCircle( eyeX, eyeY, eyeRadius, "black" );
}
Drawing the smiley -- adding the right eye The right eye is similar but we go left from the nose, so need to subtract in the X direction: eyeX = faceX - 0.3*faceRadius eyeY = faceY - 0.3*faceRadius (same as left eye) eyeRadius = 0.2*faceRadius (same as left eye) Here is the code for the right eye. Notice that we only recompute eyeX. The other PostIts can be reused, since the two eyes have the same size and Y level.
void drawSmiley( doublefaceX, double faceY, double faceRadius )
{
    // draw the face
    canvas.drawCircle(faceX, faceY, faceRadius, "yellow" );

    // draw the left eye
    double eyeX = faceX + 0.3*faceRadius;
    double eyeY = faceY - 0.3*faceRadius;
    double eyeRadius = 0.2*faceRadius;
    canvas.drawCircle( eyeX, eyeY, eyeRadius, "black" );
    
    // draw the right eye -- only the x coordinate needs to be updated
    eyeX = faceX - 0.3*faceRadius;                                    
    canvas.drawCircle( eyeX, eyeY, eyeRadius, "black" );              
}
Note: In the expression

    eyeX = faceX - 0.3*faceRadius;

there is no keyword double. The keyword double indicates that we are creating a PostIt
(a variable). Since eyeX has already been created earlier we do not specify double anymore
when we use eyeX -- it is an error to put double every time for the same PostIt.
Here is the final code for the smiley along with sample test cases:
public class SmileyApp
{
    // draws a smiley face centered at the given "(x,y)" and of the given "radius"
    // the face features are scaled relative to the face radius
    void drawSmiley( double faceX, double faceY, double faceRadius )
    {
        // draw the face
        canvas.drawCircle(faceX, faceY, faceRadius, "yellow" );

        // draw the left eye
        double eyeX = faceX + 0.3*faceRadius;
        double eyeY = faceY - 0.3*faceRadius;
        double eyeRadius = 0.2*faceRadius;
        canvas.drawCircle( eyeX, eyeY, eyeRadius, "black" );

        // draw the right eye -- only the x coordinate needs to be updated
        eyeX = faceX - 0.3*faceRadius;
        canvas.drawCircle( eyeX, eyeY, eyeRadius, "black" );
    }

    public void run()
    {
        drawSmiley( 150, 200, 60 );
        drawSmiley( 10, 20, 8 );
        drawSmiley( 300, 350, 70 );
    }
}