E5 MATLAB Assignment 4

Upon completion of the exercise you should be able to use MATLAB to

As you go through this document, you should enter the commands at the MATLAB prompt, and try variations on the commands to make sure that you fully understand. 

Reading from text

You may want to refer to chapters 1,  2 and 5 of your text.


To this point all of the data we have used has been numeric, either a scalar, a vector or an array.  MATLAB has several other types of data that it can use.  In this exercise we will explore some of these.

Strings

A "string" is a vector of "characters".  We define a string by putting a sequence of characters between quotes.

>> myString = 'This is this.'
myString =
This is this.

We can now access parts of this vector as we did with vectors of numbers.

>> myString(1)       % The first character
ans =
T

>> myString(1:4)     % The first four characters
ans =
This

>> myString(9:end)   % From character 9 to the end
ans =
this.

We can form a longer string by forming it from two (or more) smaller strings as we would create a long vector from several smaller vectors.

>> word1 = 'Know';
>> word2 = 'fear';
>> [word1 ' ' word2 '!']     % Note addition of space between words and punctuation.
ans =
Know fear!

  There are also functions to convert a number to a string of characters (num2str).  This can be useful for displaying text and numbers in a single line (instead of using multiple "disp" commands as we did in previous labs.

>> num2str(pi)   % Note: Result will be a string.
ans =
3.1416

>> disp(['The number pi is approximated as ' num2str(pi) '.'])
The number pi is approximated as 3.1416.

We can also convert from a string to a number (str2num)

>> x=str2num('1.2356')
x =
    1.2356

To get more information about strings enter "doc strings" at the command prompt.

Structures

Sometimes it is useful to create a variable with that comprises more than one piece of information.  For example, we can define a circle by its radius and center.  We could do this we two separate variables, or one variable (call it "myCircle") with two "fields,"  one called "radius" and one called "center" (and "center" is a two element vector consisting of the "x" and "y" values of the circle's center.

>> myCircle.center = [2 2];
>> myCircle.radius = 4;
>> myCircle
myCircle = 
    center: [2 2]
    radius: 4

Now we can access each part of the structure by using both the variable name and the field

>> myCircle.radius
ans =
     4

Note that the data need not be numeric, we can use strings instead.

>> myName.firstName='Erik';
>> myName.lastName='Cheever';
>> myName
myName = 
    firstName: 'Erik'
     lastName: 'Cheever'
>> disp(['Fullname is ' myName.firstName ' ' myName.lastName '.'])
Fullname is Erik Cheever.

We can even mix types of data

>> myName.age = 71
myName = 
    firstName: 'Erik'
     lastName: 'Cheever'
          age: 71

>> disp(['My name is ' myName.firstName ' and I am ' num2str(myName.age) ' years old.']);
My name is Erik and I am 71 years old.

Objects

"Objects" are in some ways similar to structures, but in addition to storing multiple pieces of information in a variable, a variety of operations that can be performed on the object are also defined.  For objects the different pieces of information are called properties instead of fields (the name used with structures). It is not important (now) to understand how objects are created, but you will need to know how they can be used.  A predefined type of "object" that you will use in the next several weeks is the "patch."

First, set four points that are the vertices of a square

>> xVals = [0 1 1 0];
>> yVals = [0 0 1 1];        % Define vertices of a square
>> plot(xVals,yVals,'ro');   % Plot the points
>> axis(2*[-1 1 -1 1]);      % Set axis limits

The "patch" command defines a graphics shape and as you will use it has three arguments: patch(x,y,c).  The variable "x" hold the x-values of the vertices, "y" holds the y-values and "c" is a color.  The color is a three element vector "[r,g,b]" where "r," "g," and "b" are numbers from 0 to 1 that specify the intensity of the color.  Define a square patch that is red (c=[1 0 0]).

>> myPatch = patch(xVals, yVals, [1 0 0])
myPatch =
    0.0026
>> axis(2*[-1 1 -1 1]);      % Set axis limits

Don't worry about the number that comes back; it is used by MATLAB to uniquely define the object.   To see all of the properties of the object use the "get" command (only some of the output is shown below; an ellipsis (...) is used where output is not shown).

>> get(myPatch)
         ...
	EdgeAlpha = [1]
	EdgeColor = [0 0 0]
	FaceAlpha = [1]
	FaceColor = [1 0 0]
	Faces = [1 2 3 4]
	LineStyle = -
	LineWidth = [0.5]
	...
	XData = [ (4 by 1) double array]
	YData = [ (4 by 1) double array]
	ZData = []
        ...
	Visible = on

To change the color, you can alter the "FaceColor" property using the "set" command.

>> set(myPatch,'FaceColor',[0 1 0]);   % Make face color green [r g b]=[0 1 0]

You can also change the edge color and thickness by adjusting the appropriate properties.

>> set(myPatch,'EdgeColor',[0 0 1]);   % Make edge color blue [r g b]=[0 0 1]
>> set(myPatch,'LineWidth',2);         % Make edge thicker

You can even change the shape by altering "XData"  property

>> set(myPatch,'Xdata',[0 1.5 1.5 0]); % Change Xdata

It is also possible to set multiple properties at once

>> set(myPatch,'XData',[0 1 1 0],'YData',[0 0 -0.5 -0.5]); % Change Xdata and YData

or to access a single property

>> myColor = get(myPatch,'FaceColor')   % Get color property
myColor =
     0     1     0

Operations with Two Vectors

Define two row vectors "p" and "q" where "p" is the unit price of three objects (e.g., apples, oranges and bananas) and "q" is the quantity of each fruit that is purchased.

>> p = [0.45 0.50 .28];  % Unit price for apples, oranges and bananas
>> q = [10, 5, 2];       % Quantities purchased of the 3 items

In this examples, apples are 45¢ each (and 10 were purchased), oranges are 50¢ (5 purchased) and bananas are 28¢ (two purchased).  To try to find how much is spent on  each type of fruit, you might try multiplying the two vectors (but this results in an error, as shown below).

>> cost = p*q
??? Error using ==> mtimes
Inner matrix dimensions must agree.

The error arises because multiplication is not defined for two row vectors.  However, what you want to do is multiply each element of "p" by the corresponding element in "q".  In MATLAB this is done with the "element-by-element" multiplication operator ".*" (a period followed by an asterisk).

>> cost = p.*q
cost =
    4.5000    2.5000    0.5600

This tells us we spent $4.50 on apples, $2.50 on oranges and 56¢ on bananas.

There are many other operations that aren't defined for two row vectors, but element-by-element operations are generally available for these operations.  A common operation is element-by-element division, "./".  A less obvious operation is exponentiation, or raising a vector to a power.  Since raising a number to a power is really just multiplying the number by itself multiple times, it shouldn't be surprising that we need an element-by-element operator.  In the example below the value of the square of the elements of "p" is calculated - first incorrectly, then correctly.

>> p^2   % Incorrect, this is equivalent to p*p and multiplication of row vectors isn't defined.
??? Error using ==> mpower
Inputs must be a scalar and a square matrix.
>> p.^2  % Correct!  Element-by-element exponentiation (equivalent to p.*p
ans =
    0.2025    0.2500    0.0784

Some Simple Shapes

Define a few shapes.  Make sure you understand the following code - you may need to review your trigonometry.  Come see me, Ann Ruether, or a Wizard if you have trouble figuring out the various shapes.  You will have to add comments later on to demonstrate you understand.  Note that the newer shapes are on top of the older shapes.

>> theta=linspace(0,2*pi);             % Theta evenly space from 0 to 2*pi
>> circleX = 0.5*cos(theta);           % X values for circle, radius = 0.5.
>> circleY = 0.5*sin(theta);           % Y values.
>> myCircle = patch(circleX, circleY, [1 1 0]);    % Yellow circle

>> theta4 = linspace(0,2*pi,5);        % Theta spaced every pi/2 (90 degs).
>> dX = 0.5*cos(theta4);               % X values for diamond ("radius"=0.5).
>> dY = 0.5*sin(theta4);               % Y values
>> myDiamond = patch(dX, dY, [0 1 1]); % Cyan diamond (defined geometrically)

>> xS1 = [0 1 1 0];                    % X values for square shape 1.
>> yS1 = [1 1 0 0];                    % Y values.
>> mySquare1 = patch(xS1,yS1,[1 0 0]); % Red Square (defined by vertices)

>> sX2 = 0.25*cos(theta4+pi/4);        % X values for square shape 2 ("radius"=0.25).
>> sY2 = 0.25*sin(theta4+pi/4);        % Y values
>> mySquare2 = patch(sX2,sY2,[0 0 1]); % Blue square (defined geometrically)

>> axis([-2 2 -2 2],'square')          % Make axes square.

 

We can move the diamond by changing its "XData" property

>> set(myDiamond,'XData',dX-0.5)       % Move diamond to left by 0.5 units by altering 'XData'.

To understand the next shape to be defined consider the parabola shown below. 

The parobola is symmetric about the vertical axis and goes through the y-axis (x=0) with a value y0 (in this case y0=0.5).  It also goes through the point (x1,y1) and in this case (x1,y1)=(1.75,2.25).  It can be shown that this parabola is defined by the equation

 
with
 

For this particular parabola, c=0.5 and a=0.5714.

If we use this information we can create a "smile" shape.  Note that the code is poorly commented on purpose.  Your job is to figure out what it does.

x=linspace(-1,1,100);               % x goes from -1 to 1
upperLip = 0.5714*x.^2+0.5;
lowerLip = x.^2;

xSmile = patch ([x -x], [upperLip lowerLip], [1 0 1]);  % Magenta "smile"

 

To do

The task this week may take a bit longer than the others because there is no predefined script.  Instead you have to start from scratch and create your own file.  Read the directions carefully to make sure you complete the specified task. Please be sure you comment the code clearly and thoroughly!

Your task is to

  1. Create the shapes shown (and described) below.  Make sure the creation of each shape is well documented in your code.
    1. A large yellow circle (the face).; defined geometrically (i.e., with sines and cosines)
    2. A red "smile"; defined with two parabolas (as above - but you must comment the code to explain it)
    3. A cyan equilateral triangle (with a vertex at the top).; defined geometrically (i.e., with sines and cosines).  The "radius" of the nose is 0.75.
    4. A blue hexagon (left eye); defined geometrically (i.e., with sines and cosines).  The "radius" of the hexagon is 0.5.
    5. A green rectangle (right eye); defined by vertices.  Dimensions are 0.25 high by 1 wide.
           
  2. After you  have defined the element, start a new cell (this will cause the figure to be published).  The published document must have the image above as well as the image below.
  3. In the new cell adjust the properties of the various patch objects to move them around to form a face, as shown below.  Don't define new patches, just use "set(...)" to change the properties of the existing patches.  Exact placement of shapes is not important
                   
  4. Create another cell and in it define a variable "h" that is the approximate number of hours this assignment took you to complete.  An example follows
           h=2.25;  % It took me 2 hours and 15 minutes to complete the assignment.
  5. Use the "disp" command, the variable "h", and the "num2str" command to display a sentence that looks something like the one below.
           This assignment took about 2.25 hours to complete.
    Please try to be accurate here - I'd like to get an idea how long this assignment took.
  6. Publish the script.  You are to turn in both the script (.m file) and the published documents (.doc or .docx file).

Hints/techniques to consider while debugging your script:

To turn in

(via moodle)

Grading is as follows: