Improved clocks (OPTIONAL)
The goal of this lab is to clean up all your clock drawing code. Make
one or more of the following improvements as you see fit.
Clean up the teaching program
Convert your clock teaching program which uses procedures.
I recommend you actually combine the teaching program and the
time-zone clock drawing program, adding any additional procedures as
needed. Simple changes to main() will determine whether you
want to display time zones, or if you want to teach a kid to tell time.
I'll start you off with a few suggestions:
-
Write a procedure, normalizeAngle which takes an angle
and adds or subtracts 2*PI; as needed until the angle is between -PI
and PI.
- Use normalizeAngle to write a procedure
anglesAboutEqual which checks if the difference in two angles
is within a reasonable tolerance.
- There are two significant problems with using atan() to
determine the angle of the mouse-click.
First, atan() comes out the same for a point, p =
(x,y), and it's reflection about the origin,
p' = (x',y'). Second, if x is 0 (or
nearly zero) then y/x is infinite (or huge).
Write a procedure atan(x, y) which behaves
like atan(y/x), with some improvements.
Basically, it only calls atan() if the point lies in the
first quadrant, and beneath the line y = x. Otherwise,
use the following facts to bring the point to within this region:
- If the point is in the 2nd or 3rd quadrants, reflect the
point about the origin, calculate the atan, and add PI to the
result.
- If the point is in the 4th quadrant, reflect the point about the
x-axis, compute the atan and negate the result.
- If the point is in the 1st quadrant, and above y =
x, reflect the point about y = x, compute the
atan, and subtract the result from PI/2. (Reflecting a point
about y = x is done by simply reversing x and y.)
Animating your clock
You can animate your clock if you wish. Add a second hand so
you can see the animation. You'll need a few new ideas:
- You'll need to clear the graphics window and redraw. See page
657 for a summary of the graphics commands.
- If you refresh too often, the window will blink anoyingly. Use
sleep(1) to sleep for 1 second between refreshes.
- Lastly, the graphics window buffers graphics. It only
get around to displaying your graphics when (a) the buffer gets full,
(b) you perform a get_mouse or (c) you exit. The following
code will fill the buffer and force a redraw:
for (int i=0; i<50; i++)
cwin << Point (10,10);