?? ch14.htm
字號:
filter so you can see the results as they are generated. However,understanding how the classes interrelate is a little tricky.Figure 14.1 shows the workflow involved in producing a Mandelbrotimage. Understanding this flow is the key to understanding thisproject.<P><A HREF="f14-1.gif" ><B>Figure 14.1 : </B><I>Workflow of producing a Mandelbrot image.</I></A><P>The process begins when an applet displaying Mandelbrot sets constructsa Mandelbrot object. (In this project, the two Applet classesare MandelApp and MandelZoomApp.) The Mandelbrot object, in turn,creates an instance of the CalculatorImage class. The Mandelbrotset passes itself as a part of the CalculatorImage constructor.It is referenced as a CalculatorProducer object, an interfacethat the Mandelbrot class implements. This interface implementationwill be used to communicate with the image filter.<P>In the next step, the applet requests a Mandelbrot image. Thisis initiated by calling the <TT>getImage()</TT>method of the Mandelbrot object, which in turn leads to a callto a like-named method of the CalculatorImage object. At thispoint, the CalculatorImage object first creates a color paletteby using an instance of the ImageColorModel class, then createsa MemoryImageSource object. This object, which implements ImageProducer,produces an image initialized to all zeros (black); it's combinedwith an instance of the CalculatorFilter class to produce a FilteredImageSource.<P>When the MemoryImageSource object produces its empty image, itis passed to the CalculatorFilter, which takes the opportunityto produce the calculated image. It does this by kicking off thethread of the image to be calculated. The CalculatorFilter doesn'tknow that it is the Mandelbrot set that's calculated-it just knowsthat some calculation needs to occur in the CalculatorProducerobject in which it has a reference.<P>Once the Mandelbrot thread is started, it begins the long calculationsto produce a Mandelbrot set. Whenever it finishes a section ofthe set, it notifies the filter with new data through the CalculatorFilterNotifyinterface. The filter, in turn, lets the viewing applet know thatit has new data to display by updating the corresponding ImageConsumer,which causes the applet's <TT>imageUpdate()</TT>method to be called. This causes a repaint, and the new imagedata to be displayed. This process repeats until the full imageis created.<P>As you have probably observed, this is a complicated process.Although the mechanics of image processing were introduced inPart III, it doesn't hurt to have another example. The Calculatorclasses here are meant to provide a generic approach toward manipulatingimages that need long calculations. You can replace the Mandelbrotclass with some other calculation thread that implements CalculatorProducer,and everything should work. A good exercise would be to replaceMandelbrot with another fractal calculation or some other scientificimaging calculation (I found that replacing Mandelbrot with aJulia fractal class calculation was very easy).<H2><A NAME="FractalsandtheMandelbrotSet"><FONT SIZE=5 COLOR=#FF0000>Fractalsand the Mandelbrot Set</FONT></A></H2><P>Before going into the internals of the classes that make up thisproject, it's worth spending a couple of moments to understandwhat's behind the images produced by the Mandelbrot class.<P>In the 1970s, Benoit Mandelbrot at IBM was using computers tostudy curves generated by iterations of complex formulas. He foundthat these curves had unusual characteristics, one of which iscalled <I>self-similarity</I>. The curves have a series of patternsthat repeat themselves when inspected more closely.<P>One of the characteristics of the curves Mandelbrot studied wasthat they could be described as having a certain dimensional qualitythat Mandelbrot termed "fractal." One of the fractalsthat Mandelbrot was investigating is called a <I>Julia set</I>.By mapping the set in a certain way, Mandelbrot came across aset that turned out to include all the Julia sets-a kind of amaster set that was deemed the <I>Mandelbrot set</I>. This sethas several spectacular features, all of them beautiful. The moststriking of these is its self-similarity and a extraordinary sensitivityto initial conditions. As you explore the Mandelbrot set, youwill be amazed by both its seeming chaos and exquisite order.<P>Figure 14.2 shows the famous Mandelbrot set, produced by thischapter's MandelApp applet. The figures in this chapter show thekind of images that appear when you zoom into various places inthis set. The Mandelbrot set is based on a seemingly simple iteratedfunction, shown in Formula 14.1.<P><A HREF="f14-2.gif" ><B>Figure 14.2 : </B><I>The full Mandelbrot set image.</I></A><HR><BLOCKQUOTE><B>Formula 14.1. Formula for calculating the Mandelbrot set.<BR></B></BLOCKQUOTE><BLOCKQUOTE><TT>z</FONT><FONT SIZE=1 FACE="Courier">n+1</FONT>=z</FONT><FONT SIZE=1 FACE="Courier">n2</FONT>+ c</TT></BLOCKQUOTE><HR><P>In Formula 14.1, <TT>z</TT> and <TT>c</TT>are complex numbers. The Mandelbrot set is concerned with whathappens when <TT>z0</TT> is zero and<TT>c</TT> is set over a range ofvalues. The real part of <TT>c</TT>is set to the x-axis, and the complex portion corresponds to they-axis. A color is mapped to each point based on how quickly thecorresponding value of <TT>c</TT>causes the iteration to reach infinity. The process of "zooming"in and out of the Mandelbrot set is equivalent to defining whatranges of <TT>c</TT> are going tobe explored. It is amazing that something so simple can yieldpatterns so sophisticated!<BR><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD><B>Note</B></TD></TR><TR VALIGN=TOP><TD><BLOCKQUOTE>If you are more interested in chaos and fractals, there are a lot of places to turn. <I>Chaos</I> by James Gleick (Penguin, 1987) is a layman's introduction to the ideas and discoveries that gave rise to chaos theory and the study of fractals. Mandelbrot's<I> The Fractal Geometry of Nature</I> (W.H. Freeman, 1983) lays out his ideas on fractals and nature. For a rigorous mathematical treatment of fractals, see the beautiful book <I>Fractals Everywhere</I> (Academic Press, 1988), written by one of the foremost figures in fractals, Michael Barnsley. Among other things, Barnsley is a major innovator on how to use fractal geometrics to achieve high rates of data compression. For a no-nonsense approach to writing programs that display fractals, see <I>Fractal Programming in C</I> by Roger T. Stevens (M&T Books, 1989). The algorithms for the Mandelbrot set were developed from this book. The C programs in this book map very easily to Java-except for the underlying graphics tools, which were developed for MS-DOS. However, the image calculation classes created in this chapter aim to fill this gap. With Stevens's book and these classes, you should be able to move his C code right over to Java and begin exploring the amazing world of fractals!</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><H2><A NAME="UsingtheApplets"><FONT SIZE=5 COLOR=#FF0000>Usingthe Applets</FONT></A></H2><P>There are two applets in this chapter. The first applet, MandelApp,generates the full Mandelbrot set. This will take a little while,depending on your computer; for example, on a 486DX2-50 PC, ittakes a couple of minutes. When the image is complete, indicatedby a message on the browser's status bar, you can save the imageto a BMP formatted file by clicking anywhere on the applet's displayarea. The file will be called mandel.bmp. Remember to run thisapplet from a program, such as appletviewer, that lets appletswrite to disk.<P>The other applet, MandelAppZoom, is more full-featured. It beginsby loading the Mandelbrot bitmap specified by an HTML applet parametertag. The default <TT>mandel1</TT>corresponds to a BMP file and a data file that specifies x-y parametervalues-included on this book's CD-ROM.<P>Once the image is up, you can pick regions to zoom in on by clickingon a point in the image, then dragging the mouse to the endpointof the region you want to display. Enter <TT>z</TT>or <TT>Z</TT> on the keyboard, andthe applet creates the image representing the new region of theMandelbrot set. The key to this applet is patience! The calculationscan take a little while to set up and run. The applet tries tohelp your patience by updating the status bar to indicate whatis going on. Furthermore, the image filter displays each columnof the set as the calculations advance.<P>You might select a region that doesn't appear to have anythinginteresting to show when you zoom in on it. You can stop a calculationin the middle by entering <TT>a</TT>or <TT>A</TT> on the keyboard. Theapplet will take a moment to wrap up, but then you can proceed.When you are having problems finding an interesting region tolook at, try increasing the size of the highlighted area. Thiswill yield a bigger area that is generated, giving you a betterfeel for what should be inspected. You get the best results byworking with medium-sized highlighted regions, rather than largeor small ones.<P>Figures 14.3 to 14.6 show what some of the zoomed-in regions ofthe Mandelbrot set look like. Figure 14.3 is a large area pickedabove the black "circles" of the full Mandelbrot set;Figure 14.5 explores an area between two of the black areas. Therichest displays seem to occur at the boundaries of the blackareas. The black color indicates that the particular value takesa long time to reach infinity. Consequently, these are also theregions that take the longest to calculate. You get what you payfor!<P><A HREF="f14-3.gif" ><B>Figure 14.3 : </B><I>Zoom in over block regions of Figure 14.2.</I></A><P><A HREF="f14-4.gif" ><B>Figure 14.4 : </B><I>Zoom in of Figure 14.3.</I></A><P>The zoom applet maintains a cache of processed images so you canmove back and forth among the processed images. Table 14.2 liststhe text codes for using the zoom applet.<P><A HREF="f14-5.gif" ><B>Figure 14.5 : </B><I>Zoom in between black regions of Figure 14.2</I></A><I>.</I><P><A HREF="f14-6.gif" ><B>Figure 14.6 : </B><I>Zoom in of Figure 14.5.</I></A><BR><P><CENTER><B>Table 14.2. Codes for controlling the Mandelbrot applet.</B></CENTER><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD WIDTH=97><CENTER><I>Characters</I></CENTER></TD><TD WIDTH=355><I>Action</I></TD></TR><TR VALIGN=TOP><TD WIDTH=97><CENTER><TT>A or a</TT></CENTER></TD><TD WIDTH=355>Abort current Mandelbrot calculation.</TD></TR><TR VALIGN=TOP><TD WIDTH=97><CENTER><TT>B or b</TT></CENTER></TD><TD WIDTH=355>Go to previous image.</TD></TR><TR VALIGN=TOP><TD WIDTH=97><CENTER><TT>F or f</TT></CENTER></TD><TD WIDTH=355>Go to next image.</TD></TR><TR VALIGN=TOP><TD WIDTH=97><CENTER><TT>C or c</TT></CENTER></TD><TD WIDTH=355>Remove all but full image from memory.</TD></TR><TR VALIGN=TOP><TD WIDTH=97><CENTER><TT>N or n</TT></CENTER></TD><TD WIDTH=355>Go to next image.</TD></TR><TR VALIGN=TOP><TD WIDTH=97><CENTER><TT>P or p</TT></CENTER></TD><TD WIDTH=355>Go to previous image.</TD></TR><TR VALIGN=TOP><TD WIDTH=97><CENTER><TT>S or s</TT></CENTER></TD><TD WIDTH=355>Save the current image to a BMP file prefixed by <TT>tempMandel</TT>.</TD></TR><TR VALIGN=TOP>`<TD WIDTH=97><CENTER><TT>Z or z</TT></CENTER></TD><TD WIDTH=355>Zoom in on currently highlighted region.</TD></TR></TABLE></CENTER><H2><A NAME="TheMandelbrotClass"><FONT SIZE=5 COLOR=#FF0000>TheMandelbrot Class</FONT></A></H2><P>The Mandelbrot class, shown in Listing 14.1, calculates the Mandelbrotset. It implements the Runnable interface, so it can run as athread, and also implements the CalculatorProducer interface,so it can update an image filter of progress made in its calculations.<P>There are two constructors for the Mandelbrot class. The defaultconstructor produces the full Mandelbrot set and takes the dimensionsof the image to calculate. The Real and Imagine variables in theconstructors and the <TT>run()</TT>method are used to map the x-y axis to the real and imaginaryportions of <TT>c</TT> in Formula14.1. The other constructor is used to zoom in on a user-definedmapping.<P>A couple of the other variables are worth noting. The variable<TT>maxIterations</TT> representswhen to stop calculating a number. If this number, set to <TT>512</TT>,is reached, then the starting value of <TT>c</TT>takes a long time to head toward infinity. The variable <TT>maxSize</TT>is a simpler indicator of how quickly the current value grows.How the current calculation is related to these variables is mappedto a specific color; the higher the number, the slower the growth.If you have a fast computer, you can adjust these variables toget a richer or duller expression of the Mandelbrot set.<P>Once the thread is started (by the CalculatorFilter object throughthe <TT>start()</TT> method), the<TT>run()</TT> method calculates theMandelbrot values and stores a color corresponding to the growthrate of the current complex number into a pixel array. When acolumn is complete, it uses the CalculateFilterNotify to let therelated filter know that new data has been produced. It also checksto see whether you want to abort the calculation. Note how itsynchronizes the <TT>stopCalc</TT>boolean object in the <TT>run()</TT>and <TT>stop()</TT> methods.<P>The calculation can take a while to complete. Still, it takesonly a couple of minutes on a 486-based PC. This performance isquite a testament to Java! With other interpreted, portable languagesyou would probably be tempted to use the reset button becausethe calculations would take so long. With Java you get fast visualfeedback on how the set unfolds.<P>A good exercise is to save any partially developed Mandelbrotset; you can use the <TT>saveBMP()</TT>method here. You also need some kind of data file to indicatewhere the calculation was stopped.<HR><BLOCKQUOTE><B>Listing 14.1. The Mandelbrot class.<BR></B></BLOCKQUOTE><BLOCKQUOTE><TT>import java.awt.image.*;<BR>import java.awt.Image;<BR>import java.lang.*;<BR><BR>// Class for producing a Mandelbrot set image...<BR>public class Mandelbrot implements Runnable, CalculatorProducer{<BR> int width; // The dimensions of theimage...<BR> int height;<BR> CalculateFilterNotify filter; // Keeps trackof image production...<BR> int pix[]; // Pixels used to construct image...<BR> CalculatorImage img;<BR> // General Mandelbrot parameters...<BR> int numColors = 256;<BR> int maxIterations = 512;<BR> int maxSize = 4;<BR> double RealMax,ImagineMax,RealMin,ImagineMin; //Define sizes to build...<BR> private Boolean stopCalc = new Boolean(false); //Stop calculations...<BR><BR> // Create standard Mandelbrot set<BR> public Mandelbrot(int width,int height) {<BR> this.width = width;<BR> this.height = height;<BR> RealMax = 1.20; //Default starting sizes...<BR> RealMin = -2.0;<BR>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -