|
This lab is all about writing functions, especially recursive ones!
To that end, you are going to create programs that create fractal images:
Fractals have lots of applications in engineering and pure mathematics. Makefile and SubmissionDownload and use this Makefile. Add compilation details for each part. Use the following terminal command for submission.~/bin/submit -c=IC210 -p=lab11 Makefile part*.cpp |
Credit: Feliks Tomasz Konczakowski |
repeat that will be
helpful for drawing the fractal patterns for the rest of the lab.
Download part1.cpp In this file, you will find a main method that is completely written for you, and a prototype for a function that you need to write:
// Prints out the string s, count times in a row,
// in a single line.
void repeat(string s, int count);
repeat
function using recursion.
main() function at all.main at all for this part — just get
repeat working perfectly and submit.
main function
such as
string DIAMOND = "\u2bc1";
As you saw in Project 2, this is a special non-ascii symbol called
Unicode. The important thing to know is that, even though it prints out
as a single symbol in the terminal, it has to be stored as a string and not a
single char.
We’ll use these unicode symbols in the rest of the lab!
repeat function
into the part2.cpp file to get started on this part.
Our first fractal image will be a one-dimensional visualization of the Cantor Set. This is an important mathematical set with some surprising properties: for example, it is completely “empty” and doesn’t contain any sub-interval of the real line, but it simultaneously has more elements than all of the possible fractions (in terms of cardinality).
But all that doesn’t matter to us; we are just drawing some ASCII art!
part2.cpp that reads in a size from the user, and
prints out in a single line the Cantor set for that size, using X
and _ characters.
Example runs:
~$ |
Make sure to understand the recursive relations applied in the examples. Width-1 Cantor set = Base case Width-3 Cantor set = Width-1 Cantor set + Width-1 empty region + Width-1 Cantor set Width-9 Cantor set = Width-3 Cantor set + Width-3 empty region + Width-3 Cantor set Width-27 Cantor set = Width-9 Cantor set + Width-9 empty region + Width-9 Cantor set |
Notice how this definition is recursive! The actual Cantor set goes on infinitely into smaller and smaller recursive sets.
X on
the terminal.
_.
Your program will work and look good for any (positive) size that is given, but to avoid specifying the details on rounding the auto-tests will only use powers of 3 for sizes like 1, 3, 9, 27, 81, etc.
You will definitely need a recursive function to print out the Cantor set, something like
void cantor_row(int length);
This function should not include printing a newline at the end of the line (although you should do that in main).
Why not? Well, this needs to be a recursive function that calls itself multiple times, but you only want to print a single newline character for the whole program, not one for each recursive call!
repeat function to print out the multiple
_s.
Now we want to show the step-by-step creation of the Cantor set on multiple
lines, all with the same width. So you should start with a line of all
Xs, then a line with the middle third removed, and so on, ending
with the last line like you printed in your part 1.
See some examples below. Again, we will only run auto-testing on power-of-three sizes, even though your program should print something that looks good for any given size.
|
~$ |
cantor_row(1,1) cantor_row(3,1) cantor_row(3,3) cantor_row(9,1) cantor_row(9,3) cantor_row(9,9) cantor_row(27,1) cantor_row(27,3) cantor_row(27,9) cantor_row(27,27) |
cantor_row() and cout<<endl will
draw only a single line.
In order to draw multiple lines, write a recursive function canter_set()
appropriately.

~$ ./part4 size: 1 Width-1 Sierpinski carpet: ♦ ~$ ./part4 size: 3 Width-3 Sierpinski carpet: ♦♦♦ ♦ ♦ ♦♦♦ ~$ ./part4 size: 9 Width-9 Sierpinski carpet: ♦♦♦♦♦♦♦♦♦ ♦ ♦♦ ♦♦ ♦ ♦♦♦♦♦♦♦♦♦ ♦♦♦ ♦♦♦ ♦ ♦ ♦ ♦ ♦♦♦ ♦♦♦ ♦♦♦♦♦♦♦♦♦ ♦ ♦♦ ♦♦ ♦ ♦♦♦♦♦♦♦♦♦ ~$ ./part4 size: 27 Width-27 Sierpinski carpet: ♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦ ♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦ ♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦ ♦♦♦ ♦♦♦♦♦♦ ♦♦♦♦♦♦ ♦♦♦ ♦ ♦ ♦ ♦♦ ♦ ♦ ♦♦ ♦ ♦ ♦ ♦♦♦ ♦♦♦♦♦♦ ♦♦♦♦♦♦ ♦♦♦ ♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦ ♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦ ♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦ ♦♦♦♦♦♦♦♦♦ ♦♦♦♦♦♦♦♦♦ ♦ ♦♦ ♦♦ ♦ ♦ ♦♦ ♦♦ ♦ ♦♦♦♦♦♦♦♦♦ ♦♦♦♦♦♦♦♦♦ ♦♦♦ ♦♦♦ ♦♦♦ ♦♦♦ ♦ ♦ ♦ ♦ ♦ ♦ ♦ ♦ ♦♦♦ ♦♦♦ ♦♦♦ ♦♦♦ ♦♦♦♦♦♦♦♦♦ ♦♦♦♦♦♦♦♦♦ ♦ ♦♦ ♦♦ ♦ ♦ ♦♦ ♦♦ ♦ ♦♦♦♦♦♦♦♦♦ ♦♦♦♦♦♦♦♦♦ ♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦ ♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦ ♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦ ♦♦♦ ♦♦♦♦♦♦ ♦♦♦♦♦♦ ♦♦♦ ♦ ♦ ♦ ♦♦ ♦ ♦ ♦♦ ♦ ♦ ♦ ♦♦♦ ♦♦♦♦♦♦ ♦♦♦♦♦♦ ♦♦♦ ♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦ ♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦♦ ♦ ♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦ |
Your task is to make a program Here’s the recursive definition: A n * n Sierpinski carpet divides the square into 9 smaller (n/3) * (n/3) squares.
See sample runs on the left. To make this look good, we don’t want to use X’s and underscores this time.
Instead, use actual spaces
Hints
|
carpet_row, using the example of printing the 13th row
of a width-27 carpet by calling
carpet_row(27, 12).
Here is the image we are trying to produce, with this particular row highlighted in red, and with the 9 sub-regions outlined in blue:
|
So now we can see that this row (in red) needs to go through three parts:
The most important thing to remember is to use recursion - it's very powerful and will help your program stay simple! If you find your self writing many complicated if/else cases and very long functions, ask for help because you are probably going in the wrong direction. |
A well-written recursive program will be nice and simple at the end, but it can be tricky and take lots of patience to get there. You will have to think hard about what you want the program to do, and then be very patient and thorough in debugging.
|
|
The Sierpinski
triangle is one of the most famous and beautiful fractal patterns.
It consists of three half-height Sierpinski triangles (recursive!) arranged with
an upside-down blank triangle in between them.
See on the left some example runs to show how your program should work. For this program, you should use a triangle character to print the base case of a 1x1 triangle using this string:
Print the inside spaces of the triangle with a dot character
Similar to before, we will only perform auto-tests at power-of-two sizes like 1, 2, 4, 8, 16, 32, etc., but it might be fun to make your program work somehow for any possible size. Note that the size given is the height of the triangle your program should create; the width should be 2h-1. I want you to work hard and figure this out, but here are a few hints:
|