Contour Plotting in Java
Volume Number: 13
Issue Number: 9
Column Tag: Javatech
Contour Plotting In Java
by David Rand
Developing a simple, useful applet using Metrowerks
CodeWarrior Java
This article discusses a Java applet which plots contours based on a given matrix of
floating-point values. The idea is to present an algorithm which is simple enough to be
implemented in a few hundred lines of code yet which performs a useful, non-trivial
operation. Java is of course multi-platform, but this article focuses on development of
the applet on the Macintosh, using Metrowerks CodeWarrior Java (specifically,
CW11, which includes version 1.0.2 of the JDK). It is assumed that the reader is at
least somewhat familiar with the Java language and the CodeWarrior environment.
See, for example, Dave Mark's series of "Getting Started" articles [1] in MacTech
magazine.
A contour plot is a convenient way of representing three-dimensional data on a
two-dimensional surface such as a map or a computer screen. If you have ever gone
hiking and took with you a topographical map indicating the lay of the land, you have
used a contour plot. The lines of constant elevation are the contours. If the lines are
close together then we have a region of steep slope, whereas widely spaced lines
indicate more gradual slope. A closed contour looping back on itself indicates the
existence of an extremum - a peak or a depression - somewhere inside the loop. If the
extremum is pronounced, i.e. a sharp peak or a deep depression, then several such
loops will be nested together concentrically.
The Plotting Algorithm
The algorithm used for contour plotting is taken from a 1978 article by W. V. Snyder
[2]. The Java implementation was created by first translating Snyder's Fortran source
code manually into C, then reworking the C code to remove the many convoluted goto
constructs, and finally manually translating this "unravelled" C code into Java. The
second step, necessary because Java does not support goto statements, proved to be the
most laborious. This incompatibility should not be considered a limitation of Java; on
the contrary, it is a result of the lack of appropriate block structures in old versions
of Fortran.
The plotting algorithm can be summarized thus:
a) Given a matrix of floating point values which are the values of a function z = f(x,y)
given at the nodes of a grid of x and y values (the grid values are assumed equally
spaced, although the horizontal and vertical spacing may differ), the program
determines the minimum and maximum values of z and then computes a number of
contour values (in this implementation, 10 values) by linear or logarithmic
interpolation between the extrema.
b) The program "walks" about the grid of points looking for any segment (i.e. a line
joining two adjacent nodes in the grid) which must be crossed by one of the contours
because some contour value lies between the values of z at the nodes.
c) Having found such a segment, it finds the intersection point of the contour and the
segment by linear interpolation between the nodes. It also stores the information that
the current contour value has been located on the current segment, so that this
operation will not be repeated.
d) The program then attempts to locate a neighbouring segment having a similar
property - that is, crossed by the same contour. If it finds one, it determines the
intersection point as in step c) and then draws a straight line segment joining the
previous intersection point with the current one. This step is repeated until no such
neighbour can be found, taking care to exclude any segment which has already been
dealt with.
e) Steps b), c) and d) are repeated until no segment can be found whose intersection
with any contour value has not already been processed.
For a more detailed description of steps b) through e) of the algorithm, consult
Snyder's article. Note that, as stated in step d), the path of each contour is constructed
of linear segments, the simplest method possible. A more sophisticated algorithm,
based on bicubic Hermite polynomials, may be found in [3].
The CodeWarrior Project
The Java applet discussed in this article was developed using Metrowerks CodeWarrior
Java on a Power Macintosh. Figure 1 shows the window corresponding to the project
file named ContourPlotApplet.µ. Figure 2 illustrates the project settings.
Figure 1. The CodeWarrior Project.
Figure 2. The Project Settings.
The project includes an html file, four java files (one for each new class) and the file
classes.zip. The settings indicate that the project will generate an applet which will be
run using the Metrowerks Java interpreter, and the classes (the applet as well as the
three classes which it uses) will have their object code stored in class files in a folder
called Classes inside the same folder as the project file. When the project is run, the
interpreter will look in the html file for an dimensions and parameters of the applet. The html file can also be opened by a
Java-enabled web browser to run the applet from within the browser; this will
display the entire contents of the html file which may include instructions for using
the applet or any related documentation.
Figure 3. The ContourPlotApplet running in the Metrowerks Java interpreter.
Figure 4. The ContourPlotApplet running in Netscape Navigator 3.0 Gold on a
Macintosh.
Figure 3 shows the applet running in the Metrowerks Java interpreter. Figure 4
shows the same applet (although using different data) running as part of a page at the
web site of the CRM, Université de Montreal; the web server is a unix platform and the
web client, as shown in the figure, is Netscape Navigator running on a Power
Macintosh. To serve the applet in this way, all that is required in the unix file system
is to create a directory called Classes in the same directory as that containing the html
file and then to ftp (as raw data) the four class files from the Classes directory on the
Macintosh where they were developed to the Classes directory on the unix machine.
Figure 5. The ContourPlotApplet running in Netscape Navigator 3.01 on a unix
platform.
As an illustration of platform independence, Figure 5 also shows the applet running
in Netscape Navigator on a unix platform. The data here are the same as in Figure 3
except that logarithmic interpolation has been chosen. In addition, the eagle-eyed
reader will notice that the character strings - such as the prompt in the upper left
corner of the applet, the button, etc. - are in French. This is easily accomplished
without modifying the applet, simply by changing the parameters in the in the html file. This requires, of course, that any language-dependent elements not be
hard-coded in the Java source code. This approach is familiar to Macintosh
programmers, who know that strings and such should be stored in an application's
resource fork and not hard-coded in the application.
As shown in Figures 3, 4 and 5, there are six user-interface elements in the
applet, each implemented as a Java object of some type derived from the Component
class. The contour plot is the largest component and is located in the right-hand part of
the applet's rectangle. The other five components, all located in the left-hand part, are
1. The prompt "Matrix of z values:".