辅导案例-ENGGEN131 2020

欢迎使用51辅导,51作业君孵化低价透明的学长辅导平台,服务保持优质,平均费用压低50%以上! 51fudao.top
ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
1

Fractal Generation: animating Julia sets





Given two complex numbers, you will find the fractals associated with each of these values and the
fractals associated with complex values on a path between the two numbers, producing a movie of
chaos theory in action.





















NOTE: This is version 1 of the project document. If you find a typo please post it to the Piazza
project typo thread. If any significant typos (beyond minor grammar and spelling errors) are found,
a newer version of the project will be uploaded to Canvas, with those typos corrected.
Project due date: You will need to upload
your code before
11.59pm on Saturday the 19th of September.

-0.79 + 0.15i

-0.162 + 1.04i

ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
2

Introduction
This project requires you to write code that will allow you to create fractal images, which will then
be combined to produce an animation. Fractals are remarkably beautiful geometric figures, where
similar patterns recur as you zoom further and further in on parts of the figure. They occur in nature
(e.g. ferns, snowflakes and coast lines) but can also be mathematically generated. Investigating
fractals is part of a branch of mathematics known as chaos theory, where very complicated
behaviour can be generated from surprisingly simple rules (and changing the starting value just a
little can have a huge impact on what happens).
The fractals we will be generating are known as Julia sets. They are named after the French
mathematician Gaston Julia, who came up with the formula that generates the sets. Each complex
number has a Julia set associated with it. As we will see, while generating a Julia set is relatively
straight forward, the Julia sets associated with different complex numbers can look startlingly
different. If we traverse a path from one complex number to another and generate a fractal for each
step that we take along the path, the resulting sequence of images can be combined to produce an
animation.
You have been provided with a main script (AnimateJulia.m) and a few useful helper functions
that take care of turning a sequence of images into animated gifs and mp4 files
(MakeAnimatedGif.m and MakeMovie.m). In the pages that follow are detailed explanations of
each of the eight functions that you need to write to fill in the gaps. On completion of the project
you will have written code that allows you to generate Julia sets for a sequence of complex numbers
and colour them with a colour map of your own creation (note that the cover image fractals were
generated using Matlab’s built-in hot colormap called whereas the images below were created using
custom colour maps.

This document shows a few example calls for each function with, but it is expected that you will
create your own test values to test your code (in many cases you can work out the answers on some
very small sets of test data by hand, so that you know what you should expect as output).
A few days prior to the submission date you will be supplied with some test data and test scripts
which can be used to help check your code. If your code fails some of the supplied test code there
is obviously work to be done. If your code passes the supplied test scripts it is a good sign you are on
the right track, but please note that the supplied test code isn’t identical to that used to mark your
code. If you rely just on the supplied test code (without doing tests of your own) you will run the
very real risk of submitting code that will not pass all the marking tests. Do NOT rely solely on the
supplied test scripts, part of doing the project is to learn how to extensively test your own code on a
ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
3

range of different values (which is why the supplied test scripts are only released towards the end of
the timeline).
This project is designed to take the average student around 15 hours to code, but some people may
find it takes upwards of 60 hours (and others will finish it in just a few hours). You will not know
ahead of time how long it will take you, so please don’t leave it to the last minute to make a start!
Remember the golden rule
Write your own code and don’t give your code to anyone. Friends don’t let friends share code.
This project needs to be YOUR work, it is an individual project, not a group project. Copying and/or
sharing code is academic misconduct. Please note that every project submission is passed through
software that detects plagiarism so if you copy you WILL be caught. Unfortunately, every year
students discover the hard way that I’m not kidding. Let me repeat,
DO NOT COPY: YOU WILL BE CAUGHT.
If you give your code to another student and they copy it, you will both be guilty of misconduct.
Copying or supplying code typically results in both the person who copied and the person who
supplied the code being awarded a mark of zero for the project, as well as your names going on the
academic misconduct register. If you have already been found guilty of academic misconduct on
another course or assignment the penalty may be even greater (e.g. a fine or fail of the course).
To help you avoid academic misconduct I have put together a very short best practices guide which
you should read. It is attached as an appendix to this document.
If you have any queries about what is or isn’t academic misconduct, please ask so that I can make
sure everyone understands what is acceptable behaviour and what isn’t.
How to tackle the project
Do not be daunted by the length of this document. It is long because a lot of explanation is given as
to exactly what each function needs to do.
The best way to tackle a big programming task is to break it down into small manageable chunks. A
lot of this work has already been done for you in the form of eight functions to write. Each function
has a detailed description of what it needs to do and most of the functions can be written
independently of each other. Have a read through the entire document and then pick a function to
start on. Remember you don’t have to start with CreateComplexGrid, although it is one of the
simplest functions. You may prefer to start with one of the other fairly straight forward functions
such as IterateComplexQuadratic or CreateColourmap.
Write as many of the functions as you can. When writing some of the specified functions you may
find it useful to call one of the other functions you have written. You may even wish to write
additional helper functions that have not been listed in the specifications. This is absolutely fine (in
fact it is good coding practice to do so). Make sure you remember to submit any extra helper
functions you write as they will be needed so that your code runs correctly. Please note that you will
be able to submit up to 16 functions in total, which leaves room for up to 8 helper functions (which
should be ample). Note that you do not need to submit any of the supplied code.
Several functions require careful thought, particularly those that form the heart of creating the Julia
sets (remember those 5 steps of problem solving!). If you are having trouble understanding how a
function should work, remember to work through the problem by hand with a small data set.
ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
4

Note that I don't expect everyone to write all the functions. Some of them are relatively easy (e.g.
CreateComplexGrid and IterateComplexQuadratic) while others are quite tricky (e.g.
ReadColourValues). You can still get a pretty good mark even if you don't complete all the
functions.
You will receive marks both for functionality (does your code work?), style (is it well written?) and
execution time (how fast does it run?). An “A” grade student should be able to nut out everything
except perhaps full marks for execution time (it can be extremely challenging to get things running
quickly for larger images). B and C grade students might not get a fully working solution. Even if you
only get three of the functions working, you can still get over 50% for the project, as long as the code
you submit is well written (since you get marks for using good style).
What Matlab functions do I need to know?
The entire project can be completed using just the functions we have covered in the course manual,
lectures and labs.
What Matlab functions can I use?
When writing your code, while you don’t need to use functions we haven’t covered in class, you may
wish to do so. As well as being able to use any functions we have covered in class, you can also use
any other functions that are part of Matlab’s core distribution (i.e. not functions from any toolboxes
you may have installed). Note that for this project the use of functions that are only available in
toolboxes is not permitted. Matlab features a large number of optional toolboxes that contain extra
functions. The purpose of this project is for you to get practice at coding, not to simply call some
toolbox functions that do all the hard work for you.
A list of some of the core Matlab functions can be found in the Matlab command reference appendix
on page 284 of the course manual. If you are uncertain whether a particular function is part of the
Matlab’s core distribution or not, type the following at the command line
which
where the term is replaced by the name of the function you are interested in. Check the
text displayed to see if the directory directly after the word toolbox is matlab (which means it is
core) or something else (which means it is from a toolbox).
For example:
>> which median
C:\Matlab\R2017b\Pro\toolbox\matlab\datafun\median.m
This shows us that the median function is part of the standard core Matlab distribution (notice how
the word matlab follows the word toolbox). You may use the median function if you wish to.
>> which imadd
C:\Matlab\R2017b\Pro\toolbox\images\images\imadd.m
This shows us that the imadd function is part of the image processing toolbox and is therefore not
permitted to be used for the project (notice how the word images follows the word toolbox).

ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
5

1+2i
An overview of creating Julia sets
Before we delve into the detail of what functions you will be writing, let’s take a quick high-level
outline of how Julia sets are created.
Recall that complex numbers have a real and imaginary part, e.g. 1+2i, and can be represented
graphically as points on a complex number plane (with the real part being shown on the x axis and
the imaginary part on the y axis)





A Julia set is associated with a particular complex number, c. For example, c = −0.79 + 0.15i was
used to generate the fractal on the left-hand side of the cover page.
For any point, z, in the complex plane we can determine if that point is within the Julia set by
investigating its behaviour when repeatedly applying the complex quadratic polynomial formula:
() = 2 +
The result of applying the formula, (), is fed back in as the new z value and we repeat this over
and over again. If repeated iterations of this formula (with a fixed c value) result in the sequence of f
values staying within the bounds of a circular region around the origin, we say that the original z
value is in the Julia set, and colour it accordingly (typically as black).
A common choice of circular region is one with radius 2, but for this project we will use the region
defined by the radius = 3 (I have chosen this particular radius because it means that all the points
we will be working with in this project start out inside the region, which makes our code a little
simpler). Note that a complex point is within a circular region of radius R if the magnitude of that
point, ||, is less than R.
The magnitude of z is often referred to as the complex modulus of z (or the absolute value of z).
Suppose we want to investigate the point z = 1 + 2i when c = −0.79 + 0.15i
We first find () = 2 +
(1 + 2) = (1 + 2)2 + = (1 + 2)2 + (−0.79 + 0.15i) = −3.79 + 4.15i
Checking the magnitude, |−3.79 + 4.15i| = 5.6202 > 3 so our point is NOT in the Julia set.
Now let’s try a different point, eg. z = 0 + i
We first find () = 2 +
(0 + ) = (0 + )2 + = (0 + )2 + (−0.79 + 0.15i) = −1.79 + 0.15i
Checking the magnitude, |−1.79 + 0.15| = 1.7963 < 3 so our point MIGHT be in the Julia set.
We now repeat the process using the value from above, z = −1.79 + 0.15i, as our new z value.
real
imaginary
1
2i
ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
6

(−1.79 + 0.15) = (−1.79 + 0.15)2 + = (−1.79 + 0.15)2 + (−0.79 + 0.15i)
= 2.3916 − 0.3870i
Checking the magnitude, |2.3916 − 0.3870i | = 2.4227 < 3 so our point still MIGHT be in the Julia set.
We keep repeating the process using the value from above, always taking the result of the function
and feeding it in as our new z value. If as we do this |()| always stays less than = 3 then the
original value we started with is a member of the Julia set. If as we repeatedly iterate we ever find |()| ≥ then our original starting z value is NOT a member of the Julia set.
Obviously when using a computer, we can’t iterate forever, so in practice we set a cutoff for the
number of iterations to perform and if the value is still within the circular region when that cutoff is
reached, we will deem the point a member of the Julia set associated with the complex value c.
Also it should be obvious that it would be impractical to work on classifying the infinite number of
points in the complex number plane, so instead we work on classifying a very small subset of points,
equally spaced in a grid pattern over the complex plane.
Performing this calculation for a whole grid of points and colouring pixels for each point on the grid
gives us a fractal image. When colouring the pixels, we will use black for those points deemed to be
in the set. For points not in the set, we will choose a shade of colour based on how many iterations
it took for that point to move out of the circular region.
Overview of Functions to Write
There are eight in total:
Function Difficulty Level Where used
CreateComplexGrid Relatively straightforward, once
you get your head around
working with complex numbers
in Matlab
Called from the main script,
likely to be a useful helper
function when writing
GenerateJuliaSets
IterateComplexQuadratic Fairly easy, a good starting point Helper function, likely to be
called from
JuliaSetPoints
JuliaSetPoints Medium in difficulty Called from the main script,
likely to be a useful helper
function when writing
GenerateJuliaSets
ColourJulia Fairly challenging Called from the main script,
likely to be a useful helpful
function when writing
GenerateJuliaSets
GenerateJuliaSets A little challenging but not too
bad if you make use of some of
the other functions as helper
functions
Called from the main script
ReadColourValues Fairly challenging, one of the
longer functions
Called from the main script
LookupColourValues A little challenging Called from the main script
CreateColourmap Fairly straightforward, another
good starting point
Called from the main script

ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
7

All functions except IterateComplexQuadratic are called directly from the supplied main script
file named AnimateJulia.m.
IterateComplexQuadratic is a great warm up function and is likely to be a useful helper
function for when you when you write your JuliaSetPoints function. Even if you decide not to
call your IterateComplexQuadratic function from your JuliaSetPoints function you should
still write it, as it will be marked.
You will need to implement CreateComplexGrid, JuliaSetPoints, ColourJulia and
GenerateJuliaSets before being able to use the supplied script file to generate animated
fractals. To use custom colour maps to colour your fractals you will also need to implement
ReadColourValues, LookupColourValues and CreateColourmap.
The pages following have detailed specifications of what each function should do. Note that while
the functions are designed to work together with the supplied main script (to allow the creation of
animated fractals in a colour map of your choice), many of the functions can be written and tested in
isolation. Even if you get stuck on one function you should still try and write the others.
Keep the following general principles in mind:

• Note the capital letters used in function names. Case matters in Matlab and you should take
care that your function names EXACTLY match those in the projection specification. E.g. if
the function name is specified as CreateColourmap don’t use the name
CreateColormap, createcolourmap, Create_Colourmap or CreateColourMap.
• The order type and dimension of input arguments matters. Make sure you have the required
number of inputs in the correct order. E.g. if a function requires 2 inputs, as ColourJulia
does (where the first input is a 2D array of values for points in the Julia set and the second
input is a 2D array containing a colour map) then the order matters (i.e. the first input
should be the array of points not the colour map, to match the specifications). The number
of inputs also matters (so don’t change a function that requires 2 inputs to require more
inputs).
• The order, type and dimensions of the outputs matter, e.g. ReadColourValues returns
two outputs, the first of which is a cell array (where each element contains a colour name,
stored as a string), then the second element is a 2D array of colour values (with each row
containing the colour values for the named colour from the corresponding row of the first
array). Muddling up the order or returning the wrong type of array would lose you all the
marks for this function.
• Matlab supports complex numbers and all the usual operations work as expected, as
demonstrated by this short script:



% demonstrate some basic complex arithmetic
z1 = 3 + 4i
z2 = 2 – 5i

zAdd = z1 + z2 % add z1 and z2 together
zSubtract = z2 – z1 % subtract z1 from z2
zMultiply = z1 * z2 % multiply z1 by z2
zDivide = z1/z2 % divide z1 by z2
zCubed = z1^3 % cube z1

% find the complex modulus (magnitude) of z1
zMagnitude = abs(z1)

ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
8

imaginary
2+2i
2-2i -2-2i
-2+2i
The CreateComplexGrid function

Purpose CreateComplexGrid creates a 2D array of size × which stores complex values
drawn from a square grid of equally spaced points (from the complex plane) bounded
by the lines x=-2, x=2 and y=2i, y=-2i
i.e. the 4 corners of the grid are the points -2+2i (top left), 2+2i (top right), -2-2i
(bottom left) and 2-2i (bottom right)
Input(s) It takes one input, n, a positive integer specifying the number of rows and columns for
the output array
Output(s) It returns a single output, an × 2D array of equally spaced complex values
representing a grid over the complex plane, where the 4 corners of the grid are the
points -2+2i (top left), 2+2i (top right), -2-2i (bottom left) and 2-2i (bottom right)













Example calls
Here are some examples of calls to CreateComplexGrid
>> grid2 = CreateComplexGrid(2)

grid2 =

-2.0000 + 2.0000i 2.0000 + 2.0000i
-2.0000 - 2.0000i 2.0000 - 2.0000i

>> grid3 = CreateComplexGrid(3)

grid3 =

-2.0000 + 2.0000i 0.0000 + 2.0000i 2.0000 + 2.0000i
-2.0000 + 0.0000i 0.0000 + 0.0000i 2.0000 + 0.0000i
-2.0000 - 2.0000i 0.0000 - 2.0000i 2.0000 - 2.0000i


>> grid4 = CreateComplexGrid(4)

grid4 =

-2.0000 + 2.0000i -0.6667 + 2.0000i 0.6667 + 2.0000i 2.0000 + 2.0000i
-2.0000 + 0.6667i -0.6667 + 0.6667i 0.6667 + 0.6667i 2.0000 + 0.6667i
-2.0000 - 0.6667i -0.6667 - 0.6667i 0.6667 - 0.6667i 2.0000 - 0.6667i
-2.0000 - 2.0000i -0.6667 - 2.0000i 0.6667 - 2.0000i 2.0000 - 2.0000i

real
Example of points in the
grid created by the call
CreateComplexGrid(3)
ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
9

The IterateComplexQuadratic function

Purpose IterateComplexQuadratic repeatedly applies the complex quadratic
() = 2 + for a specified value of z and c (with z being replaced by f in the next
iteration). This continues until the value of f is no longer within the bounded region
(i.e. |()| ≥ 3) or the maximum number of iterations is reached (specified by the
cutoff).

If |()| ≥ 3 we return the number of iterations it took until this condition was met
(indicating the initial z value is not in the Julia set associated with c)

If the maximum number of iterations was reached and f is still within the bounded
region (i.e. |()| < 3 ) we return 0 (indicating the initial z value is a member of the
Julia set associated with c)
Input(s) It takes three input(s) in the following order:
1. z, the initial complex value that we begin the iteration process with (this is the
value to determine the nature of)
2. c, a specified complex value (used to generate a particular Julia set)
3. a cutoff value that determines the maximum number of iterations to perform
(this will be a positive integer value)
Output(s) It returns a single output, the number of iterations it took until |()| ≥ 3 or 0 if the
maximum number of iterations was reached and |()| < 3

Consider a call to IterateComplexQuadratic(0,0.5+i,10)
The initial value of z is = 0 and = 0.5 + i and we have a cutoff of 10 iterations (so will perform a
maximum of 10 iterations)
Keeping track of iterations in a table we have
Iteration () ||
1 (0) = (0)2 + (0.5 + ) = 0.5 + i

|0.5 + i| = 1.118 < 3
2 (0.5 + ) = (0.5 + )2 + (0.5 + ) = −0.25 + 2 |−0.25 + 2| = 2.0156 < 3
3 (−0.25 + 2) = (−0.25 + 2)2 + (0.5 + )= −3.4375 |−3.4375| = . ≥

After three iterations |()| ≥ 3 and hence we return 3.
Now consider a call to IterateComplexQuadratic(0,0.5+i,3)
The initial value of z is = 0 and = 0.5 + i but now our cutoff has been reduced to 3. We would
still perform the same three iterations as shown in the table above, and after performing these
iterations, |()| ≥ 3 so we would return a value of 3.
Now consider a call to IterateComplexQuadratic(0,0.5+i,2)
The initial value of z is = 0 and = 0.5 + i but our cutoff has been reduced to 2. This would
correspond to performing just the first two iterations shown in the table above. After two iterations
we have |()| < 3 , so we would return 0.
ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
10

Example calls
Here are some examples of calls to IterateComplexQuadratic
>> p=IterateComplexQuadratic(0,0.5+i,10)

p =

3

>> p=IterateComplexQuadratic(0,0.5+i,3)

p =

3

>> p=IterateComplexQuadratic(0,0.5+i,2)

p =

0
>> p=IterateComplexQuadratic(2+2i,0.5+i,10)

p =

1

>> p=IterateComplexQuadratic(1+i,-i,100)

p =

0

>> p=IterateComplexQuadratic(1+i,-1-i,10)

p =

2


ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
11

The JuliaSetPoints function

Purpose JuliaSetPoints determines whether or not each point in a grid of complex
values is a member of the Julia set associated with a specified complex value c.

If a point in the grid is still within the bounded region after the maximum number of
iterations has been performed, it is deemed a member of the Julia set (and assigned a
value of 0). If a point is not a member of the Julia set it will be assigned a value that
corresponds to the number of complex quadratic iterations it took for that point to
exit the bounded circular region.

Note the 2D array that stores the grid of complex values could have any number of
rows and columns (i.e. it does not have to be square).
Input(s) It takes three input(s) in the following order:
1. a 2D array that stores the grid of complex values we will determine the nature
of (i.e. whether or not they are points in the Julia set)
2. a specified complex value, c, (used to generate the particular Julia set)
3. a cutoff value that determines the maximum number of iterations to perform
Output(s) It returns a single output, a 2D array describing the nature of each point on the grid.
If a grid point is in the Julia set it will have a value of 0. If a grid point is not in the Julia
set it will have a value that corresponds to the number of complex quadratic
iterations it took to exit the bounded circular region (the maximum possible value of
iterations will be determined by the cutoff used when generating the Julia set)


Note that you will likely find it useful to use IterateComplexQuadratic as a helper function
when writing JuliaSetPoints. Remember to write your code to handle any size 2D array (not
just square arrays). This includes being able to handle row and column vectors.
Example calls
Here are some examples of calls to JuliaSetPoints
>> row = [-1+i, i, 1+i] % note this is not a square array

row =

-1.0000 + 1.0000i 0.0000 + 1.0000i 1.0000 + 1.0000i

>> points = JuliaSetPoints(row,0.5+0.5i,10)

points =

3 6 2

>> points = JuliaSetPoints(row,0.5+0.5i,5)

points =

3 0 2

ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
12



>> grid2 = CreateComplexGrid(2)

grid2 =

-2.0000 + 2.0000i 2.0000 + 2.0000i
-2.0000 - 2.0000i 2.0000 - 2.0000i

>> points = JuliaSetPoints(grid2,1+i,10)

points =

1 1
1 1

>> grid3 = CreateComplexGrid(3)

grid3 =

-2.0000 + 2.0000i 0.0000 + 2.0000i 2.0000 + 2.0000i
-2.0000 + 0.0000i 0.0000 + 0.0000i 2.0000 + 0.0000i
-2.0000 - 2.0000i 0.0000 - 2.0000i 2.0000 - 2.0000i

>> points = JuliaSetPoints(grid3,-0.79+0.15i,10)

points =

1 1 1
1 0 1
1 1 1


>> grid5 = CreateComplexGrid(5)

grid5 =

-2.0000 + 2.0000i -1.0000 + 2.0000i 0.0000 + 2.0000i 1.0000 + 2.0000i 2.0000 + 2.0000i
-2.0000 + 1.0000i -1.0000 + 1.0000i 0.0000 + 1.0000i 1.0000 + 1.0000i 2.0000 + 1.0000i
-2.0000 + 0.0000i -1.0000 + 0.0000i 0.0000 + 0.0000i 1.0000 + 0.0000i 2.0000 + 0.0000i
-2.0000 - 1.0000i -1.0000 - 1.0000i 0.0000 - 1.0000i 1.0000 - 1.0000i 2.0000 - 1.0000i
-2.0000 - 2.0000i -1.0000 - 2.0000i 0.0000 - 2.0000i 1.0000 - 2.0000i 2.0000 - 2.0000i

>> points = JuliaSetPoints(grid5,-0.79+0.15i,100)

points =

1 1 1 1 1
1 2 3 2 1
1 57 0 57 1
1 2 3 2 1
1 1 1 1 1

>> points = JuliaSetPoints(grid5,-0.79+0.15i,5)

points =

1 1 1 1 1
1 2 3 2 1
1 0 0 0 1
1 2 3 2 1
1 1 1 1 1
ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
13

The ColourJulia function

Purpose ColourJulia colours the points in a Julia set black and the points outside of the
set an appropriate shade of colour selected from a provided colour map1.

All points within the Julia set are coloured black. If a grid point is not in the Julia set it
will be coloured using the row from the colour map that corresponds to the value
used to describe the nature of that point.

Note the 2D array that describes the nature of each point could have any number of
rows and columns (i.e. it does not have to be square).
Input(s) It takes two input(s) in the following order:
1. a 2D array describing the nature of each point on a grid. If a grid point is in
the Julia set, it will have a value of 0. If a grid point is not in the Julia set, it
will have a positive integer value less than or equal to the cutoff used when
generating the Julia set (this value corresponds to the number of complex
quadratic iterations it took for that point to exit the bounded circular region)
2. a 2D array of size × 3 containing a colour map (the number of rows, r, in the
colourmap must match the value of the cutoff used to generate the Julia set).
The colour values in a row will be between 0 and 1 inclusive, representing the
percentage of red, green and blue respectively, for the colour in that row.
Output(s) It returns a single output, an RGB image of the Julia set. Points in the Julia set will be
coloured as black. Points not in the set will be coloured using the provided colour
map (where the value of the grid point corresponds to the row number of the colour
to use from the map). The image is returned as a 3D array of uint8 values of size
× × 3 (i.e. colour values will be unsigned integers between 0 and 255 inclusive)

Note that when calculating uint8 colour values, any non-integer values will be
rounded to the nearest integer using standard rounding rules (e.g. a red value of
100.5 will be rounded up to 101 whereas a red value of 100.4 would by rounded down
to 100).

Note that colour maps are arrays of doubles with values ranging between 0 and 1 inclusive.
They are not arrays of unsigned 8 bit integers ranging between 0 and 255 inclusive. When using
colour maps you will need to do some calculations to convert colour map colour values to equivalent
uint8 RGB colour values.
Each row in a colour map specifies a colour, with the values in a row representing the percentage or
red, green and blue respectively. E.g. a red value of 0 indicates no red, a red value of 0.5 indicates
50% red and a red value of 1 would represent 100% red (this would be equivalent to uint8 values of
0, 128 and 255 respectively, if using unsigned 8 bit integers to store the amount of red for a pixel).



1 See the colormap documentation file for a full list of Matlab’s built in colormaps (note the US spelling of
color): https://au.mathworks.com/help/matlab/ref/colormap.html
ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
14

Example calls
Here are some examples of calls to ColourJulia
>> row = [-1+i, i, 1+i]; % note this is not a square array

>> points = JuliaSetPoints(row,0.5+0.5i,10)

points =

3 6 2

>> J = ColourJulia(points,jet(10)) % use jet colour map with 10 rows

1×3×3 uint8 array

J(:,:,1) =

0 85 0


J(:,:,2) =

85 255 0


J(:,:,3) =

255 170 255


% script to generate a small 100 x 100 Julia set
grid100 = CreateComplexGrid(100);
points = JuliaSetPoints(grid100,-0.79+0.15i,10); % note cutoff of 10
J1 = ColourJulia(points,jet(10)); % use the jet colour map with 10 rows
J2 = ColourJulia(points,hot(10)); % use the hot colour map with 10 rows
figure(1)
subplot(1,2,1)
imshow(J1) % will produce the 100 x 100 pixel image below left
subplot(1,2,2)
imshow(J2) % will produce the 100 x 100 pixel image below right





ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
15


>> grid5 = CreateComplexGrid(5);

>> points = JuliaSetPoints(grid5,-0.79+0.15i,5)

points =

1 1 1 1 1
1 2 3 2 1
1 0 0 0 1
1 2 3 2 1
1 1 1 1 1

>> J = ColourJulia(points,jet(5))

5×5×3 uint8 array

J(:,:,1) =

0 0 0 0 0
0 0 128 0 0
0 0 0 0 0
0 0 128 0 0
0 0 0 0 0


J(:,:,2) =

128 128 128 128 128
128 255 255 255 128
128 0 0 0 128
128 255 255 255 128
128 128 128 128 128


J(:,:,3) =

255 255 255 255 255
255 255 128 255 255
255 0 0 0 255
255 255 128 255 255
255 255 255 255 255



ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
16

The GenerateJuliaSets function

Purpose GenerateJuliaSets takes a sequence of complex values and generates the
corresponding sequence of Julia set images.

Input(s) It takes three input(s) in the following order:
1. a 1D array of complex values to generate Julia set fractals for
2. n, a value specifying the grid size to use (the grid will be × )
3. a 2D array of size × 3 containing a colour map (the number of rows, r, in the
colourmap will be used as the value for the cutoff when generating the Julia
sets). The colour values in each row will be between 0 and 1 inclusive,
representing the percentage of red, green and blue respectively, for the
colour in that row.

Output(s) It returns a single output, a cell array where each element contains an RGB image of a
Julia set (as a 3D array of uint8 values of size × × 3) for the corresponding
complex value from the complex values array, will all Julia sets coloured using the
provided colour map.

Note that we don’t need to pass in the cutoff value as an input to the function, as the cutoff value
can be found by counting the number of rows in the 2D array that is passed in as the third input (the
colourmap array).
Example call
Here is an example of a call to GenerateJuliaSets, using a jet colour map with 50 rows.
% script to test GenerateJuliaSets, will produce images below
cvalues = [-0.8 + 0.2i, -0.8 + 0i, 0 - 0.2i] % 1D array of complex values
ImageArray = GenerateJuliaSets(cvalues,500,jet(50));
figure(1)
subplot(1,3,1); imshow(ImageArray{1})
subplot(1,3,2); imshow(ImageArray{2})
subplot(1,3,3); imshow(ImageArray{3})





ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
17

The ReadColourValues function

Purpose ReadColourValues reads in a list of colour names and their values from a
specified text file, returning the colour names in a cell array and the colour values in a
2D array. If the text file cannot be opened, an error message will be displayed to the
user saying Error opening file where is replaced by the name
of the file. If the file could not be opened the output variables will not be assigned
any values.

Input(s) It takes a single input, a string containing the filename of a text file that stores a
mapping of colour names to colour values. Each line of the text file will list the name
of a colour followed by three colour values, all separated by spaces. The three values
will be between 0 and 1 inclusive, representing the percentage or red, green and blue
respectively for the colour on that line.

Output(s) It returns two outputs in the following order:

1. a cell array of colour names, where each element of the cell array is a colour
name stored as a string. This array should have r rows and 1 column where
the number of rows corresponds to the number of colour names read from
the file.
2. a 2D array of colour values of size × 3, where each row contains the three
colour values read in from the file (for the colour in the corresponding row of
the colour names array). The values in a row will be between 0 and 1
inclusive, representing the percentage of red, green and blue respectively.
That is, the first column will be the amount of red, the second the amount of
green and the third the amount of blue.

Below is shown the contents of some sample text files, to demonstrate the format:
BasicColours.txt RoyalColours.txt Monochrome.txt




You may assume the text file is of the correct format and contains at least two colours. It could have
many more colours. You may assume that colour names will use a single word. Colour values will
range from 0 to 1 inclusive.
Note that processing a line that includes both text and numerical values can be tricky. Think about
what character separates the two parts and how you might go about splitting the two up, so that
you have one substring containing a colour name and another substring containing the three values
(which can then be easily scanned for the numerical values).
Note that if you want to display an error message in red you can use the fprintf function to print
the message to standard error (which has the file id 2).
red 1 0 0
green 0 1 0
blue 0 0 1
yellow 1 1 0
magenta 1 0 1
cyan 0 1 1
black 0 0 0
white 1 1 1

navy 0 0 0.5
purple 0.5 0 0.5
silver 0.753 0.753 0.753
gold 1 0.843 0
ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
18

Example calls
Here are some examples of calls to ReadColourValues using the text files mentioned above
>> [colours, values]=ReadColourValues('BasicColours.txt')

colours =

6×1 cell array

{'red' }
{'green' }
{'blue' }
{'yellow' }
{'magenta'}
{'cyan' }


values =

1 0 0
0 1 0
0 0 1
1 1 0
1 0 1
0 1 1

>> [colours, values]=ReadColourValues('RoyalColours.txt')

colours =

4×1 cell array

{'navy' }
{'purple'}
{'silver'}
{'gold' }


values =

0 0 0.5000
0.5000 0 0.5000
0.7530 0.7530 0.7530
1.0000 0.8430 0

>> [colours, values]=ReadColourValues('RoyalColors.txt') %mispelled filename
Error opening file RoyalColors.txt
Output argument "colourNames" (and maybe others) not assigned during call to
"ReadColourValues".



ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
19

The LookupColourValues function
Purpose LookupColourValues looks up the colour values for a named colour, from a list
of provided colours and their values. It should ignore the case of the name. If the
colour is not found an error message is displayed saying Colour not found and default
colour values of 0 0 0 are returned.
Input(s) It takes three inputs in the following order:
1. a string containing the name of a colour to look up
2. a cell array of colour names, where each element of the cell array is a colour
name stored as a string.
3. a 2D array of colour values of size × 3, where each row contains the three
colour values read in from the file (for the colour in the corresponding row of
the colour names array). The values in a row will be between 0 and 1
inclusive, representing the percentage of red, green and blue respectively.
Output(s) It returns a single output, a 1 × 3 element array of colour values for the colour to look
up. The values in a row will be between 0 and 1 inclusive, where the first column will
be the percentage of red, the second the percentage of green and the third the
percentage of blue.

Note that if you want to display an error message in red you can use the fprintf function to print
the message to standard error (which has the file id 2).
Remember that the case used for the name should not matter, e.g. if the colour gold is on the list
then looking up values for the name Gold or even GOLD should still work.
See the next page for example calls.


ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
20

Example calls
Here are some examples of calls to LookupColourValues using the colours from the sample text
file RoyalColours.txt mentioned in the ReadColourValues section.
>> [colours, values]=ReadColourValues('RoyalColours.txt')

colours =

4×1 cell array

{'navy' }
{'purple'}
{'silver'}
{'gold' }

values =

0 0 0.5000
0.5000 0 0.5000
0.7530 0.7530 0.7530
1.0000 0.8430 0

>> NavyValues = LookupColourValues('navy',colours,values)

NavyValues =

0 0 0.5000

>> GoldValues = LookupColourValues('Gold',colours,values) % note capital G

GoldValues =

1.0000 0.8430 0

>> GreenValues = LookupColourValues('green',colours,values) % no green on list
Colour not found

GreenValues =

0 0 0


ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
21

The CreateColourmap function

Purpose CreateColourmap creates a custom colour map, with n shades of colour that
range from a specified starting colour through to a specified ending colour.

Input(s) It takes three inputs in the following order:
1. a 1 × 3 element array of colour values for the starting colour for the map. The
values in this row vector will be between 0 and 1 inclusive, representing the
percentage or red, green and blue respectively.
2. a 1 × 3 element array of colour values for the ending colour for the map. The
values in this row vector will be between 0 and 1 inclusive, representing the
percentage or red, green and blue respectively.
3. n, the number of rows to generate for the colour map array
Output(s) It returns a single output, a colour map in the form of an × 3 element array, where
each row represents a colour. The values in a row will be between 0 and 1 inclusive,
representing the percentage or red, green and blue respectively.

The first column will contain the red values, which will be linearly spaced from the
starting red value (in row 1) to the ending red value (in the final row)
The second column will contain the green values, which will be linearly spaced from
the starting green value (in row 1) to the ending green value (in the final row).
The third column will contain the blue values, which will be linearly spaced from the
starting blue value (in row 1) to the ending blue value (in the final row).


Note that colour maps are arrays of doubles with values ranging between 0 and 1 inclusive.
They are not arrays of unsigned 8 bit integers ranging between 0 and 255 inclusive.
Each row in a colour map specifies a colour, with the values in a row representing the percentage or
red, green and blue respectively. E.g. a red value of 0 indicates no red, a red value of 0.5 indicates
50% red and a red value of 1 would represent 100% red (this would be equivalent to uint8 values of
0, 128 and 255 respectively, if using unsigned 8 bit integers to store the amount of red for a pixel).
Example calls
Here are some examples of calls to CreateColourmap
>> BlackToWhite = CreateColourmap([0 0 0],[1 1 1],5)

BlackToWhite =

0 0 0
0.2500 0.2500 0.2500
0.5000 0.5000 0.5000
0.7500 0.7500 0.7500
1.0000 1.0000 1.0000



ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
22


>> PurpleToGold = CreateColourmap([0.5 0 0.5],[1 0.843 0],5)

PurpleToGold =

0.5000 0 0.5000
0.6250 0.2107 0.3750
0.7500 0.4215 0.2500
0.8750 0.6322 0.1250
1.0000 0.8430 0

>> RedToBlue = CreateColourmap([1 0 0],[0 0 1],10)

RedToBlue =

1.0000 0 0
0.8889 0 0.1111
0.7778 0 0.2222
0.6667 0 0.3333
0.5556 0 0.4444
0.4444 0 0.5556
0.3333 0 0.6667
0.2222 0 0.7778
0.1111 0 0.8889
0 0 1.0000




ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
23

How the project is marked
A mark schedule and some test scripts will be published prior to the due date, outlining exactly how
marks will be allocated for each part of the project and giving you the opportunity to test your code.
You will receive marks both for functionality (does your code work?), style (is it well written?) and
execution time (how fast does it run?). There are 26 marks available for functionality (each function
is marked out of 3, except ReadColourValues and LookupColourValues which are marked out of 4),
12 marks for style and 2 marks for execution time.
Each of the eight required functions will be marked independently for functionality so even if you
can’t get everything to work, please do submit the functions you have written. Some functions may
be harder to write than others, so if you are having difficulty writing a function you might like to try
working on a different function for a while and then come back to the harder one later.
Note it is still possible to get marks for good style, even if your code does not work at all! Style
includes elements such as using sensible variable names, having header comments, commenting the
rest of your code, avoiding code repetition and using correct indentation.
Each function can be written in less than 20 lines of code (not including comments) and some
functions can be written using just a few lines but do not stress if your code is longer. It is perfectly
fine if your project solution runs to several hundred lines of code, as long as your code works and
uses good programming style.
How the project is submitted
Submission is done by uploading your code to the Aropa website. More information will be provided
on how to submit the project to Aropa in a Canvas email announcement. You should be able to
work on your project from anywhere assuming you have access to Matlab (either installed on a
computer of running online) and can access the internet to upload your final submission.
Submission Checklist
Here is a list of the eight functions specified in this document. Remember to include all eight (or as
many of them as you managed to write) in your project submission. The filenames should be
EXACTLY the same as shown in this list (including case). They should also work EXACTLY as described
in this document (pay close attention to the prescribed inputs and outputs and their order). In
addition if your functions call any other “helper” functions that you may have written, remember to
include them too (you can submit up to a total of 16 files, so may include up to 8 helper functions).
The eight required functions are:
• CreateComplexGrid
• IterateComplexQuadratic
• JuliaSetPoints
• ColourJulia
• GenerateJuliaSets
• ReadColourValues
• LookupColourValues
• CreateColourmap
ENGGEN131 2020 Matlab Project version 1 Due date: Saturday 19th September 11.59pm.
24

Any questions?
If you have any questions regarding the project, please first check through this document. If it does
not answer your question, then feel free to ask the question on the class Piazza forum. Remember
that you should NOT be publicly posting any of your project code on Piazza, so if your question
requires that you include some of your code, make sure that it is posted as a PRIVATE piazza query.

Have fun!
Enggen131 Good Practice Guidelines
Acceptable



% wholeNumberAverage function is responsible for checking whether or not
% the average of the digits is a whole number
% Inputs: s, an array of numbers representing a sequence to check
% Outputs: b, zero if the array does NOT average to a whole number,
% otherwise it returns the whole number average (which corresponds
% to the number of balls required to juggle the pattern)
function b = wholeNumberAverage(s)

% calculate average
av = mean(s);


% check if the rounded average is equal to the original average
roundedAv = round(av);
if av > 0 && roundedAv == av
b = av;
else
b = 0;
end






You used some of the project specification
text in the header comments for your
function
A friend told you about the mean function,
which can be used to find the average of an
array. You looked up the matlab help on
mean and decide to use it, then WROTE YOUR
OWN CODE
A group of you discussed ideas about how to check if a
value is a whole number. As part of the group
discussion, everyone figured out that if the original
value is the same as the rounded value, then it must be
a whole number. You then WROTE YOUR OWN CODE, using
this idea.



Acceptable

% wholeNumberAverage function is responsible for checking whether or not
% the average of the digits is a whole number
% Inputs: s, an array of numbers representing a sequence to check
% Outputs: b, zero if the array does NOT average to a whole number,
% otherwise it returns the whole number average (which corresponds
% to the number of balls required to juggle the pattern)
function b = wholeNumberAverage(s)


% check if the rounded average is equal to the original average
% by seeing if the reminder after division by one is positive
% algorithm retrieved from www.mycoolalgorithm.com/aGreatIdea
if rem(s,1) > 0
b = mean(s);
else
b = 0;
end









You found an algorithm on the internet that described a method for
checking for whole number values, by seeing if the remainder after
division by one was a positive number.

You credited the source of the algorithm and then WROTE YOUR OWN
matlab code to implement it
Unacceptable – DO NOT DO






% checks whether a string consists of nonzero digits only
% (i.e. the characters 1 to 9 inclusive)
% Inputs: s, a string to check
% Outputs: isValid, a Boolean variable, true if the string contains only
% non zero digits and false otherwise
function isValid = nonZeroDigitsOnly(s)

isValid = true;
i = 1;

% loop through characters to see if they are within a valid ascii range
while isValid==true && i <= length(s)
if (s(i) < 49 || s(i) > 57)
% if out of range, this sequence is invalid
isValid = false;
end
i = i +1;
end

 
You didn't know how to write an if
statement that worked, so your friend came
to your computer and typed out this line
for you
You were unsure what to write for the
function header comments so took a photo of
your neighbour's work with your iphone and
then typed in their comment lines later
You were having trouble late at night with
debugging your while loop. You asked your
friend about it on msn and they sent
through a few lines of their working code,
so you used their while loop condition.
Unacceptable – DO NOT DO

% takes a string containing digits and coverts it to the corresponding
% array of characters
% Inputs: c, a string of characters containing only nonzero digits
% Outputs: n, an array of numbers corresponding to the digits of the string
function [n] = char2num(c)

% convert to an array of numbers
for i=1:length(c)
n(i) = str2num(c(i));
end







% generate carry path starting at height 0, going from an initial x position
% to a final x position (specified in terms of cm from origin)
% While this could be a straight line, it looks prettier if the ball dips
% down below the y axis
%
% Inputs: 1) initial x co-ordinate (catch location)
% 2) final x co-ordinate (throw location)
% Outputs: 1) An array of x co-ordinates for the path through the hand
% 2) An array of y co-ordinates for the path through the hand
function [x,y]= generateParabolicPath(xinit,xfinal)

x = linspace(xinit,xfinal,5);
y = [0 -1 -2 -1 0];

 
You didn't know how to write this function,
so a friend emailed you their code, which
you then copied. To make it look different
you changed the wording of the comments and
the variable names
You couldn't write this function by
yourself so you and a friend worked on it
together. After writing the entire thing
together you each took a copy and put it
into your project.
51作业君

Email:51zuoyejun

@gmail.com

添加客服微信: abby12468