TURN IN THIS ASSIGNMENT USING WEBWORK!!!
Do this homework using DrScheme. (Save the file as a ".scm" file--that is, with a .scm extension.)
Your parameters must be in the same order as they are shown here. If you are unsure, ask your TA. You will lose credit otherwise.
Your functions should be named exactly as they are shown in each problem.
Follow the HW Skeleton, these homeworks will be autograded and must be in the specified format. You will lose credit otherwise.
Any submissions which don't execute cleanly (i.e. no errors when you click Execute) may receive a grade of zero.
If you do not submit a .scm file, you may receive a grade of zero.
Remember that you must be in "Advanced Student Scheme".
Remember to retrieve and verify your submission from WebWork to ensure that it was transmitted accurately.
For all problems, you should read the words program and function to mean "program or group of programs," or "function or group of functions."
0. This extra is all about fractals! Most people find the fractals
assignment to be both very challenging and rewarding - because,
after all the work, you get to see the drawings being done before
your very eyes.
To preview the fractals you will be drawing, check out the
collection of images at:
www.prism.gatech.edu/~gtg121a/images/CompSci/Spirals
Each fractal requires a large set of helper functions, so you must
get started early and split the work up over several sessions.
1. This assignment is to be done on an *entirely* individual basis.
No collaboration whatsoever is permitted, except for assistance
from TAs on Phase 1 ONLY. The work you turn in from then on must
reflect entirely your individual effort on the fractals.
2. This assignment is worth 200 points towards your homework grade.
3. PHASE 1 MUST BE COMPLETED TO RECEIVE ANY CREDIT. Drawing the
rest of the fractals, however, is entirely up to you. You will
receive credit for each portion that you complete fully.
4. For the fractals that you choose to turn in: it's all or nothing!
Either everything is there and it functions and draws correctly
or - if it doesn't work or the documentation is missing, you get
no credit for that phase.
ASSIGNMENT NOTES:
0. Be sure that you are in Advanced Student mode and turn in a .scm
file when you are finished.
1. All functions (whether local or global) require a Contract and
Purpose ONLY. You will also be expected to have test cases
that will display each fractal in a separate canvas window
(details below).
2. DO NOT define the posn structure - it is predefined and the
built-in drawing functions do not work with "redefined" posns.
3. DO NOT define pi. The accuracy of the fractal depends highly on
the significant digits of the built-in pi definition.
4. Most of the fractal drawings require some basic knowledge of trig.
You may find it helpful to review your sines, cosines and radians.
5. Keep in mind each fractal may require several functions besides
ones mentioned directly. Making good design decisions and writing
abstractions where necessary will save you some large headaches.
======================================================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PRELIMINARY PHASE - Screen info & drawing exercises ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Before we dive headfirst into drawing fractals, it is important to get
familiar with how on-screen graphics work. It's quick and painless,
so pay attention:
----------
(a) On-screen graphics use a slightly different coordinate system than
what you are used to. Computers start counting pixels from the
UPPER left-hand corner, with the x axis horizontal as usual, but
the y-axis directed DOWNWARD instead of upward. This makes things
slightly confusing - everything is "upside down" vertically, but
the horizontal directions are the same as always.
(b) The origin is therefore at the top left of the screen, and a point
coordinate such as (make-posn 200 100) is actually found by taking
200 pixels across, and 100 pixels *downward* from that top-left
corner:
SCREEN:
origin
o---------------------------------------> x-axis
|(0,0)............(200, 0)
| .
| .
| .
| P = (200, 100) - that's 200 across, 100 downwards
|
|
|
|
V
y-axis
whereas in Cartesian coordinates, you would count 200 across and
then 100 upwards. You'll get used to it - don't worry.
(c) Rotations around the origin therefore become *clockwise* for
positive angles instead of counterclockwise. This will become
apparent later, when you see it drawn on screen. Just remember,
if you want to rotate something the regular way, you have to plug
in a *negative* angle.
----------
Now that you know a little bit about on-screen coordinates, we can start
the fun stuff - drawing pictures! Finally you'll be able to show your
mom something cooler than lists and vectors:
(a) From the Language menu in Dr. Scheme, Add Teachpak: draw.ss
(b) Hit Execute! You should see a teachpak message in the interactions
window.
(c) From the Help Menu, pull up the Help Desk and click on the
"Teachpaks" category. Read the (very brief) documentation for
draw.ss to get familiar with all the drawing functions.
Particularly useful for this project:
(start x y)
(draw-solid-line p1 p2 'color)
(draw-circle ctr rad 'color)
Note which symbols are legal color symbols, and try drawing a few
circles and lines of any colors:
(begin
(start 500 500) ;; <-- a large canvas
(draw-solid-line (make-posn 0 0) (make-posn 100 300) 'blue)
(draw-circle (make-posn 200 200) 150 'red))
What happens when you leave the optional color argument off?
What gets returned *each time* you draw to the screen?
(for contracts, later...)
Experiment a little bit and you'll quickly get the hang of passing
in coordinates and drawing them where expected.
----------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PHASE 1 - CONSTANTS AND GEOMETRY - 50 pts ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In order to set the stage for drawing complex patterns like fractals,
you must get certain mundane details out of the way:
1. CONSTANTS:
(a) Define two constants - one for the width of the canvas, one for
the height. Set them to something fairly large, between 300 and
500 or so (500x500 is good). Whenever you use the (start ...)
command, insert these two constants from now on, instead of
actual numbers for the dimensions.
(b) Define the center of the canvas, using the previous constants.
The center should be a posn, and it should depend on the
dimensions defined above - if the screen constants are changed
to other values, the center should still be valid, without
the need for changes to the code.
(c) Define a constant for the radius of a large circle, using the
two constants from part (a). The radius will be exactly TWO
FIFTHS the size of the smallest of the two dimensions: that is,
either 2/5 of the height or the width, whichever is smallest.
You may use the function (min ... ) in your definition.
If the screen constants are changed, this radius should change
accordingly, without needing any updates - much like the center.
(d) Define the top of the circle (a posn that is directly above the
center of the circle, lying on the circle's radius). It should
also completely depend on the previous definitions.
FOR THIS ASSIGNMENT, YOU MUST INCLUDE ALL TEST CASES SHOWN.
Include the following, replacing the items in BOLD by your
defined constants, and fill in any valid color symbol:
;; Test:
(start WIDTH HEIGHT)
(draw-solid-disk CENTER RADIUS 'any-color)
(draw-solid-line CENTER TOP 'any-color)
Make sure these tests work for any arbitrarily sized canvas!
The circle should not get "cut off" by the edge of the screen.
----------
In order to run the fractal algorithms, we will need to rotate points
around other points on the screen:
2. ROTATIONS:
(a) Define a function called rotate. It should take a posn and
an angle measured in *radians*, and rotate that posn about the
origin, by that angle. We will use the old rotation matrix from
your MatLab assignment - to refresh your memory, here it is:
Given a posn with coordinates (x,y), the coordinates for the new
posn (x',y'), rotated through angle theta, are given by:
x' = x*cos(theta) - y*sin(theta)
y' = x*sin(theta) + y*cos(theta)
You will have to make use of Scheme's (sin ...) and (cos ...)
functions to work this formula.
Remember to test with angles in radians, such as (* 2 pi) and
(* 1/2 pi), Scheme's sine and cosine do not take regular
degrees!
Include the following:
;; Test:
(rotate (make-posn 1 0) (* pi 2))
(make-posn 1 0)
Remember to include all shown test cases. If you get imprecise
numbers, prefixed with #i..., that's fine - just estimate where
exactly they lie. In most cases 0 will appear as #i...e-017 or
e-16.
It is not always the case that we want to rotate about the *origin*
per se. For most of our work, we will need to have a different point
about which to rotate.
(b) Define a function called rotate-about. It should be called
in the following manner:
(rotate-about <center> <point> <angle>)
It should rotate the given point about the given "center" point,
instead of about the origin.
Using a local, you may wish to save the vertical and horizontal
displacements between the two points as two local constants:
dx = Px - Cx
dy = Py - Cy
Rotate those about the origin, and once they are rotated, return
the posn resulting from those displacements *off the center
point!* Thus the new coordinates x' and y' are given by:
x' = Cx + Rx
y' = Cy + Ry
Where R stands for the rotated displacements.
Include the following:
;; Test:
(rotate-about (make-posn 5 5) (make-posn 6 5) pi)
(make-posn 4 5)
Think about how this works: (6,5) rotating around (5,5) is just
like (1,0) rotating about (0,0). After pi radians, the new posn
lands on (-1, 0) - exactly 180 degrees away - and then we use
that to gather the relative distance from (5,5) in the original
problem. The rotated point is therefore (5-1, 5+0) or (4,5).
Sketching this on paper geatly helps to visualize everything.
Again you may get imprecise numbers - but they should be awfully
close to 4 and 5, in that test case.
-----------
3. MISCELLANEOUS GEOMETRY:
(a) The distance formula always comes in handy - so define it!
Note however: this is not the distance from a point to the
origin, this is the distance between *two points*.
Test carefully - otherwise you'll never be looking for a
mistake here later...
Recall: dist[P1P2] = sqrt[ (dx*dx) + (dy*dy)]
dx and dy are the horizontal and vertical distances, given by:
dx = p2x - p1x
dy = p2y - p1y
Include the following:
;; Test:
(dist (make-posn 0 3) (make-posn 4 0))
5
(b) Finally, for each of these fractals we will need to move points
towards other points, shifting them in a certain direction by
a certain factor of distance.
Write a function called shift which will take a posn, and move
it towards another posn, by some given percent of the distance
between them. In order to find a good formula for this, make
up a few simple examples and dissect your method of finding the
solution. The function should operate as follows, shifting p1
towards p2:
(shift <p1> <p2> <factor>)
For instance, if I were to move (10,10) towards (20, 20) by 70%,
of the distance between them, where would it land? How did you
get that answer? Write the formula down and then translate it
into Scheme code. You may wish to use a local to save the
horizontal and vertical displacements. Don't forget to add the
scaled displacement back to the original coordinates of p1!
Assume that the percent factor will be given as a decimal.
Include the following:
;; Test:
(shift (make-posn 50 100)
(make-posn 150 200) .40)
(make-posn 90 140)
In this case 50 moves towards 150 by 40% of that distance,
and 100 moves towards 200 by 40% of that distance.
-----------
4. TESTING:
In order to get credit for this phase, the following test MUST be
visible on a fresh canvas, upon hitting Execute in your file!
Simply insert your predefined constants in place of the BOLD
variables in the code to run this:
;; Test:
"TESTING PHASE 1:"
(begin
(start WIDTH HEIGHT)
;; green background:
(draw-solid-disk CENTER RADIUS 'green)
;; rotations:
(do [(i 0 (+ i 1)) ]
[(> i 32) true]
(draw-solid-line
(shift CENTER (make-posn WIDTH HEIGHT) .90)
(rotate-about CENTER TOP (* i pi -1/16) )) ))
This should produce something along the lines of:
If that worked, then that's it! Congrats - you're done with Phase 1,
that's 50 points back on a homework! Now on to the real fun...
--------- FRACTALS ----------
EACH FRACTAL IS COMPLETELY OPTIONAL - YOU WILL GET CREDIT FOR ANY THAT
ARE COMPLETE, SO LONG AS PHASE 1 IS COMPLETE AS WELL.
NOTE:
As a word of info, phase 2 is rather lengthy, while phases 3
and 4 are very closely related to each other - doing one will
help with completing the other.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PHASE 2 - POLYGONAL SPIRAL - 50 pts ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
This phase will deal with spiraling any N-sided polygon and forming an
image such as this:
This function will require a lot of patience and a very good grasp
of geometry. Ready?
We're all familiar with regular polygons:
3 sides - triangle
4 sides - square
5 sides - pentagon
6 sides - hexagon
etc. etc. etc..
Each polygon consists of N sides and N points - edges and vertices.
In Scheme we will represent only the vertices, and we will store them
in a LIST. Why a list? So that there is no limit on how many-sided
the polygon may be. Remember, each point on the polygon is a posn -
therefore our polygon is really going to be: a list of posns.
Keep this in mind, and write your contracts accordingly.
Remember those constants we defined in phase 1? Here is where they
start to come in handy. *All* of your regular polygons will always fit
precisely into the large circle we defined. Their points will all lie
on the circle's edge, so it's just a matter of rotating one point around
that edge to define them all. We will use this to construct a list of
points that will make up the polygon.
------
1. MAKING A POLYGON:
In order to make a polygon of any number of sides, you should begin
with a the circle we defined constants for in phase 1.
All we have to do now is to place N different points on this circle,
spacing them out evenly - and voila! - there is our polygon. If you're
not convinced, try drawing a picture. You can inscribe *any* regular
polygon into a circle (see screenshot below).
In order to space the points out evenly along the circle's edge, we
will use rotation. Starting at the topmost point (also a defined
constant) we will rotate in evenly spaced increments and mark off each
point until we come around full circle. We will also include the
first point *again* at the end of the list, in order to close the
polygon fully - back to front.
(a) Write a function called make-polygon. It will take a number, N,
and construct a list of N+1 posns. There are really only N
distinct points - the reason we will have N+1 is because we will
attach the initial point both at the beginning AND at the end of
the list of posns, in order to close the polygon when drawing.
Begin with the "top" point, defined in phase 1. Using either
recursion or iteration, build a list of points given by rotating
that top point in even increments. You could make use of "local"
and define the correct increment as a local constant. Stop when
the rotation angle becomes greater than 2*pi, but make sure you
repeat the initial point once at the end of your list!
Remember to use radian measure for angles! You will have to divide
the full circle of 2*pi radians into N evenly spaced increments.
The last point should simply be the "top" point repeated again.
You will see in part (3) why this is useful.
Remember each point should be rotated about the CENTER point
defined as a constant in phase 1. Do not just rotate about the
origin.
If the user asks for a 0 sided polygon or less, you must return
an empty list.
;; Test carefully!
(make-polygon 5) ;; <-- a pentagon
(list
(make-posn #i249.99999999999994 #i50.0) ;; <-- approx (250, 50)
(make-posn #i59.78869674096927 #i188.19660112501055)
(make-posn #i132.4429495415054 #i411.8033988749895)
(make-posn #i367.55705045849464 #i411.80339887498945)
(make-posn #i440.21130325903073 #i188.19660112501052)
(make-posn 250 50)) ;; <-- notice this one is duplicated!
This test case is for a 500x500 canvas - yours may differ slightly
if you choose different dimensions for your screen.
Note: the point (250, 50) is the "top" point and appears twice,
both at the beginning and at the very end of the list.
Note that those posns MUST form a regular pentagon. The easiest
way to check that is to write the function in part (2) and draw
your result to the canvas.
-------
2. DRAWING A POLYGON:
Reading a list of points is not that exciting - the real way to test
your polygons is to actually draw them and see the shapes for
yourself! Here is where you'll need the drawing function:
(a) Given a polygon (which is a list of posns), write a function that
connects each pair of posns with a line. Call it draw-polygon.
That duplicate point at the end of the list is handy - we have to
connect *all* lines, including the line that connects the last
point right back to the first one - closing the shape.
Since your polygon will have the duplicate point at the end of it,
all you have to do is write a function that connects points until
they run out. That final repeated point will automatically close
the polygon.
Your function should *not* start a canvas, it should only draw.
We will be using this over and over again, and we want to always
draw on the same canvas, not open new ones each time.
Since you need at least a *pair* of posns in the list in order to
draw lines, you will need to terminate your recursion or iteration
when the list no longer contains at least TWO posns. NOT just when
the list is empty!
When you are drawing lines, you may find it helpful to extract both
the (first ...) of the polygon list, and the (second ...). You may
also find it helpful to use a begin statement, to perform more than
one procedure in a row.
Given an empty list, or a list with only one posn - you must return
true, without drawing anything.
Given a one or two sided polygon, your function will draw either a
point or a line, if you coded it correctly. (Even though there is
technically no such thing as a one-sided or two-sided polygon...)
Include the following, so that it comes up on a fresh canvas:
;; Test:
(begin
(start WIDTH HEIGHT)
(draw-solid-disk CENTER RADIUS 'green)
(draw-polygon (make-polygon 5) ))
This should result in:

-----------
3. SHIFTING A POLYGON:
In order to get the spiraling effect, we will need to apply the "shift"
function to each point in the polygon, moving them towards each other
along the sides, by a certain distance. (see the screnshot below)
(a) Write a function called shift-polygon which will move each posn
in the given list (the given polygon) towards the next point, by
a certain factor:
(shift-polygon <polygon> <factor>)
The "factor" is to be used in the "shift" function, to slide each
point towards the next point by that percentage of the distance.
Assume that you will be given a decimal percent, .75 for instance,
for the shifting factor. Simply pass that given factor into your
shift function.
If the given list has at least two points in it, you'll need to use
recursion or iteration to go through the list and shift each point
towards the next point. You may find it helpful to extract both
the (first ...) point and the (second ...) point in the list each
time.
If the given list is empty, or if the given list only contains ONE
point, you must return the given list, without any changes.
BIG HINT:
Shift the first point towards the second, and save that as a local
constant before beginning your recursion or iteration.
At the end of the process, attach that initial point to the very
end of the list in order to close the polygon. Remember our
polygon lists will need to contain the first point duplicated at
the end, in order to be drawn properly. If you simply run this
function without attaching the first shifted point at the end,
then you will find that your polygon will not be closed - it will
be missing a side.
(b) Include the following, to be displayed on a new canvas:
;; Test:
(begin
(start WIDTH HEIGHT)
(draw-solid-disk CENTER RADIUS 'green)
;; Normal pentagon:
(draw-polygon (make-polygon 5))
;; Shifting the pentagon:
(draw-polygon (shift-polygon (make-polygon 5) .20))
;; Shifting twice:
(draw-polygon
(shift-polygon (shift-polygon (make-polygon 5) .20) .20) ))
;; should result in:

------------
4. SPIRALING A POLYGON:
Now you are ready to define the main spiraling function. You are going
to repeatedly shift the polygon by a certain factor, until it spirals
in on itself (nifty animation there). When the points on the polygon
become too close - within 3 to 5 pixels - you may terminate the process.
(a) Write a function called spiral-polygon which will take a number N,
for the number of sides, and a factor F, for the spiraling shift.
Given N for the sides, and a factor F, it should do the following:
1. Start a canvas of the predefined dimensions (from phase 1)
2. Draw a circle (not a disk) of the predefined radius, and of
any color you like.
3. Make and draw a polygon of N sides ONLY IF N<3.
4. Otherwise make a polygon of N sides and pass this polygon
and the spiraling factor to a helper.
(b) Your helper function should do the following:
1. Terminate and return true if the points in the polygon are
within a very small distance of each other (2 to 5 is good).
2. Otherwise draw the current polygon, and then use recursion
on the polygon after it is *shifted by the given factor*.
You will see that running a very small factor (less than 10%)
produces the best results for your test cases.
(c) Include the following screenshots:
;; Tests:
(spiral-polygon 3 .05) ;; triangle
(spiral-polygon 4 .05) ;; square
(spiral-polygon 5 .05) ;; pentagon
(spiral-polygon 6 .05) ;; hexagon
(spiral-polygon 10 .05) ;; decagon
This code must work for any N, not just the above four. It should
not cause errors when the given N is less than 3.
Again, images of each of these examples can be found at:
www.prism.gatech.edu/~gtg121a/images/CompSci/Spirals
You may wish to comment these out when working on Phases 3-4, but
don't forget to un-comment them when turning your file in!
-------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PHASE 3 - CURLY FRACTAL - 50 pts. ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Using a good combination of local and begin you should be able to
outline this fairly complex process. Here is how to generate a curly
fractal (see screenshots below) using recursion:
1. Begin with two points, A and B and draw a line between them:
2. Find a point C, that is exactly 1/2 * sqrt(2) times the distance
AB from point A, along the segment AB. (You have a helper coded!)
3. Rotate that point C about point A by an angle of -1/4 * pi radians.
(That is -45 degrees). This is going to be the "new" point B.
Note that this is a counterclockwise rotation, on-screen. Reread
the preliminary discussion for more info.
4. Use recursion on point A and the "new" point B. Make sure to note
very carefully the order of those two parameters!
5. Now back from the original segment AB, find a point D that is
exactly 1/2 * sqrt(2) times the distance AB from POINT B, along
the segment AB. (Again, using your helper makes this trivial.)
6. Now rotate point D about point B by an angle of +1/4 * pi radians.
(That is +45 degrees). This is going to be the "new" point A.
Note that this is a clockwise rotation - exactly opposite that of
point C.
7. Use recursion on the "new" point A and the original point B. Note
again, carefully, the order of those two parameters!
The next few sequences are shown, supposing you will simply use
recursion on each segment that is generated:
Your task: Write a function called curl, which will take two posns
A and B, and a number signifying the amount of iterations.
The "amount of iterations" signifies how many times the
algorithm should be repeated. The triangles get smaller
and smaller as the process goes on, so after about 15 or so
the details of the fractal are fully rendered.
Your function should start a canvas using the predefined
dimensions, and then perform the above algorithm, generating
the fractal. Once the process has repeated the specified
number of times, the recursion should stop.
In order to keep track of the number of recursions, you may
wish to have a helper function that keeps track of a
"counter" parameter and terminates when that counter reaches
the originally given limit. At that point, simply return
true.
The function should be called as follows:
(curl <p1> <p2> <number of iterations>)
In this call p1 and p2 are posns that will represent the original
starting points A and B for the fractal.
Include a test case that will draw a good picture of the fractal
when Execute is hit. Something like 14 iterations should produce:
This is given by (curl (make-posn 100 200) (make-posn 300 400) 14)
on a 500x500 screen.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PHASE 4 - DRAGON FRACTAL - 25 pts. ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Ever read the old paperback "Jurassic Park"? If you did, you might even
remember the "dragon" fractal shown in various stages of growth between
each chapter heading:
In this phase you will be generating it! The algorithm is very closely
related to that of the curly fractal, except for some tiny, but crucial
changes. Read through the instructions for phase 3 to get familiar with
this. For the dragon fractal, the process is as follows:
1. Begin with two points A and B. Draw a line between them.
2. Locate point C on line AB, which is 1/2 * sqrt(2) times the
distance AB away from point A, along the segment AB.
3. Rotate point C about point A by an angle of 1/4 * pi radians. This
will become the "new" point B. Note that this is a clockwise
rotation, on-screen. Reread the preliminary discussion for more
info.
4. Use recursion on point A and the "new" point B. Make sure to note
very carefully again, the order of those two parameters!
5. Now back from the original segment AB, find a point D that is
exactly 1/2 * sqrt(2) times the distance AB from POINT B, along
the segment AB.
6. Rotate point D about point B by an angle of -1/4 * pi radians.
Note that this is a counterlockwise rotation - exactly opposite
that of point C. Believe it or not this will also become the
"new point B" for your recursive call! Subtle, but very different
from the curly fractal.
7. Use recursion on the original point B and the "new" point B. Note
again, carefully, the order of those two parameters!
The next two sequences are shown, supposing you will simply use
recursion on each segment that is generated:
The remaining iterations (all labeled Itr_X.jpg) can be seen at:
www.prism.gatech.edu/~gtg121a/images/CompSci/Dragons
Your task: Write a function called dragon, which will take two posns
A and B, and a number signifying the amount of iterations.
The "amount of iterations" signifies how many times the
algorithm should be repeated. The triangles get smaller
and smaller as the process goes on, so after about 15 or so
the details of the fractal are fully rendered.
Your function should start a canvas using the predefined
dimensions, and then perform the above algorithm, generating
the fractal. Once the process has repeated the specified
number of times, the recursion should stop.
In order to keep track of the number of recursions, you may
wish to have a helper function that keeps track of a
"counter" parameter and terminates when that counter reaches
the originally given limit.
However, if you simply leave it at that, you will notice
your rendering of this fractal contains many unslightly
"construction" lines. It is not a clean curve as in the
screenshot below. You will have to deviate slightly from
the given algorithm...
Your task: Devise a way to eliminate the drawing of those intermediate
lines, and to only draw the final curve. Where should you
give the (draw-solid-line ...) command?
Your function should be called as follows:
(dragon <p1> <p2> <number of iterations>)
Here p1 and p2 are posns representing the original A and B used
as the starting points for your fractal.
Include a test case that will draw a good picture of the fractal
when Execute is hit. Something like 12 iterations should generate
the example shown at the top of this section.
Fewer iterations will generate a less detailed rendering:
---------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MULTI-COLOR BONUS - 25 pts. ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Adding at least two colors to each of your fractals will earn you
an extra 25 pts. (No, black and white do not count as extra colors!)
Colors and variations can make the fractals look quite intriguing:
--------
END NOTE: Before you turn the assignment in, check carefully to make
sure that you have included Contract & Purpose for EVERY
function that you have written. NO CREDIT is given for
functions without documentation!
Make sure that when you hit Execute, the required screenshots
on this page all come up, and the other required test cases
are also printed. Do not leave any of them commented out!
Don't forget to show your mom!
--------