Homework 18: Concentric Circles
Concepts
Focus on just one concept for this assignment: using a recursive strategy to encapsulate and re-use .
Recursion (Functions that Call Themselves)
You may have noticed in a previous assignment how a function can call another function (eg, captureString could have used prompt to display a message). What happens when we have a function that calls itself? Consider this implementation of pow
:
return (base * pow(base, (exponent - 1)) );
}
Yikes, what is going on here? This function returns the base it receives times the result of pow(base, expontent - 1)
, then returns that value to the caller. But there's a problem. Let's take a look at calling pow(2, 3)
.
Call | Return value |
pow(2, 3) | 2 * pow(2, 2) |
pow(2, 2) | 2 * pow(2, 1) |
pow(2, 1) | 2 * pow(2, 0) |
pow(2, 0) | 2 * pow(2, -1) |
pow(2, -1) | 2 * pow(2, -2) |
Uh oh!
The problem in the above code is that the function will run "forever." Why? Because there is no "stopping condition." When you are implementing a recursive function, you should first decide "what is the stopping condition" or "what is the most simple case of this function that can return a value, rather than call itself?"
Let's fix the above implementation. What is the "most simple case" in the above implementation? When exponent
is 1
, we can just return base
since any base raised to the power of 1
is the value of the base (21
is 2
). Let's take a look:
if (exponent == 1) {
return base;
} else {
return (base * pow(base, (exponent - 1)) );
}
}
That's better. This function will recurse until it gets to "the bottom" where exponent
is 1
. When pow(2, 1)
gets called, it merely returns 2
, rather than making another call to itself.
Call | Return value |
pow(2, 3) | 2 * pow(2, 2) |
pow(2, 2) | 2 * pow(2, 1) |
pow(2, 1) | 2 |
The point we are emphasizing here is that you should try to think of stopping conditions in recursive function definitions first. Otherwise, you'll likely end up with an unintended result or a recursive function that does not stop. Can you say, "Stack Overflow?"
Instructions
Bend your mind a little and try your hand at implementing a recursive function that results in a series of concentric circles to be drawn on the screen. An example might look like this:
For this assignment, you should define a function called drawConcentricCircles that:
- Returns "nothing" to its caller.
- Accepts three integer parameters: one for the x coordinate of the center, one for the y coordinate of the center, and one for the radius of the circle to be drawn.
This function should:
- First check to see if it should stop, doing nothing, and simply return to its caller.
The function should stop its recursion if the radius parameter is less than or equal to 3. - Otherwise, it should create a random color, draw a circle (use ofCircle) and then call itself, drawConcentricCircles, passing it the same x/y center coordinates but a radius value that is decreased by 5.
Your draw function should consist of one function call to drawConcentricCircles.
Hints
Start with draw. What does it need to do? Merely call drawConcentricCircles passing it three integer values.
Next, implement drawConcentricCircles. What does it need to do? (see above)
If you don't want to use random colors, can you think of a way of enhancing drawConcentricCircles such that you can pass it some additional parameters for the color to be used? If you do this, how might drawConcentricCircles modify the color parameters for each recursive call? (Hint: it's similar to how radius is handled).
Requirements and Rubric
A friendly message from The Terminator, our grading program
*bzzzt* *buurpt*. Oh, excuse me. I will check for the following:
Your program's draw function must call drawConcentricCircles only once.
drawConcentricCircles must call itself.
Thank you. Not "so much," but thank you.
This work is worth 70 points.
Requirement | Points | Notes |
---|---|---|
Place your name in the comment header in main.cpp | 5 | |
Correct submission of src directory as a .zip file. | 5 | |
Correct definition of drawConcentricCircles |
50 | |
draw makes only one call to drawConcentricCircles | 10 |
Concepts Exercised: functions, abstraction, reuse, syntax, recursion, graphics, animation
© 2012 Yong Joseph Bakos.