📄 ch32.htm
字号:
31 # $incr = increment<BR>
32 # $maxAngle = up to this angle.<BR>
33<BR>
34 sub tree {<BR>
35 my ($h,$x,$y,$theta,$flen)
= @_; # local variables<BR>
36 my ($nx,$ny,$nlen,$mycolor); #
for drawing to.<BR>
37 my ($i,$incr,$startAngle,$maxAngle);
# for the fanout<BR>
38 my ($randFans);<BR>
39<BR>
40 #<BR>
41 # Stopping conditions first.
<BR>
42 #<BR>
43 if ($h < 1) {<BR>
44 $im->filledRectangle($x-1,$base_y+$y-1,$x+2,$base_y+$y+2,$leaf);
<BR>
45 return
0; }<BR>
46 $nlen = $flen * $fanRatio;
<BR>
47 if ($nlen < 1) { return
0;}<BR>
48<BR>
49 $mycolor = $brown;<BR>
50 if ($h == 2) { $mycolor
= $color3; }<BR>
51 if ($h == 3) { $mycolor
= $color2; }<BR>
52 if ($h == 4) { $mycolor
= $color1; }<BR>
53 if ($h == 5) { $mycolor
= $color0; }<BR>
54 #<BR>
55 # Important!!!<BR>
56 #<BR>
57 $h -= 1; #
for recursion<BR>
58<BR>
59<BR>
60 $maxAngle = $theta + $fanAngle;
<BR>
61 $incr = ($maxAngle)/($maxfans
+ int(rand() * 3));<BR>
62<BR>
63 $startAngle = $theta - ($fanAngle/2);
<BR>
64<BR>
65 if ($startAngle < $NPIBY2)
{ $startAngle = $NPIBY2; }<BR>
66 if ($startAngle > $NPIBY2)
{ $startAngle = $PIBY2; }<BR>
67<BR>
68 # printf "\n From %5.1f
--> %5.1f, incr %5.1f",<BR>
69 # $startAngle,$maxAngle,
$incr;<BR>
70<BR>
71 for ($i = $startAngle ;
$i < $maxAngle; $i += $incr)<BR>
72 {
<BR>
73 $nx
= $nlen * sin($i);<BR>
74 $ny
= $nlen * cos($i);<BR>
75 #
<BR>
76 #
<BR>
77 #
<BR>
78 $im->line($x,$base_y+$y,$nx+$x,$base_y+$ny+$y,$mycolor);
<BR>
79 tree($h,$nx+$x,$ny+$y,$i,$nlen);
<BR>
80 }
<BR>
81 }<BR>
82<BR>
83 $height = 300;<BR>
84 $width = 300;<BR>
85 $maxfans = 3;<BR>
86 $maxdepth = 6;<BR>
87 $fanAngle = deg2rad(120); # Maximum
120 degrees<BR>
88 $fanRatio = 0.65; #
Each new branch is 4/5 of old.<BR>
89 $base_y = $height / 2;<BR>
90 #<BR>
91 #<BR>
92 #<BR>
93 $start_x = $width/2;<BR>
94 $start_y = 25;<BR>
95 $start_length = 80;<BR>
96 $start_angle = deg2rad(80);<BR>
97<BR>
98 srand(time);<BR>
99<BR>
100 use GD;<BR>
101<BR>
102 $im = new GD::Image(300,300);<BR>
103 $backgd = $im->colorAllocate(154,192,205);<BR>
104 $white = $im->colorAllocate(255, 255, 255);<BR>
105 $black = $im->colorAllocate(0, 0, 0);<BR>
106 $brown = $im->colorAllocate(188,130, 130);<BR>
107 $leaf = $im->colorAllocate(157,255,12);<BR>
108 $color0 = $im->colorAllocate(245,196,90);<BR>
109 $color1 = $im->colorAllocate(95,158,60);<BR>
110 $color2 = $im->colorAllocate(46,139,87);<BR>
111 $color3 = $im->colorAllocate(152,251,152);<BR>
112 $red = $im->colorAllocate(255,0,0);<BR>
113 $blue = $im->colorAllocate(0,0,255);<BR>
114 $im->transparent($white); # white
color is transparent<BR>
115 $im->interlaced(1); #
cool venetian blinds effect<BR>
116<BR>
117 tree ($maxdepth,$start_x,$start_y,$start_angle,$start_length);
<BR>
118<BR>
119<BR>
120 $text_y = $base_y / 2 + $width / 2;<BR>
121 $text_x = $width / 5;<BR>
122 $infoStr = "Welcome to Kamran's Home Page";<BR>
123 $dateStr = "Today is " . `date`;<BR>
124 $message = " http://www.ikra.com/index.html";
<BR>
125<BR>
126 $im->string(gdLargeFont,$text_x,$text_y,$infoStr,$red);
<BR>
127 $im->string(gdSmallFont,$text_x,$text_y + 30,$dateStr,$blue);
<BR>
128 $im->stringUp(gdLargeFont,10,$height - 10,$message,$blue);
<BR>
129<BR>
130<BR>
131 # print the image to stdout<BR>
132<BR>
133 $|=1;<BR>
134<BR>
135 print "Content-type: image/gif \n\n";<BR>
136 print $im->gif;</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
Lines 4 through 12 define some of the constants for using degrees
and radians. The script uses the following global variables:
<UL>
<LI><TT><FONT FACE="Courier">$height</FONT></TT> and <TT><FONT FACE="Courier">$width</FONT></TT>
are the extents of the image.
<LI><TT><FONT FACE="Courier">$maxfans</FONT></TT> is the maximum
number of sub-branches allowed per branch.
<LI><TT><FONT FACE="Courier">$fanAngle</FONT></TT> is the angle
where each new sub-branch is created.
<LI><TT><FONT FACE="Courier">$fanRatio</FONT></TT> is the ratio
of the length of the new branch to the length of its parent branch.
</UL>
<P>
Each call to the recursive function, <TT><FONT FACE="Courier">tree()</FONT></TT>,
uses the following variables:
<UL>
<LI><TT><FONT FACE="Courier">$h</FONT></TT> is the current depth
in recursion.
<LI><TT><FONT FACE="Courier">$x</FONT></TT> is the current <TT><FONT FACE="Courier">x</FONT></TT>
to draw from.
<LI><TT><FONT FACE="Courier">$y</FONT></TT> is the current <TT><FONT FACE="Courier">y</FONT></TT>
to draw from.
<LI><TT><FONT FACE="Courier">$theta</FONT></TT> is the angle to
start drawing from.
<LI><TT><FONT FACE="Courier">$flen</FONT></TT>is the length of
the current branch.
</UL>
<P>
If the depth is <TT><FONT FACE="Courier">1</FONT></TT> or less,
the <TT><FONT FACE="Courier">tree()</FONT></TT> function draws
a rectangle at the current location and backs out of the recursion.
See lines 43 and 44. It also backs out without drawing a leaf
if the new branch is too small to draw.
<P>
Different colors are used based on the depth of the recursion
in lines 49 through 53.
<P>
Line 57 is where the depth of the recursion is marked off. The
value of <TT><FONT FACE="Courier">$h</FONT></TT> is decremented
before a recursive call to <TT><FONT FACE="Courier">tree()</FONT></TT>
is made. Lines 60 to 66 make sure that the <I>fanout</I> (maximum
number of degrees between the outer most branches) and number
of sub-branches is set in the correct <TT><FONT FACE="Courier">-PI/2</FONT></TT>
to <TT><FONT FACE="Courier">+PI/2</FONT></TT> range. You may want
to customize these lines to see how you want your tree to "grow."
<P>
At line 71 we use a <TT><FONT FACE="Courier">for</FONT></TT> loop
to make a recursive call to the <TT><FONT FACE="Courier">tree()</FONT></TT>
function with different fanout angles, locations to draw, and
colors.
<P>
The initialization of global variables is done from lines 83 to
98. The random number generator is seeded at line 98.
<P>
The image is created at line 102, with colors for its components
created in lines 103 to 115. The <TT><FONT FACE="Courier">tree()</FONT></TT>
function is called at line 117. Add more calls to <TT><FONT FACE="Courier">tree()</FONT></TT>
if you want more than one tree printed. Some text is drawn in
the image area to customize the output in the lines up to 131.
<P>
Lines 133 to 136 actually print the image to standard output as
the response to an HTTP request.
<P>
To use the previous listing in an HTML file, you can add this
tag to an HTML page:
<BLOCKQUOTE>
<TT><IMG SRC="http://www.ikra.com/cgi-bin/tree.pl"></TT>
</BLOCKQUOTE>
<P>
The browser showing the HTML page will call the <TT><FONT FACE="Courier">tree.pl</FONT></TT>
script, which in turn will return the GIF image back. Therefore,
every time you reload the Web page, you'll see a new image. Neat.
Actually, you can also refer to the <TT><FONT FACE="Courier">tree.pl</FONT></TT>
in the Location prompt on your browser. Refer to Figure 32.5 to
see how it's referred to in a URL. The script is called <TT><FONT FACE="Courier">fractal.pl</FONT></TT>
in Figure 32.5.
<P>
<A HREF="f32-5.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f32-5.gif" ><B>Figure 32.5 : </B><I>Dynamic image creating with Web pages.</I></A>
<P>
You can see how easy it is to create GIF images on-the-fly and
use them in Web pages. Using the <TT><FONT FACE="Courier">GD.pm</FONT></TT>
module, it's easy to have Perl write your output as a GIF file
for use in other applications.
<H2><A NAME="Summary"><B><FONT SIZE=5 COLOR=#FF0000>Summary</FONT></B></A>
</H2>
<P>
In this chapter I covered two ways of creating images: using <TT><FONT FACE="Courier">gnuplot</FONT></TT>
and directly through the use of the <TT><FONT FACE="Courier">GD.pm</FONT></TT>
module. The <TT><FONT FACE="Courier">gnuplot</FONT></TT> method
is simpler to use when you have a set of data points in a logical
order that can be read directly from within <TT><FONT FACE="Courier">gnuplot</FONT></TT>.
An example for using <TT><FONT FACE="Courier">gnuplot</FONT></TT>
is when drawing charts and 3D plots. If you are drawing more than
just charts and plots, consider generating the images directly
from within Perl by using the <TT><FONT FACE="Courier">GD.pm</FONT></TT>
module. Using <TT><FONT FACE="Courier">GD.pm</FONT></TT> is a
bit more difficult because you have to manage the details of drawing
yourself, but it does eliminate the need for an external program
like <TT><FONT FACE="Courier">gnuplot</FONT></TT>.
<P>
<HR WIDTH="100%"></P>
<CENTER><P><A HREF="ch31.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch31.htm"><IMG SRC="pc.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/pc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="#CONTENTS"><IMG SRC="cc.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/cc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="index.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/index.htm"><IMG SRC="hb.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/hb.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="ch33.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch33.htm"><IMG
SRC="nc.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/nc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A></P></CENTER>
<P>
<HR WIDTH="100%"></P>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -