GS 2001/Math - Collins
Lab 5
Graphical Transformations - The Name Game

Preliminaries

Start MATLAB (from Start Menu).
Arrange your windows so you can see MATLAB and this webpage.

Enter Your Data

If you haven't done it already, create a file that contains
the information you determined for your name in the homework.
If you already have it in a file, copy the file to
the Work directory in MATLAB.  Call the file "name.m".  
If you have some mathematical expressions in
your data you need to make sure that they are written in
a way that MATLAB understands them.  Use sqrt for
square root.

At the beginning of the file, before your data, put a line
   N = [
and at the end of your data, put 
   ];
My sample file looks like this:
   N = [
   1   3*sqrt(2)  135  6  7
   2  3*sqrt(2)  225  3  10
   3  4   270  0  7
   4  3*sqrt(2)  -45  0  3
   5  3*sqrt(2)  45  3  0];

If you are creating this file for the first time or if you make
any changes to it, you should either save it a copy on a floppy
or email a copy of it to yourself.  We'll need this data for
future labs.

In MATLAB, see if your file is okay by typing
    name, N
You should see a table of your data.

View Your Name

Each line of data is the information needed to build a transformation
that transforms the line from (0,0) to (1,0) into a segment of
your name.  Our first exercise is to make a function which
performs this tranformation.  You can work it out yourself or
copy the program at the end of this page into a M-file "viewname.m".

To use your function, you will just type 
    viewname(N)

Details

We perform the transformations in the following order:
   Scale, then Rotate, then Translate
The resulting matrix (using homogeneous coordinates) is
       (sx*cos(a)  -sy*sin(a)  tx)
   T = (sx*sin(a)   sy*cos(a)  ty)
       (   0          0       1)
where sx=sy=length, a=angle (in radian) and (tx,ty) is the
coordinate of the endpoint.

We must loop through each segment, build the transformation, transform
the line, and then plot it.  Here are some helpful commands 
(Note: this is not a complete program, just some pieces)
   Nseg = size(N,1);   % number of segments

   sx = N(i,2);        % length of segement #i
   sy = sx;
   a  = N(i,3);        % angle
   a  = a*pi/180;      % convert to radians (if you used degrees)
   tx = N(i,4);        % coordinates
   ty = N(i,5);

   LS = [0 1;0 0;1 1];   % line segment from (0,0) to (1,0)
   T = [sx*cos(a) -sy*sin(a) tx; sx*sin(a) sy*cos(a) ty; 0 0 1];  % transf.
   newS = T*LS;        % transform the segment
   plot(newS(1,:),newS(2,:))   % first row of newS is x coord, 2nd is y
   hold on                     % tells MATLAB to keep all the plots
                               % on one graph

   hold off                    % use this after all the plots are done
   axis equal                  % makes the units the same in the x-y directions


Exercise 1

Get this function working and print out your name.  You
can use Print from the File menu.

If what you get doesn't look right, put these two lines in "viewname.m" 
right after the plot statement:
   disp(i)
   pause
This will show you the segment number, and pause so you can see
which segment is at fault.  You should make the changes to the
file "name.m" and rerun it.  Make sure you save a good copy of
your data.

Challenge

Modify "viewname.m" so that instead of transforming the line
segment from (0,0) to (1,0) to make your name, it transforms
the rectangle with corners (0,0), (1,0), (1,0.1), (0,0.1) to
make the parts of your name.

Come up with some other shape that can be transformed into
the parts of your name.

Transform Your Name

Make a new function "viewname2.m" which takes N and a matrix A
as input and plots your name as in "viewname" but applies the
transformation in A to it first.

Edit "viewname.m" and save it as "viewname2.m".  Then change
the 1st line to
    function viewname2(N,A)
Next, we want to apply the transformation A after we
apply the transformation of our name.  So, 
add the following line after we compute newS:
    newS = A*newS;
That's all you need to do.

Remember that we are using homogeneous coordinates so A must
be a 3x3 matrix (not 2x2).

Create three transformation matrices: a skew of 1/2, a rotation of 
30 degrees and a translation (2 right, 1 down).  Call them 
skew, rot and trans.

We would have
   skew = [1 0.5 0; 0 1 0; 0 0 1];
   a = 30*pi/180;
   rot = [cos(a) -sin(a) 0; sin(a) cos(a) 0; 0 0 1];
   trans = [1 0 2;0 1 -1; 0 0 1];

Try these out:
    viewname2(N,skew)
    viewname2(N,rot)
    viewname2(N,trans)
You can also combine these transformations:
    viewname2(N,rot*trans)
    viewname2(N,skew*rot)
    viewname2(N,rot*rot)
    viewname2(N,trans*rot)
Now for some fun, you can use the command hold on
before you draw your name each time and the previous drawing will not
be erased.  Try the following:
    viewname(N), hold on
    viewname2(N,rot), hold on
    viewname2(N,rot*rot), hold on
    viewname2(N,rot^3), hold on
    viewname2(N,rot^4), hold on
    viewname2(N,rot^5), hold on
    viewname2(N,rot^6)

Exercise 2 (if time allows)

Use a variety of transformations in some pattern to generate a
nice picture.  You can use different transformations from what
we used above.  Print out the final result.

Hint: since this might involve some trial and error, you should
put all your commands starting with reading in the name data
and building the transformation matrices to the actual calls
to viewname and viewname2 into a M-file (a script).  Then you
can make changes, and re-run it without having to retype
everything.

If you want to save a copy of your graph, you use the print to
file option from the print menu, or you can type
    print -djpeg filename.jpg
to save it to the file filename.jpg.

Fun

MATLAB also has the ability to record pictures you draw and then
play them back, i.e. make a movie.

After you figure out what pictures you want in your movie, you need
to figure out what screen (or axes) will hold all your pictures.
Figure out the x-range and the y-range that can contain every picture
you draw.  Create a vector of these values:
   myaxis = [xleft xright ybot ytop];
Now you are ready to make a movie.  The steps are pretty basic,
first you create the space for the movie, then you create images
frame by frame and save them.  It looks like this:
   n = 24;   % number of frames (you can use more or less)
   axis(myaxis)
   M = moviein(n);
   for j=1:n
      % put your plot commands here, before the axis command
      axis(myaxis)
      M(:,j) = getframe;    % captures whatever is on the graph
   end
The command axis off removes the axis markings.

To play your movie, you just type
   movie(M)   or
   movie(M,10)  or
   movie(M,-10) 
The first version plays it once, the second 10 times, the third plays
it forward and backward.

There is a sample program below you can play around with if you are
not sure where to start.


---------------------------------SOLUTIONS-------------------------------
To use these, select all the lines in green, copy them, and paste them
into the M-file editor window.  Save and run.


viewname.m

function viewname(N)
% plots the name as given in the data in N
%  each row of N has: segment #, length, angle, x,y coord.

LS = [0 1; 0 0; 1 1];   % line segement from (0,0) to (1,0);
Nseg = size(N,1);   % number of segments

for i = 1:Nseg
   sx = N(i,2);        % length
   sy = sx;
   a  = N(i,3);        % angle
   a  = a*pi/180;      % convert to radians (if you used degrees)
   tx = N(i,4);        % coordinates
   ty = N(i,5);

   T = [sx*cos(a) -sy*sin(a) tx; sx*sin(a) sy*cos(a) ty; 0 0 1];
   newS = T*LS;        % transform the segment
   plot(newS(1,:),newS(2,:))   % first row is x coord, 2nd is y
   hold on
end

hold off
axis equal


viewname2.m

function viewname2(N,A)
% plots the name as given in the data in N, transformed by A
%  each row of N has: segment #, length, angle, x,y coord.

LS = [0 1; 0 0; 1 1];   % line segement from (0,0) to (1,0);
Nseg = size(N,1);   % number of segments

for i = 1:Nseg
   sx = N(i,2);        % length
   sy = sx;
   a  = N(i,3);        % angle
   a  = a*pi/180;      % convert to radians (if you used degrees)
   tx = N(i,4);        % coordinates
   ty = N(i,5);

   T = [sx*cos(a) -sy*sin(a) tx; sx*sin(a) sy*cos(a) ty; 0 0 1];
   newS = T*LS;        % transform the segment
   newS = A*newS;
   plot(newS(1,:),newS(2,:))   % first row is x coord, 2nd is y
   hold on
end

hold off
axis equal


Sample Movie
n = 36;   % number of frames (you can use more or less)
myaxis = [-5 9 -5 10];  % ADJUST THIS FOR YOUR PICTURES
axis(myaxis)
M = moviein(n);
sc = [0.9 0 0; 0 0.9 0; 0 0 1];
a = 10*pi/180;
rot = [cos(a) -sin(a) 0; sin(a) cos(a) 0; 0 0 1];
A = eye(3);   % 3x3 identity
for j=1:n
   viewname2(N,A)
   A = rot*sc*A;
   axis(myaxis)
   axis off
   M(:,j) = getframe;    % captures whatever is on the graph
end


Mail: ccollins@math.utk.edu