Parametric Rendering On The Web
Abstract
This report details the design and problems encountered in the creation of a web-page which graphs parametric equations. The web page utilizes the HTML form fill-out capability to interface with a C program (known as a CGI script), which then interfaces with Matlab's External Engine to render the graph. The C program creates a new web page which displays the graph, as well as supplying an additional form fill-out to transform (translate, scale, and rotate) the image. This form then interfaces with a second C program, which also uses Matlab to render the transformed graph. The transforming can repeat ad nauseum. 27 different kinds of two and three dimensional graphs can be plotted, as well as myriad plot options, to provide the user maximum flexibility. Due to the interface with Matlab, the user must use Matlab syntax to enter the equations. A tutorial is provided for those users not familar with it.
My project can be found here.
The Goal
The goal of this project was to create a web page, which could graph parametric equations (and secondarily transform the resulting graph), and could be usable by anyone with any web browser and from any computer.
Approaches
My first decision was to decide what tools I would use to design such a page. It appeared there were two options open to me:
- Create the page using Java.
- Use a CGI (Common Gateway Interface) C program which then interfaces with a graphics engine, such as Matlab's.
After researching the first option, I discarded the idea of using Java because one of the goals of the project was that any web browser on any computer should be able to display the image. This may very well be true in a few years, but for the present, Java is not omnipresent. A Java viewer has not, for example, come out for the Macintosh yet. Besides, even if the Java viewer is made for a computer, that does not necessarily mean everyone who owns that computer will have the Java viewer.
The essential difference between a CGI Script and a Java applet is that CGI programs run on the server, whereas Java runs on the web browser's computer. Therefore, with a CGI program, it does not matter what platform the browser is on. Matlab has a powerful external interface, capable of all the needs of this project, which CGI scripts can use. My decision was made.
The Early Design Stages
CGI scripts can be used for a variety of purposes; however, the most common one is for reading HTML form submissions. An HTML form allows the user to make choices and enter arbitrary text. These choices are represented as variables, and the whole set of variables, both name and value, are passed as environment variables to a CGI script which can read them.
I first set out to find a sample CGI Script form reader, the creation of which is not a trivial task. Since the external interface with Matlab is intended for C or Fortran use, I set out to find the C code for such a program (most CGI Scripts are written in Perl, since the variables are passed as strings). I used the code I found to create a sample form fill-out, a music survey. The variable parser used in that script proved indispensable to my later project.
Usage Of The Matlab External Interface
The Matlab external interface is very elegant in its simplicity, while retaining the power of the whole language. Essentially, it works by spawning a Matlab process, which can then be communicated with by sending strings to it to be evaluated as if they were actually being entered at Matlab's command prompt.
The user interface of my project took shape as one in which the fancy details of plotting, such as the colors involved and the line styles, would be presented via menus and radio boxes, but the actual equations to be plotted would be kept as strings and sent directly to Matlab to be evaluated as is.
From there, Matlab would plot the desired graph, and perform the gif conversion. It would also save all the variables in a workspace file, to be loaded again for the transforming program's use if necessary.
Capabilities/Examples Of The Graphing Page
16 types of one-parameter equation plots and 11 types of two-parameter equation plots can be chosen. There is a surface plot which takes into account lighting, and another which shows surface normals. What follows are some examples of these:
Equations entered for a surface plot:
- t0 = -31
- tf = 31
- n = 32
- theta = pi*t/n
- phi = (pi/2)*t/n
- x = cos(phi)'*cos(theta)
- y = cos(phi)'*sin(theta)
- choose 'use above as is' on meshgrid question
- z = sin(phi)'*ones(size(theta))
- c = hadamard(n)
- colormap cool
- faceted shading
- axis square
Equations entered for a surface with lighting plot:
- z = peaks(20)
- colormap hot
- shading interp
Equations entered for a surface with normals plot:
- t0 = -7.5
- tf = 7.5
- n = 30
- x = t
- y = t
- choose yes on meshgrid
- R = sqrt(x.^2 = y.^2) + eps
- z = sin(R)./R
The capabilities, explanations, and examples of every type of graph and every plot control feature are detailed in Graph-It's extensive on-line help
Capabilities And Theory Of Transforming Page
The transforming form utilizes the following equations:
- Translation
- x' = x + Tx
- y' = y + Ty
- z' = z + Tz
- Scaling
- x' = x*Sx
- y' = y*Sy
- z' = z*Sz
- X-axis Rotation
- x' = x
- y' = y*cos(Rx) - z*sin(Rx)
- z' = y*sin(Rx) + z*cos(Rx)
- Y-axis Rotation
- x' = x*cos(Ry) + z*sin(Ry)
- y' = y
- z' = -x*sin(Ry) + z*cos(Ry)
- Z-axis Rotation
- x' = x*cos(Rz) - y*sin(Rz)
- y' = x*sin(Rz) + y*cos(Rz)
- z' = z
The user is offered the option of keeping the axes as they were before the transformation; otherwise the only transform which changes the graph noticeably is rotation. Matlab just scales the appropriate axes in the case of the other two.
An example of a transformed sphere (of earlier example 1):
- keep axes as they were
- scale the y axis by 2
Overview Of The Graphing Program's Execution
- First, the CGI program parses the environment variables into a set of name/value pairs, in the order in which they came (on the form).
- The program then goes through the results of the form, variable by variable, and sends the appropriate strings to Matlab for evaluation.
- There are five main sections of the form: choice of plot, creation of the time vectors, equation fill-ins for one-parameter equations, equation fill-ins for the two-parameter equations, and the plot control options.
- The choice of plot determines which variable (x,y,z) section to evaluate and which to ignore.
- Once the equations have all been evaluated, the plot controls specified are stored (but not evaluated).
- The graph is plotted, along with all the plot controls, in one string sent for evaluation (this is an optimization; it would waste time to plot the graph, then force it to be re-plotted when the axes are changed).
- The graph is titled and the axes labelled (with the equations for x,y, and z if available).
- Necessary variables are stored in the workspace for transformation.
- The process id (of the C program) is obtained.
- The graph is converted to a gif and stored in a special graphs sub-directory (linked to one in the web directory), as well as the workspace (variables), using the process id in the name.
- The Graph Result Page is displayed, containing the graph and below it the transformation form fill-out.
- One of the choices in the transform fill-out sends the process id number to the transforming program.
- Day old graphs and workspaces are removed from the graphs directory to avoid unnecessary clutter.
Overview Of The Transforming Program's Execution
- Form variables are parsed.
- The old process id, the first variable from the form, is stored.
- Necessary variables are retrieved from the workspace with the appropriate process id, such as all the desired transform values.
- Transform starts with translation of x,y, and z. It then proceeds to scaling in that order, and then rotation in that order (around the appropriate axis).
- The graph is re-plotted.
- The new process id is obtained, and the new graph and workspace are saved with that in their names.
- The Graph Result is displayed as before.
- Day old files are removed as before.
The How And Why
Many of the steps taken above were in response to problems that deserve further discussion.
- A CGI Script cannot write a file to any directory but either the one it is in or a subdirectory there-of. An html document can only read files from directories designed as html-readable, or subdirectories there-of. This was a dilemma, since the C program created the gif in the CGI directory, but it needed to be read from the web directory. The solution was to create a graphs sub-directory in the web one, and create a symbolic link to it in the CGI one. Then both could read and write from a common subdirectory.
- When creating documents from a CGI such as gifs, there is no limit to the amount of users who may be attempting to view one at exactly the same time. It would not be fitting to have one file named graphs, overwritten each time, only to have one user receive a graph meant for another user's equations! The solution is to obtain the process id of each run of the CGI script, and name the gif with this. Individuality is thus maintained. This was used for the workspace files as well.
- The question of disk space. The gifs could be thrown away after viewing (although that would mean hitting reload would erase it) I suppose, but the workspace's could not. The idea of having the option to transform the existing graph ad infinitum means always keeping around the most current workspace file. This causes the problem of the graphs subdirectory filling up. The gifs only range from 6 to 20k, but the workspaces are usually around 60k. The solution was to use the find command to remove all files in the graphs directory with an access time of one day old or more. Thus, if you kept your web browser on for a full day, and then tried to transform the graph, an error would result. Not a very large problem.
- A slight modification was needed for the above, because when the last transformation is desired, the last workspace saved is never accessed, and thus the find command ignores it. A system call to touch solves this problem easily.
- It turns out the Engine interface is very sensitive to attempts to manipulate variables that are not there. When the form variables are passed to the transform phase, the transform code doesn't know whether all of x,y, and z are there. And even trying to retrieve those matrices and checking for their existence can cause the program to crash. The solution was to include in the saved workspace three boolean variables that told whether x, y, and z were there.
- Axes were labelled with the actual x, y, and z equations if present. However, problems arose when a transpose operator, ', was present in the equation; likewise for quotes in the title. This is because of the way the axes and title are labelled: axis(' ... ') A transpose inside the label will cause Matlab's string parser to reach a premature end. The solution is to double the quotes, as in other languages. For that task, all equations and the title had to pass through a parser which doubled all quotes present.
The Final Conflict
The last task of my project was to move the project from the Sunlab machines, where it was developed, onto the Theory Center machines. This task turned out to be the most frustrating of all. As far as I can tell, the Matlab External Interface on the TC machines was not set up correctly. Even attempting to run the sample source code that came with Matlab provided core dumps. Thus the transer was not accomplished. This result is disappointing, not only for the question of permanent storage, but also the expectations of faster processing by the more powerful Theory Center machines.
What I Might Have Done Differently
- It may have been better to just put the one-variable and two-variable equation sections together.
- I could have had a separate "form" submission on the page called "show example", which would have returned the same page again (through printf's), with examples filled in for the text areas. That would have been a good way to show people how to use the page. Secondary to that, at least having a separate form which graphed the example and showed the equations entered to produce such a plot.
- Perhaps run a survey of people to find out what features people thought were unnecessary.
Bibliography And Source Code
"The Student Edition of Matlab, Version 4 User's Guide", MathWorks Inc., Prentice Hall, Englewood Cliffs, NJ 07632, 1995
(although the interface is with the professional version)
"MATLAB User's Guide for UNIX workstations", MathWorks, Inc., 1992.
"3-D Computer Graphics, Second Edition", Alan Watt, Addison-Wesley, 1993
Download the source code
It is made up of six files:
- Makefile
- graphit.html
- graphit_help.html
- graphit.c
- transformIt.c
- util.c
Note that the paths set up in the Makefile for Matlab are for the Sunlab.