The Graphics Package of the Big C++ Book

Goals

By the end of this lab you should:

Introduction

The text book for this course supplies a very simple graphics package that will allow you to draw shapes and text in a window. Although at first you might think that there is little you can do with Points, Lines, Circles, and Messages ( text ); you will likely be surprised at how much is actually possible. For instance, the current students in cs10 are writing a "Moon Lander" game using this package, and by the end of this class you will have written a suite of programs which use the graphics package as well.

Compiling for the Graphics Package

Writing code for use with the graphics package will be a bit different than you're used to, though not really any more difficult. When writing code for the graphics package you must sharp include "ccc_win.h". The first major difference that you will encounter is that you aren't really writing the main function. You simply write a function that the main calls. The function that you write must be named "ccc_win_main()" and return an integer type. Even though you are only writing a function, and not the main, this is only a shift in paradigms and has absolutely no effect on how the code is written. For all intensive purposes you are really writing the main and just using a different name.

If you were working on your own machine, you would go to the books web site, download all of the code for the graphics package, and put it somewhere on your hard drive. Things are a bit different here at school because you only have so much space in your account. Because of this limitation, and the logistics of getting everyone to download everything and agree where to put it, systems has downloaded a single copy of the files and made them available to everyone. All of the ".h" files for the graphics package have been placed in a location where the compiler will be able to find them.

For this course we will use the make utility to compile all of our programs. How the make utility works will be covered in the next lab, so for now we will just use it and not delve into the details.

For now this is what you need to know about the make utility:

For this lab, as well as for the first assignment a makefile will be provided for you.

Graphics Objects

The graphics objects represent the simplest geometric constructs, and basic text. The geometric constructs are the Point, Line, and Circle. Text is represented by a Message object. By using these objects together, you can actually develop some fairly sophisticated drawings. All of the objects have a very similar interface. Every object can be created, moved, and queried for it's defining characteristics. The following sections describe each object in more detail.

Point

The Point is simply a ( x, y ) pair representing a coordinate in the window. The interface of the Point object is described in the table below.

Functions of the Point Class
Name Purpose
Point( x, y ) Constructs a point at location ( x, y )
p.get_x() Returns the x-coordinate of point p
p.get_y() Returns the y-coordinate of point p
p.move( dx, dy ) Moves point p by the displacement ( dx, dy )

If you wanted to create a point in the center of the drawing area and then move it 3 units to the left, your code might look something like the following:

Point my_point( 0, 0 );
my_point.move( -3, 0 );
    

Circle

A Circle is defined by a Point and a radius. The interface of the Circle object is described in the table below.

Functions of the Circle Class
Name Purpose
Circle( p, r ) Construct a circle with center p and radius r
c.get_center() Returns the center point of circle c
c.get_radius() Returns the radius of circle c
c.move( dx, dy ) Moves circle c by the displacement ( dx, dy )

Line

If you think hard back to when you took geometry in high school, you'll likely remember that in Geometry class two Points were required to define a line. Its no different with the graphics package supplied by the text. However, take note that in the graphics package not all points in a Line are created equal. One Point is the "starting Point" and one is the "ending Point." The interface of the Line object is described in the table below.

Functions of the Line Class
Name Purpose
Line( p, q ) Constructs a line jointing points p and q
l.get_start() Returns the starting point of line l
l.get_end() Returns the ending point of line l
l.move( dx, dy ) Moves line l by the displacement ( dx, dy )

Message

Message objects are used to display text and numbers in the graphics window. You can create a Message object using either a string or a numeric type such as int or double. The interface of the Message object is described in the table below.

Functions of the Message Class
Name Purpose
Message( p, s ) Constructs a message with starting point p and text string s
Message( p, x ) Constructs a message with starting point p and a label equal to the number x
m.get_start() Returns the starting point of message m
m.get_text() Gets the text string of message m
m.move( dx, dy ) Move the message m by the displacement ( dx, dy )

Input/Output for the Graphics Window

In order to display any of the graphic objects that you create, you must give them to a GraphicWindow object. A GraphicWindow object is created for you when you sharp include "ccc_win.h". The name of the GraphicWindow object is cwin. The GraphicWindow object has been designed to function very much like the stream objects that you are used to using in regular programs. ( namely cout ) When you want to display a shape on the window area you use cwin with the insertion operator ( << ). For example, you could create a Point and display it in the window with the following code.

Point my_point( -5.25, 2.75 );
cwin << my_point;
  

By default the drawing window is a 20 x 20 grid with the coordinate ( 0, 0 ) positioned in the center of the window. However, you can change the size of the grid and the area of the coordinate system that it displays if it suits you purposes. For instance, you may want to draw a graph that plots the number of hours that you sleep against the number of lines of code that you write the following day. On the y-axis you want to range from ( 0 to 24 ), on the x-axis you want to range from ( 0 to 1000 ). You can set up the coordinate system to your liking with the following line of code.

cwin.coord( 0, 24, 1000, 0 );
  

The first two numbers represent the upper left hand corner of the drawing window, and the last two numbers represent the lower right hand corner of the drawing window. Although virtually any coordinate system is valid, note that the graphics package will draw everything inside of a square. So, if you use a set of coordinates that forms a rectangle, one of your dimensions will be squished.

The interface of the GraphicWindow object is described in the table below.

Functions of the GraphicWindow Class
Name Purpose
w.coord( x1, y1, x2, y2 ) Sets the coordinate system for subsequent drawing: ( x1, y1 ) is the top left corner, ( x2, y2 ) is the bottom right corner
w << x Displays the object x ( a Point, Circle, Line, or Message ) in window w
w.clear() Clears window w ( erases its contents )
w.get_string( p ) Displays prompt p in window w and returns the entered string
w.get_int( p ) Displays prompt p in window w and returns the entered integer
w.get_double( p ) Displays prompt p in window w and returns the entered floating-point value
w.get_mouse( p ) Displays prompt p in window w and returns the mouse click point

A Simple Example

The following program produces a "self-portrait" in the drawing window. Note the use of a rectangular coordinate system in order to produce oval shapes. Feel free to download the Makefile and ccc_main.cpp file and run the program yourself.

#include "ccc_win.h"

int ccc_win_main()
{
  // draw the head
  Circle head( Point( 0, 0 ), 8 );
  cwin << head;

  // draw the nose
  Point bridge( 0, 2 );
  Point left_nos( -1, -1 );
  Point right_nos( 1, -1 );
  cwin << Line( left_nos, bridge )
       << Line( bridge, right_nos )
       << Line( right_nos, left_nos );

  // change the coordinate system so that we can
  // draw ovals
  cwin.coord( -10, 40, 10, -40 );

  // draw the mouth
  Circle mouth( Point( 0, -15 ), 3 );
  cwin << mouth;

  // draw the eyes
  Circle eye( Point( -3, 15 ), 1.75 );
  cwin << eye;
  eye.move( 6, 0 );
  cwin << eye;

  // put pupils in the eyes
  // notice that yet another coordinate system is used here
  cwin.coord( -40, 40, 40, -40 );
  Circle pupil( Point( -12, 15 ), 1.5 );
  cwin << pupil;
  pupil.move( 24, 0 );
  cwin << pupil;

  return 0;
}
  

Self Portrait

Think about the following questions: How might you zoom in or out on a drawing by changing the coordinate system? How might you draw a solid ( filled in ) shape?