📄 ch32.htm
字号:
<P>
Now let's look at how to plot 3D images using <TT><FONT FACE="Courier">gnuplot</FONT></TT>.
Rather than writing your own 3D plotting software, it's probably
better to use <TT><FONT FACE="Courier">gnuplot</FONT></TT>. In
fact, in the next section, "Using the Output in CGI Applications,"
we'll only draw 2D plots. For quick plots of 3D data, using <TT><FONT FACE="Courier">gnuplot</FONT></TT>
will be faster than rolling your 3D-rendering software.
<P>
Here's another example of how to use <TT><FONT FACE="Courier">gnuplot</FONT></TT>
to print the output of a Perl script. Look at Listing 32.3, which
generates the image shown in Figure 32.2. The formula in Listing
32.3 produces a nice wave form with an equation from a math textbook.
The formula is code in lines 7 and 14. The complete formula for
generating the points on a surface is:
<P>
<A HREF="f32-2.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f32-2.gif" ><B>Figure 32.2 : </B><I>Using 3D plots.</I></A>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">z = C * sin( 2 * A * PI * sqrt($x * $x
+ $y * $y)) ;</FONT></TT>
</BLOCKQUOTE>
<P>
where <TT><FONT FACE="Courier">A</FONT></TT> and <TT><FONT FACE="Courier">C</FONT></TT>
are constants that the user can play with in order to affect the
number and <BR>
amplitude of the waves generated. The display output from the
points generated with this <BR>
formula is shown in Figure 32.2.
<HR>
<BLOCKQUOTE>
<B>Listing 32.3. Using </B><TT><B><FONT FACE="Courier">gnuplot</FONT></B></TT><B>
to generate images.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #!/usr/bin/perl<BR>
2 #<BR>
3 # Check out the use of GNU plot.<BR>
4 $a=3.0;<BR>
5 $c=0.25;<BR>
6 $pi= 3.141593;<BR>
7 $ta = 2 * $a * $pi;<BR>
8<BR>
9 open( PLOTFILE, ">tdata") || die "\n
Cannot open plot file $! \n";<BR>
10<BR>
11 for($x=-1;$x < 1 ;$x += 0.02) {<BR>
12 for($y= -1 ;$y < 1.00;$y +=
0.02) {<BR>
13<BR>
14 $z = $c
* sin( $ta * sqrt($x * $x + $y * $y)) ;<BR>
15 printf
PLOTFILE "%6.3f\n", $z;<BR>
16 }<BR>
17 print PLOTFILE "\n";
<BR>
18 }<BR>
19 close PLOTFILE;<BR>
20<BR>
21<BR>
22 open (GNUPLOT,"| gnuplot");<BR>
23<BR>
24 print GNUPLOT <<gnuplot_commands;<BR>
25 set term pbm color small<BR>
26 set output "myoutput.pbm"
<BR>
27 set noparametric<BR>
28 set title "Test GNUPLOT"
<BR>
29 splot "tdata"<BR>
30 gnuplot_commands<BR>
31<BR>
32<BR>
33 close GNUPLOT;<BR>
34<BR>
35 `ppmtogif myoutput.pbm > myoutput.gif 2>/dev/null
`;</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The constants for the formula used in this program are defined
in lines 4 through 7. The plot file to hold the intermediate points
is the <TT><FONT FACE="Courier">tdata</FONT></TT> file, which
is opened in line 9. All points stored in the data file are stored
in a matrix form with a value of <TT><FONT FACE="Courier">z</FONT></TT>
for each <TT><FONT FACE="Courier">x,y</FONT></TT> location in
the matrix. This format is the nonparametric form of data for
<TT><FONT FACE="Courier">gnuplot</FONT></TT>. (The parametric
form involves writing vectors to create wire frame models and
is thankfully beyond the scope of this book.) Each line in the
input file is one row of <TT><FONT FACE="Courier">x</FONT></TT>
coordinates. All <TT><FONT FACE="Courier">y</FONT></TT> coordinate
values for the row are stored in a line. At line 22, we open a
pipe to <TT><FONT FACE="Courier">gnuplot</FONT></TT>. The commands
sent to <TT><FONT FACE="Courier">gnuplot</FONT></TT> are slightly
different here because we are plotting nonparametric data with
the height of each <TT><FONT FACE="Courier">z</FONT></TT> coordinate
given in a matrix. The <TT><FONT FACE="Courier">x</FONT></TT>
and <TT><FONT FACE="Courier">y</FONT></TT> coordinates will be
the row and column number from which the data is picked up. The
terminal type is set to PBM output in color using small fonts.
The output file is set to <TT><FONT FACE="Courier">myoutput.pbm</FONT></TT>
instead of the terminal. The title of the plot is set to <TT><FONT FACE="Courier">Test
GNUPLOT</FONT></TT>. We have to explicitly force <TT><FONT FACE="Courier">gnuplot</FONT></TT>
to the nonparametric mode for the type of data we are about to
feed it. Finally, the <TT><FONT FACE="Courier">splot</FONT></TT>
command is used to render a 3D image with the data in the file
<TT><FONT FACE="Courier">tdata</FONT></TT>.
<P>
As in Listing 32.2, the output is converted from PBM to GIF format
with this line:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">35 `ppmtogif myoutput.pbm > myoutput.gif
2>/dev/null `;</FONT></TT>
</BLOCKQUOTE>
<P>
The output can be viewed with <TT><FONT FACE="Courier">xv</FONT></TT>,
as before, using the <TT><FONT FACE="Courier">`xv myoutput.gif`</FONT></TT>
command. Instead of doing this, let's see how the images can be
sent as GIF images for use with World Wide Web browsers.
<H2><A NAME="UsingtheOutputinCGIApplications"><B><FONT SIZE=5 COLOR=#FF0000>Using
the Output in CGI Applications</FONT></B></A></H2>
<P>
The output from both the programs shown in Listings 32.2 and 32.3
are GIF files. The output can be used in HTML pages in two steps
from the Web browser side:
<OL>
<LI>Call the Perl script to render the image.
<LI>Reload the page with the URL pointing to the image created
by the Perl script.
</OL>
<P>
There are two glaring problems with using Perl and <TT><FONT FACE="Courier">gnuplot</FONT></TT>
in this manner. First, you are creating two steps for the user
to work through. Second, reloading an image in a browser may reload
the cached version of the image at the client side and not the
image at the server side. So, unless the user flushes the images
at the browser side, he or she is not likely to see the changes
in the image.
<P>
A way out of these problems is to use the image-generating Perl
script as the URL instead of the image file itself. The Perl script
will have to be modified to print out the MIME header and the
contents of the image back to the standard output. To do this,
replace line 35 in Listing 32.2 with these three lines:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$| = 1;<BR>
print "Content-Type: image/gif \n\n";<BR>
system('ppmtogif myoutput.pbm 2>/dev/null');</FONT></TT>
</BLOCKQUOTE>
<P>
The first of the three lines shown here will force flushing of
all output to standard output immediately. This is required for
Perl scripts that are replying to Web browsers. The next line
sets the MIME header required for all GIF images being sent back
to the browser. The two carriage returns in the <TT><FONT FACE="Courier">print</FONT></TT>
line are required, so do not remove them. If you do not place
the two carriage returns, the browser requesting the image is
likely to hang up. The last line is very similar to line 35, except
that the output from the <TT><FONT FACE="Courier">pptogif</FONT></TT>
program is sent to <TT><FONT FACE="Courier">stdout</FONT></TT>
instead of a file. Since this Perl script is called to send replies
back to a browser, the GIF image just created will be sent back.
<P>
The URL for the Perl script is the filename for the Perl program
itself. See Listing 32.4 for a sample HTML page using this URL.
Note how the URL for the <TT><FONT FACE="Courier">IMG</FONT></TT>
tag is set to a Perl script. The output for the HTML file is shown
in Figure 32.3.
<P>
<A HREF="f32-3.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f32-3.gif" ><B>Figure 32.3 : </B><I>Using plots with HTML files.</I></A>
<HR>
<BLOCKQUOTE>
<B>Listing 32.4. The HTML page using GIF images.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 <HTML><HEAD><TITLE>MPS
Inc. Home Page </TITLE><BR>
2 </HEAD><BR>
3 <BODY><BR>
4 <P><BR>
5 <p><BR>
6 <H2>Test loading images </H2><BR>
7 <P><BR>
8 <FORM NAME="mineFormkh"><BR>
9 <IMG SRC="http://ikra.com/cgi-bin/my3D.pl"
BORDER > <B>Hello</B><BR>
10 </FORM<BR>
11 </BODY><BR>
12 <HTML></FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
So far, you've learned how to create GIF files from within a Perl
script using <TT><FONT FACE="Courier">gnuplot</FONT></TT>. Next,
you'll generate GIF files directly without using external programs
by using the <TT><FONT FACE="Courier">GD.pm</FONT></TT> module.
<H2><A NAME="CreatingGIFImagesDirectlyfromPerl"><B><FONT SIZE=5 COLOR=#FF0000>Creating
GIF Images Directly from Perl</FONT></B></A></H2>
<P>
The primary motivation for using the <TT><FONT FACE="Courier">GD.pm</FONT></TT>
library is that it's easy to create GIF images directly from within
Perl programs. The module is loaded directly into a Perl program
and does not involve the use of system resources in order to convert
to a different format.
<P>
The <TT><FONT FACE="Courier">GD.pm</FONT></TT> module has been
developed and placed in the CPAN archives by Leonard Stein (<TT><FONT FACE="Courier">lstein@genome.wi.mit.edu</FONT></TT>).
You can find an HTML page with good information about this package
at
<BLOCKQUOTE>
<TT><A HREF="http://www-genome.wi.mit.edu/~lstein" tppabs="http://www-genome.wi.mit.edu/~lstein">http://www-genome.wi.mit.edu/~lstein</A></TT>
</BLOCKQUOTE>
<P>
Go to the nearest CPAN site to get the tar file with the module
and extensions. The files used in this chapter are collected from
the CPAN archive at
<BLOCKQUOTE>
<TT><A HREF="http://www-genome.wi.mit.edu/ftp/pub/software/WWW/GD.html" tppabs="http://www-genome.wi.mit.edu/ftp/pub/software/WWW/GD.html">http://www-genome.wi.mit.edu/ftp/pub/software/WWW/GD.html</A></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">GD.pm</FONT></TT> library relies
on a C function library called <TT><FONT FACE="Courier">libgd</FONT></TT>.
This library has been developed by Tom Boutell (<TT><FONT FACE="Courier">boutell@boutell.com</FONT></TT>).
There is a great detailed Web page available that you can see
at
<BLOCKQUOTE>
<TT><A HREF="http://www.boutell.com/gd" tppabs="http://www.boutell.com/gd">http://www.boutell.com/gd</A></TT>
</BLOCKQUOTE>
<P>
The version used for this book is 1.2; however, it's best if you
use the latest version.
<P>
You have to take two steps to install both these libraries. First,
install the <TT><FONT FACE="Courier">gd</FONT></TT> library, and
then install the <TT><FONT FACE="Courier">GD.pm</FONT></TT> module
and its libraries. Use only <TT><FONT FACE="Courier">gcc</FONT></TT>
for compiling all the <TT><FONT FACE="Courier">gd</FONT></TT>
code. The code hasn't been tested with many ANSI C compilers and
might not work with any other type of compiler. In the example
for this book, the code only worked and compiled cleanly with
<TT><FONT FACE="Courier">gcc</FONT></TT>, and the makefile did
not work with Visual C++. If you are using the Microsoft VC++
compiler, stop. Get a version of <TT><FONT FACE="Courier">gcc</FONT></TT>
and use it instead if you don't want to mess with the makefiles.
<H3><A NAME="InstallingthegdLibrary"><B>Installing the </B><TT><B><FONT SIZE=4 FACE="Courier">gd</FONT></B></TT><B><FONT SIZE=4>
Library</FONT></B></A></H3>
<P>
Installing the <TT><FONT FACE="Courier">gd</FONT></TT> library
and source code involves these steps:
<OL>
<LI>Uncompress the distribution file and untar the distribution
with the command <BR>
<TT><FONT FACE="Courier">tar -xvf gd1.2.tar</FONT></TT>.
<LI><TT><FONT FACE="Courier">cd</FONT></TT> to the <TT><FONT FACE="Courier">gd1.2</FONT></TT>
directory.
<LI>Run <TT><FONT FACE="Courier">make</FONT></TT> to create the
programs and the <TT><FONT FACE="Courier">libgd.a</FONT></TT>
file.
<LI>Run <TT><FONT FACE="Courier">ranlib libgd.a</FONT></TT> to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -