GS 2003/Math - Collins
Lab 9
Graphical Transformations - Fractal Name

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.
Call the file name.m and have it create a variable segs

Here's an example
   segs = [
   0 1 1/2 0
   1/2 0 1 1/2
   0 1 1/2 2
   1/2 2 1 3/2];

Now copy the following file and save it as drawname.m
   function drawname(xx)
   % draws a list of segments
   N = size(xx,1);
   xl = min([min(xx(:,1)),min(xx(:,3))]);
   xr = max([max(xx(:,1)),max(xx(:,3))]);
   yt = max([max(xx(:,2)),max(xx(:,4))]);
   yb = min([min(xx(:,2)),min(xx(:,4))]);
   plot([xl xr],[yb yt],'w.')
   hold on
   for i = 1:N
   hold off

After you have created your file and entered the function
drawname, test your data by typing

Build the Transformations

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


The transformation for the segment (a,b) -> (c,d) is given by

        | c-a  b-d  a |
    T = | d-b  c-a  b |
        |  0    0   1 |

To store all the transformations (each a 3x3 matrix) we'll use
the cell structure in MATLAB.  For a cell array, use
curly brackets {} instead of regular parenthesis (). Thus
T{i} will the be the 3x3 transformation for segement
number i. Your function should return a cell-array of transformations,
one for each segment.

Fractal Your Name

To finish we need the routine transform.m from Lab 8.
You might already have it, otherwise, copy it from below
and save it.

Here's the big idea for the fracname: When we go to draw
a segment in your name, we instead use the transformations we
built to transform that segment into your name.  Thus every
segment in your name is then drawn as your name.  This
is a substitution rule fractal generator.


Make your name a list of points that covers the line
segment from (0,0) to (1,0)
Loop through the transformations
  Apply each transformation to the points in your
     name and draw the result
End Loop

If you don't want to write this program, you can copy fracname.m
from below and use it.  It is a script and it calls name
and all the other needed routines.  Once you save it, just type
to see the results.


1. Get your data file entered and get these functions working.
2. Print out your name in normal form.
3. Print out your name in fractal form.
4. (Fun) Modify fracname so that instead of using
   line segments to draw your name, it uses some other shape.
   Try using different colors.
5. (Challenge) Modify fracname so that it also applies
   another transformation before it does the final drawing,
   eg. apply a rotation or scaling or reflection.
6. (Challenge) Modify fracname so that it applies the
   substitution rule twice, i.e. each segment in your name is
   drawn using your name with each segment being your name.

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


function T = maketrans(xx)
% constructs a cell array of the transformations
% for each segment in xx

N = size(xx,1);   % number of segments
xm = max([max(xx(:,1)),max(xx(:,3))]);
xx = xx/xm;
T = cell(N,1);    % storage for transformations
for i = 1:N
   dx = xx(i,3)-xx(i,1);
   dy = xx(i,4)-xx(i,2);
   T{i} = [dx -dy xx(i,1); dy dx xx(i,2);0 0 1];


function newpts = transform(pts,T)
% applies the (homogeneous) transformation T to the points in pts

N = size(pts,1);         % number of points
pts = [pts,ones(N,1)];   % add 1s as 3rd coordinate
newpts = T*pts';         % apply T (turn pts around first)
newpts = newpts(1:2,:)'; % strip off 3rd coordinate and turn around


% script to read name data, construct transformations
%   and draw a fractal version of a name

name                 % run program which generates name data
N = size(segs,1);    % number of segments/transformations
T = maketrans(segs); % creates all the transformations; one per segment

xm = max([max(segs(:,1)),max(segs(:,3))]);   % finds length of name
segs = segs/xm;                        % rescale so fit unit segment
ym = max([max(segs(:,2)),max(segs(:,4))]);   % finds height of name
segs(:,[2,4]) = segs(:,[2,4]) - ym/2;   % centers on x-axis

plot(segs(1,1),segs(1,2),'w.')    % plot a dot to set the axis
hold on
pts1 = segs(:,1:2);    % convert name to 2 lists 
pts2 = segs(:,3:4);    %    of points
for i = 1:N          % loop through each transformation
   xp1 = transform(pts1,T{i});   % transform first points
   xp2 = transform(pts2,T{i});   % transform second points
   xp = [xp1,xp2];               % make list of segments
   drawname(xp)                  % draw name
   hold on
hold off