Fractals/fractint

From Wikibooks, open books for an open world
Jump to navigation Jump to search

Fractint is a freeware computer program that can render and display many kinds of fractals. Source code is available

Authors[edit | edit source]

The primary authors of Fractint 19.5 are:

  • Bert Tyler
  • Timothy Wegner
  • Jonathan Osuch
  • Wesley Loewer

code[edit | edit source]


Images[edit | edit source]

commons:Category:Fractals created with Fractint

Fractint parameters[edit | edit source]

Fractint image information

Image Calculation Parameters[edit | edit source]

 CORNERS=[xmin/xmax/ymin/ymax[/x3rd/y3rd]]

"Example: corners=-0.739/-0.736/0.288/0.291 Begin with these coordinates as the range of x and y coordinates, rather than the default values of (for type=mandel) -2.0/2.0/-1.5/1.5. When you specify four values (the usual case), this defines a rectangle: x- coordinates are mapped to the screen, left to right, from xmin to xmax, y-coordinates are mapped to the screen, bottom to top, from ymin to ymax. Six parameters can be used to describe any rotated or stretched parallelogram: (xmin,ymax) are the coordinates used for the top-left corner of the screen, (xmax,ymin) for the bottom-right corner, and (x3rd,y3rd) for the bottom-left. Entering just "CORNERS=" tells Fractint to use this form (the default mode) rather than CENTER-MAG (see below) when saving parameters with the [B] command."[1]

 CENTER-MAG=[Xctr/Yctr/Mag[/Xmagfactor/Rotation/Skew]]

"This is an alternative way to enter corners as a center point and a magnification that is popular with some fractal programs and publications. Entering just "CENTER-MAG=" tells Fractint to use this form rather than CORNERS (see above) when saving parameters with the [B] command. The [TAB] status display shows the "corners" in both forms. When you specify three values (the usual case), this defines a rectangle: (Xctr, Yctr) specifies the coordinates of the center of the image while Mag indicates the amount of magnification to use. Six parameters can be used to describe any rotated or stretched parallelogram: Xmagfactor tells how many times bigger the x- magnification is than the y-magnification, Rotation indicates how many degrees the image has been turned, and Skew tells how many degrees the image is leaning over. Positive angles will rotate and skew the image counter-clockwise."

Mag indicates the amount of magnification to use. Initial value ( no zoom ) is 6.66666667e-01. "If the magnification is set to 1, the range on the Y axis is +1 to -1 - this is zoomed in too much and cuts off some of the top & bottom bulbs on the Mandelbrot set. With magnification set to .666666667, the range on the Y axis is +1.5 to -1.5, which gives a view of the complete Mandelbrot set. " (Ryan Davenport )[2]

/* 
frames.c - frames for endless zoom 
http://www.nahee.com/spanky/www/fractint/loewer/frames.c
Results of Wesley Loewer's Study : 
"The C program, frames.c, was used to generate the batch file, using "frames > tmp.bat" at the command line prompt.   I put the following in my sstools.ini and then ran tmp.bat.

      batch=y
      video=f3
      sound=off
      float=y
      passes=b
      viewwindows=///128/128 
      maxiter=1000
      colors=000_HcaDhc9n<2>YGkD_HEdH76H<2>50GTWJ<2>YLZA7F<73>YQo\
      000<75>IdU111<36>igu102<14>SAi000<13>5815917105A1<14>AJ3
When I stitched them together in an animation, the last frame looks just like the first frame."

*/
 
#include <stdio.h>
#include <math.h>

main(int argc, char *argv[])
{
	int frame, frames;
	double zoom, relzoom, zoomfactor;

    zoom = 1e5; /* seems like a deep enough starting place */
	relzoom = pow(2.0, 2.5*8); /* 2**(2.5 * 8 steps/lap ) */
	frames = 100;
	zoomfactor = pow(relzoom, 1.0 / (frames - 1));
	for (frame = 0; frame < frames; frame++)
	{
		printf("fractint center-mag=0/1/%g\n", zoom);
		zoom *= zoomfactor;
	}
	return 0;
}
/* 
frames45.c - frames at 45 degree increments using autokey option 
http://www.nahee.com/spanky/www/fractint/loewer/frames45.c
Results of Wesley Loewer's Study : 
"The C file, frames45.c, generates an auto.key script to produce the whole sequence of frames via FractInt's "g" command.   
After compiling frames45.c, at the command line prompt, just enter "frames45 > auto.key".   
Then I started FractInt with:

      video=af3 
      float=y
      viewwindows=///128/128 
      passes=b 
      maxiter=5000
      autokey=play
and away it went. "
*/

#include <stdio.h>
#include <math.h>

main(int argc, char *argv[])
{
	int angle, frame, frames;
	double zoomfactor, zoom;

	frames = 100;
	zoomfactor = pow(2.0, 2.5);
	zoom = 1.0; /* looks like a good starting place */
	angle = 0;
	for (frame = 0; frame < frames; frame++)
	{
		printf(
"\"g\"\n"
"\"center-mag=0/1/%g/1.333333/%d\"\n"
"ENTER\n"
"CALCWAIT\n"
"\"s\"\n"
"CALCWAIT\n"
"\"eh..\"\n"
"ESC\n\n"

			, zoom, angle);
		zoom *= zoomfactor;
		angle = (angle + 45) % 360;
	}
	return 0;
}

fractint files[edit | edit source]

Most important files are :

  • par files - plane description and build-in type
  • frm files - fractal type ( formula). Here one cendefine iterated function ( map)
  • map files - color gradient. In Fractint map denotes color gradient not function ( math formula)
  • IFS Files - *.ifs

gif[edit | edit source]

  • Fractint does save the parameters in its GIF file
  • one can use command line to extract par file from the gif file
wine fractint.exe foo.gif makepar=bar.par/foo


formula[edit | edit source]

# https://www.fractalforums.com/mandelbrot-and-julia-set/is-there-anything-novel-left-to-do-in-m-like-escape-time-fractals-in-2d/255/
# fracmonk
e90circs(xyaxis) {;z0=+,-sqrt(2)
  z=sqrt(2), c=pixel:;no
    s=z*z           ;periodicity
    t=s*s           ;testing!
    z=(1/s-(1/t))*c
    |z| < p3
}
DM54(xaxis) {;deg 10
  c=pixel, z=p1, d=p2:;quasi M2
    q=z*z       ;d=1:z0=4/5=.8
    r=q*q       ;only!
    s=r*z       ;nonstandard
    t=(s-r)*c-d ;dendritic
    z=t*t       ;structure
    |z| < p3
}

Notes:

  • If a-b>1 AND b=1, then the sets will look similar to the a-b=1 case, but will be surrounded by infinite numbers of satellite islands of varing size,
  • for b=1, use sqrt(3)= .5773503... for a=3, and cuberoot(4)=.6299605...

map[edit | edit source]

FractInt palettes have 256 colours (of which the first is reserved for interior). They are stored as 6bit RGB, encoded in ASCII. Gradients of slowly changing colours are compressed as two endpoints and a count. Check FractInt documentation Topic=Color Specification for details. (Claude Heiland-Allen )


Conversions


One can use/check Fractint map files in Gnuplot:

 set palette file "Skydye07.map" using ($1/255):($2/255):($3/255) # Read in a palette of RGB triples each in range [0,255]
 test palette


Fractint_default_colour_map (256 colors) serving for 4 different needs in a single colour table[5]

  • 0..15: The first 16 colours are encoded exactly as with all 16 colour modes (0Dh/0Eh/10h/12h) which in turn use the same 4 bit encoding as the colour attributes of all text modes (*1). It is backward compatible with the EGA and CGA adapters.
  • 16..31: The next 16 deliver an even lit 4 bit black (10h) to white (1Fh) grayscale ( binary coded gray scale)
  • 32..247: 216 (3x8x3x3) colours: an evenly spaced, HSV colour cylinder (*2) based on a
    • 24 hue RGB wheel, starting at blue, with 8 subdivisions per R,G and B, resulting in 24 (3x8) discrete "hues". Each of those is present in
    • 3 level of saturation (colourfulness)
    • 3 level of intensity(value of brightness)
  • 248..255: 8 color (= 256 - (16 + 16 + 216)) definitions are guaranteed free for user applications ( user definable colours), usually black. 8 unused definitions. By guaranteeing that the BIOS will not touch them.

VGA color index for 256 colors (= 16x16). It shows index not directly rgb color value.

VGA color idex values:

  • decimal: from 0 to 255
  • hexadecimal: from #00 to #FF ( or $00 in old notation)[6]


See also:

  • M Sargent: MAPView : This is a stand-alone program that displays the color spectrum of any selected MAP file.
  • M Sargent: MAP file collection - Fractint 256-color MAP files ( color palettes). They are text files containing RGB triplets, which are easy to create or edit. This ZIP archive contains a small collection. There are hundreds if not thousands of these files available on the Web. The programs allow you to select MAP files from their GUI menus, and usually show a preview of their color spectra.
  • Fractal-Zoomer color maps ( the same structure as for Fractint)

par[edit | edit source]

"Fractint uses Parameter files[7][8] to save/restore all options and settings,[9] required to recreate particular images. The parameters required to describe an image require very little disk space, especially compared with saving the image itself. " [10]

Parameter files

  • They are ordinary text files
  • can contain parameter for one file or named groups of parameters, looking something like this:

    name { ; main comment 
         ....
         } 
      
    quickdraw {      ; a set of parameters named quickdraw
       maxiter=150
       float=no
       }
    slowdraw {       ; another set of parameters named slowdraw
       maxiter=2000
       float=yes
       }

These sections are called parset sections and describe a fractal equation, a view area, parameters and a color palette.[11]

For standard view of parameter plane and Mandelbrot set :

Mandel_Demo        { ; PAR for initialization of Fractint demo
  reset=1900 type=mandel corners=-2.5/1.5/-1.5/1.5 params=0/0 inside=0
  sound=no
  }

or :[12]

1_01                  { ; quite good spirals 
  reset=2000 type=mandel passes=1
  corners=-0.6014129278/-0.5990935452/0.427747516/0.429487053
  params=0/0 float=y maxiter=1000 inside=0 outside=15
  distest=1/10/320/200 
  }

1_02                  { ; stringy one, with dist estimator
  reset=2000 type=mandel passes=1
  corners=-1.9228429644992/-1.9228427944992/-6.3749991620026e-008/6.375000\
  8379971e-008 params=0/0 float=y maxiter=1000 inside=0 outside=15
  distest=1/20/320/200
  }

1_03                  { ; OK, bit dull, not zoomed in far 
  reset=2000 type=mandel passes=1
  corners=0.3734922373/0.3820837907/-0.243292645/-0.23684898
  params=0/0 float=y maxiter=1000 inside=0 outside=15
  distest=1/10/320/200
  }

1_04                  { ; a mess, needs dist est
  reset=2000 type=mandel passes=1
  corners=-1.862224008886682/-1.86222400040936/-3.214020831358832e-009/3.1\
  43970347410528e-009 params=0/0 float=y maxiter=1000 inside=0
  outside=15 distest=1/10/320/200 
  }

1_05                  { ; A twirly twiddly one 
  reset=2000 type=mandel passes=1
  corners=-0.77464016774366/-0.77463987034365/0.12426328506998/0.124263508\
  11999 params=0/0 float=y maxiter=1000 inside=0 outside=15
  distest=1/10/320/200 
  }

Parameter file for FractInt ( extension PAR) :

top-mag1500      { ; a really really deep zoom        Wesley Loewer
                   ; highly self similar
                  ; took over 1200 hours at 320x240 on a 486sx/25
                  reset=1920 type=mandel passes=b center-mag=0.0/1.0/1e+1500
                  maxiter=15000  }

Julia set :

test               {
  reset=2004 type=julia center-mag=0/0/0.6666667
  params=-0.49749687108886109/-0.0025041736227045075 float=y inside=0
  colors=@default.map
  }

To use it :

  • Save file to fractint main directory.
  • Run fractint.
  • press 2 key
  • press F6 key
  • select par file ( default is usr/share/xfractint/pars/fractint.par )

One can :

  • save command to par file with b key
  • change from corners to center with F7 key
  • select par file with F6 key
  • load par file with ctrl-@

Reset causes Fractint to reset all calculation related parameters to their default values. Non-calculation parameters such as "printer=", "sound=", and "savename=" are not affected.[13] The reset=1730 in the parameter file shows that it was created with 17.3 version of Fractint.[14]

Search the code :

grep -R "par file"

result :

 miscres.c:   /* just to make par file look nicer */
 miscovl.c:               ranges which can be written as <nn> to compress .par file entry.
 printer.c:            /* user might change gammas with a .par file entry mid-run.     */

decomposition[edit | edit source]

Aproximation of field lines on the parameter plane ( exterioar of Mandelbrot set) by 256-decomposition[15]

Field              { ; Field lines, Jay R Hill, 1997
  reset=1960 type=mandel center-mag=-0.75/-1.12577e-013/0.8695652
  params=0/0 float=y maxiter=256 bailout=3600 decomp=256
  colors=000www<33>www000www<33>www000w\
  ww<9>www000www<23>www000www<32>www0\
  00www<22>www000www<9>www000www<34>\
  www000www<32>www000000
  savename=field
  }

See also:

Lists[edit | edit source]

code[edit | edit source]

Drawing Method[edit | edit source]

Description from Fractint Version 20.04

The "passes option" (<X> options screen or "passes=" parameter) selects one of

  • the single-pass
  • dual-pass
  • triple-pass
  • solid-guessing (default)
  • solid-guessing after pass n
  • boundary tracing
  • tesseral,
  • synchronous orbits
  • orbits modes


This option applies to most fractal types.

Single-pass mode ("1") draws the screen pixel by pixel. Dual-pass ("2") generates a half-resolution screen first as a preview using 2x2-pixel boxes, and then generates the rest of the dots with a second pass. Dual-pass uses no more time than single-pass. Triple-pass ("3") generates the coarse first pass of the solidguessing mode (see "g" below), then switches to either "1" (with low resolution video modes) or "2" (with higher resolution video modes). The advantage of '3' vs '2' is that when using high resolution modes, the first pass has a much lower resolution (about 160x120) and is therefore much quicker than the first pass of the passes=2 mode. However, with the '2' mode, the first pass does not represent wasted time. The '3' mode wastes the effort of generating the coarse first screen.

The single, dual, and triple pass modes all result in identical images. These modes are for those who desire the highest possible accuracy. Most people will want to use the guessing mode, described next.

Solid-guessing ("g") is the default. It performs from two to four visible passes - more in higher resolution video modes. Its first visible pass is actually two passes - one pixel per 4x4, 8x8, or 16x16 pixel box is generated, and the guessing logic is applied to fill in the blocks at the next level (2x2, 4x4, or 8x8). Subsequent passes fill in the display at the next finer resolution, skipping blocks which are surrounded by the same color. Solid-guessing can guess wrong, but it sure guesses quickly!

Solid-guessing stop after pass n ("g1" through "g6") are a variation on the guessing mode in which the algorithm stops after the nth pass. This facility is for exploring in low resolution when you'd rather see a low resolution image with large blocky pixels filling the whole screen than a small low resolution image such as you get with the <v> (View Windows) command. Note that on the <x> screen you can't directly type g1 or g2. Press g repeatedly until you get the option you want, or else use the left or right cursor keys.

Boundary Tracing ("b"), which only works accurately with fractal types (such as the Mandelbrot set, but not the Newton type) that do not contain "islands" of colors, finds a color boundary, traces it around the screen, and then "blits" in the color over the enclosed area.


Tesseral ("t") is a sort of "super-solid-guessing" option that successively divides the image into subsections and colors in rectangles that have a boundary of a solid color. It's actually slower than the solid-guessing algorithm, but it looks neat, so we left it in. This mode is also subject to errors when islands of color appear inside the rectangles.

Diffusion Scan ("d") is a drawing type based on dithering techniques. It scans the image spreading the points evenly and to each point it paints a square of the appropriate size so that the image will be incrementally enhanced. This method calculates ALL the points in the image being a good substitute for Single/Dual/Triple pass and presents a quick visualization even in the slowest fractals. With "fillcolor=0" (below) the squares are not painted and the points are spread over the image until all have being calculated (sort of a "Fade In").

The "fillcolor=" option in the <X> screen or on the command line sets a fixed color to be used by the Boundary Tracing and Tesseral calculations for filling in defined regions. The effect of this is to show off the boundaries of the areas delimited by these two methods.

Orbits ("o") draws an image by plotting the orbits of the escape time fractals. This technique uses the same coordinates to draw an image as the other passes options, sets "passes=1" and no symmetry, and then plots the orbits for each pixel. Zooming into a "passes=o" image is in fact zooming into the "passes=1" image, and the resulting image may not be what is expected. To find interesting places to investigate, press <O> after an image has completed and watch the behaviour of the orbits as the cursor is moved around the screen. See Orbits Window (p. 36).

The "outside=summ" option causes Orbits to increment a pixel's color number every time an orbit touchs it; the resulting display is a 2-d histogram. If "outside=" is some other value, then the "inside=" color determines the color of the plotted orbits. If "inside=0", then the color number is incremented at the start of each pixel of the passes=1 image.

The "orbitdelay=" option controls how many orbits are computed before the orbits are displayed on the screen. This allows the orbits to settle down. The "orbitinterval=" option causes Orbits to plot every nth orbit point. A non-zero value of the "periodicity=" option causes Orbits to not plot orbits that have reached the bailout conditions or where an orbit goes off the visible area of the image. A zero value of periodicity will plot all orbits except as modified by orbitdelay and orbitinterval.

Synchronous orbits ("s") is an experimental mode using the "fractal witchcraft" algorithm based on the Almondbread implementation by Michael Ganss. This algorithm optimizes deep zooms by calculating parallel orbits starting at different points, and subdividing when the orbits break formation. Michael's implementation had to be extensively modified to work with Fractint's DOS medium memory model environment.

Synchronous orbits (also known as SOI) has some limitations. SOI is loosely coupled with fractint and most options don't work with it. Only types mandel and julia are implemented. SOI is only useful for very deep zooms, but only up to the limit of double precision. Within this narrow magnification range, SOI can result in tremndous speedups. If you invoke fractint with "debug=3444" on the command line, a long double (rather than double) version will be used, which allows zooming about 1000 times deeper. SOI really needs to be ported to fractint's arbitary precision. This will likely happen only after Fractint is moved to a better programming environment.


algorithms[edit | edit source]

Escher like tilings of Julia sets[edit | edit source]

In Version 19.6 new features include: new fractal types {=HT_ESCHER escher_julia} and {=HT_VL volterra-lotka} courtesy Michael Sargent.

Escher-Like Julia Sets

(type=escher_julia)

These unique variations on the Julia set theme, presented in The Science of Fractal Images, challenge us to expand our pre-conceived notions of how fractals should be iterated. We start with a very basic Julia formula:

   z(n+1) = z(n)^2 + (0, 0i)

The standard algorithm would test each iterated point to see if it "escapes to infinity". If its size or "modulus" (its distance from the origin) exceeds a preselected Bailout Test (p. 100) value, it is outside the Julia set, and it is banished to the world of multicolored level sets which color-cycle spectacularly. But another way of describing an escaped point is to say that it is "attracted" to infinity. We make this decision by calculating whether the point falls within the "target set" of all points closer to infinity than the boundary created by the bailout value. In this way, the "disk around infinity" is conceptually no different from the disks around Finite Attractors (p. 188) such as those used for Newton fractals.

In the above formula, with c = (0, 0i), this standard algorithm yields a rather unexciting circle. But along comes Peitgen to tell us that "since T [the target set] can essentially be anything, this method has tremendous artistic potential. For example, T could be a so-called p- norm disk ... or a scaled filled-in Julia set or something designed by hand. This method opens a simple [beware when he uses words like that] and systematic approach to Escher-like tilings."

So, what we do is iterate the above formula, scale each iteration, and plug it into a second Julia formula. This formula has a value of c selected by the user. If the point converges to this non-circular target set:

   T = [ z: | (z * 15.0)^2 + c | < BAILOUT ]

we color it in proportion to the overall iteration count. If not, it will be attracted to infinity and can be colored with the usual outside coloring options. This formula uses a new Fractint programming feature which allows the use of a customized coloring option for the points which converge to the target Julia set, yet allows the other points to be handled by the standard fractal engine with all of its options.

With the proper palette and parameters for c, and using the Inversion (p. 94) option and a solid outside color from the Color Parameters p. 130), you can create a solar eclipse, with the corona composed of Julia-shaped flames radiating from the sun's surface.

If you question the relevance of these images to Escher, check out his Circle Limit series (especially III and IV). In his own words: "It is to be doubted whether there exist today many ... artists of any kind, to whom the desire has come to penetrate to the depths of infinity.... There is only one possible way of ... obtaining an "infinity" entirely enclosed within a logical boundary line.... The largest ... shapes are now found in the center and the limit of infinite number and infinite smallness is reached at the circumference.... Not one single component ever reaches the edge. For beyond that there is "absolute nothingness." And yet this round world cannot exist without the emptiness around it, not simply because "within" presupposes "without", but also because it is out there in the "nothingness" that the center points of the arcs that go to build up the framework are fixed with such geometric exactitude."

References:

  • Ernst, B. The Magic Mirror of M. C. Escher, Barnes & Noble, 1994, pp. 102-11.
  • Peitgen, H.-O. and Saupe, D. The Science of Fractal Images, Springer-Verlag, 1988; pp. 185, 187.


One can search the source code using:

 grep -nR "escher"

Results:

// help2.src
    Escher-like tiling of Julia sets from The Science of Fractal Images
      z(0) = pixel
      z(n+1) = z(n)^2 + (0, 0i)
    The target set is a second, scaled, Julia set:
      T = [ z: | (z * 15.0)^2 + c | < BAILOUT ]
    Two parameters: real and imaginary parts of c
    Iteration count and bailout size apply to both Julia sets.
// fractalp.c
   {
   "escher_julia",
      {realparm, imagparm, ES, ES},
      {0.32, 0.043, 0, 0},
      HT_ESCHER, HF_ESCHER, WINFRAC,
      (float)-1.6, (float)1.6, (float)-1.2, (float)1.2,
      0, NOFRACTAL, NOFRACTAL, NOFRACTAL, ORIGIN,
      EscherfpFractal, juliafp_per_pixel, StandardSetup, 
          StandardFractal,
      STDBAILOUT
   },


// fractal19.par
{ ; "Escher-Julia #1"                     t=  0:32:35.06
  ; t=calc time [h:mm:ss.] using 486DX2-66 at 1024x768
  ; (c) 1997 by Les St Clair 101461.2032@compuserve.com
  ; parameters created on Apr 13, 1997
  reset=1960 type=escher_julia passes=1
  center-mag=+0.42798355610118920/+0.29420988317529780/3.4153
  params=0.005/0.641 float=y bailout=100 inside=bof60 logmap=4
  decomp=256
  colors=000H51<39>ywezxfzxf<40>H51G40G40<40>ywezxfzxf<40>H51G40G40<40>ywe\
  zxfzxf<39>I62 cyclerange=0/255
  }

boundary trace[edit | edit source]

/*

fracint 

CALCFRAC.C contains the high level ("engine") code for calculating the
fractal images (well, SOMEBODY had to do it!).
Original author Tim Wegner, but just about ALL the authors have contributed
SOME code to this routine at one time or another, or contributed to one of
the many massive restructurings.
The following modules work very closely with CALCFRAC.C:
  FRACTALS.C    the fractal-specific code for escape-time fractals.
  FRACSUBR.C    assorted subroutines belonging mainly to calcfrac.
  CALCMAND.ASM  fast Mandelbrot/Julia integer implementation
Additional fractal-specific modules are also invoked from CALCFRAC:
  LORENZ.C      engine level and fractal specific code for attractors.
  JB.C          julibrot logic
  PARSER.C      formula fractals
  and more
 -------------------------------------------------------------------- */
 
 
/******************* boundary trace method ***************************
Fractint's original btm was written by David Guenther.  There were a few
rare circumstances in which the original btm would not trace or fill
correctly, even on Mandelbrot Sets.  The code below was adapted from
"Mandelbrot Sets by Wesley Loewer" (see calmanfp.asm) which was written
before I was introduced to Fractint.  It should be noted that without
David Guenther's implementation of a btm, I doubt that I would have been
able to implement my own code into Fractint.  There are several things in
the following code that are not original with me but came from David
Guenther's code.  I've noted these places with the initials DG.

                                        Wesley Loewer 3/8/92
*********************************************************************/



#define bkcolor 0  /* I have some ideas for the future with this. -Wes */
#define advance_match()     coming_from = ((going_to = (going_to - 1) & 0x03) - 1) & 0x03
#define advance_no_match()  going_to = (going_to + 1) & 0x03


/***** vars for new btm *****/
enum direction {North,East,South,West};
enum direction going_to;
int trail_row, trail_col;


static
int  bound_trace_main(void)
    {
    enum direction coming_from;
    unsigned int match_found, continue_loop;
    int trail_color, fillcolor_used, last_fillcolor_used = -1;
    int max_putline_length;
    int right, left, length;
    static FCODE btm_cantbeused[]={"Boundary tracing cannot be used with "};
    if (inside == 0 || outside == 0)
        {
        static FCODE inside_outside[] = {"inside=0 or outside=0"};
        char msg[MSGLEN];
        far_strcpy(msg,btm_cantbeused);
        far_strcat(msg,inside_outside);
        stopmsg(0,msg);
        return(-1);
        }
    if (colors < 16)
        {
        char msg[MSGLEN];
        static FCODE lessthansixteen[] = {"< 16 colors"};
        far_strcpy(msg,btm_cantbeused);
        far_strcat(msg,lessthansixteen);
        stopmsg(0,msg);
        return(-1);
        }

    got_status = 2;
    max_putline_length = 0; /* reset max_putline_length */
    for (currow = iystart; currow <= iystop; currow++)
        {
        reset_periodicity = 1; /* reset for a new row */
        color = bkcolor;
        for (curcol = ixstart; curcol <= ixstop; curcol++)
            {
            if (getcolor(curcol, currow) != bkcolor)
                continue;

            trail_color = color;
            row = currow;
            col = curcol;
            if ((*calctype)()== -1) /* color, row, col are global */
                {
                if (showdot != bkcolor) /* remove showdot pixel */
                   (*plot)(col,row,bkcolor);
                if (iystop != yystop)  /* DG */
                   iystop = yystop - (currow - yystart); /* allow for sym */
                add_worklist(xxstart,xxstop,curcol,currow,iystop,currow,0,worksym);
                return -1;
                }
            reset_periodicity = 0; /* normal periodicity checking */

            /*
            This next line may cause a few more pixels to be calculated,
            but at the savings of quite a bit of overhead
            */
            if (color != trail_color)  /* DG */
                continue;

            /* sweep clockwise to trace outline */
            trail_row = currow;
            trail_col = curcol;
            trail_color = color;
            fillcolor_used = fillcolor > 0 ? fillcolor : trail_color;
            coming_from = West;
            going_to = East;
            match_found = 0;
            continue_loop = TRUE;
            do
                {
                step_col_row();
                if (row >= currow
                        && col >= ixstart
                        && col <= ixstop
                        && row <= iystop)
                    {
                    /* the order of operations in this next line is critical */
                    if ((color = getcolor(col, row)) == bkcolor && (*calctype)()== -1)
                                /* color, row, col are global for (*calctype)() */
                        {
                        if (showdot != bkcolor) /* remove showdot pixel */
                           (*plot)(col,row,bkcolor);
                        if (iystop != yystop)  /* DG */
                           iystop = yystop - (currow - yystart); /* allow for sym */
                        add_worklist(xxstart,xxstop,curcol,currow,iystop,currow,0,worksym);
                        return -1;
                        }
                    else if (color == trail_color)
                        {
                        if (match_found < 4) /* to keep it from overflowing */
                                match_found++;
                        trail_row = row;
                        trail_col = col;
                        advance_match();
                        }
                    else
                        {
                        advance_no_match();
                        continue_loop = going_to != coming_from || match_found;
                        }
                    }
                else
                    {
                    advance_no_match();
                    continue_loop = going_to != coming_from || match_found;
                    }
                } while (continue_loop && (col != curcol || row != currow));

            if (match_found <= 3)  /* DG */
                { /* no hole */
                color = bkcolor;
                reset_periodicity = 1;
                continue;
                }

/*
Fill in region by looping around again, filling lines to the left
whenever going_to is South or West
*/
            trail_row = currow;
            trail_col = curcol;
            coming_from = West;
            going_to = East;
            do
                {
                match_found = FALSE;
                do
                    {
                    step_col_row();
                    if (row >= currow
                            && col >= ixstart
                            && col <= ixstop
                            && row <= iystop
                            && getcolor(col,row) == trail_color)
                              /* getcolor() must be last */
                        {
                        if (going_to == South
                                || (going_to == West && coming_from != East))
                            { /* fill a row, but only once */
                            right = col;
                            while (--right >= ixstart && (color = getcolor(right,row)) == trail_color)
                                ; /* do nothing */
                            if (color == bkcolor) /* check last color */
                                {
                                left = right;
                                while (getcolor(--left,row) == bkcolor)
                                      /* Should NOT be possible for left < ixstart */
                                    ; /* do nothing */
                                left++; /* one pixel too far */
                                if (right == left) /* only one hole */
                                    (*plot)(left,row,fillcolor_used);
                                else
                                    { /* fill the line to the left */
                                    length=right-left+1;
                                    if (fillcolor_used != last_fillcolor_used || length > max_putline_length)
                                        { /* only reset dstack if necessary */
                                        memset(dstack,fillcolor_used,length);
                                        last_fillcolor_used = fillcolor_used;
                                        max_putline_length = length;
                                        }
                                    sym_fill_line(row, left, right, dstack);
                                    }
                                } /* end of fill line */

#if 0 /* don't interrupt with a check_key() during fill */
                            if(--kbdcount<=0)
                                {
                                if(check_key())
                                    {
                                    if (iystop != yystop)
                                       iystop = yystop - (currow - yystart); /* allow for sym */
                                    add_worklist(xxstart,xxstop,curcol,currow,iystop,currow,0,worksym);
                                    return(-1);
                                    }
                                kbdcount=max_kbdcount;
                                }
#endif
                            }
                        trail_row = row;
                        trail_col = col;
                        advance_match();
                        match_found = TRUE;
                        }
                    else
                        advance_no_match();
                    } while (!match_found && going_to != coming_from);

                if (!match_found)
                    { /* next one has to be a match */
                    step_col_row();
                    trail_row = row;
                    trail_col = col;
                    advance_match();
                    }
                } while (trail_col != curcol || trail_row != currow);
            reset_periodicity = 1; /* reset after a trace/fill */
            color = bkcolor;
            }
        }
    return 0;
    }

/*******************************************************************/
/* take one step in the direction of going_to */
static void step_col_row()
    {
    switch (going_to)
        {
        case North:
            col = trail_col;
            row = trail_row - 1;
            break;
        case East:
            col = trail_col + 1;
            row = trail_row;
            break;
        case South:
            col = trail_col;
            row = trail_row + 1;
            break;
        case West:
            col = trail_col - 1;
            row = trail_row;
            break;
        }
    }

/******************* end of boundary trace method *******************/

Install[edit | edit source]

How does Fractint achieve its speed?[edit | edit source]

Answer from the sci.fractals FAQ[21], by Michael C. Taylor and Jean-Pierre Louvet with numerous contributions by others.

Fractint's speed (such as it is) is due to a combination of:

  • Reducing computation by Periodicity checking and guessing solid areas (especially the "lake" area).
  • Using hand-coded assembler in many places.
  • Using fixed point math rather than floating point where possible (huge improvement for non-coprocessor machine, small for 486's, moot for Pentium processors).
  • Exploiting symmetry of the fractal.
  • Detecting nearly repeating orbits, avoid useless iteration (e.g. repeatedly iterating 02+0 etc. etc.).
  • Obtaining both sin and cos from one 387 math coprocessor instruction.
  • Using good direct memory graphics writing in 256-color modes.

The first three are probably the most important. Some of these introduce errors, usually quite acceptable.


Help[edit | edit source]

References[edit | edit source]

  1. fractint Image Calculation Parameters
  2. Fractaal forum : FractInt > Mag
  3. Converting between FractInt and Fractal eXtreme palettes
  4. the KAM map by Fred Schimmel
  5. retrocomputing SE question: why-were-those-colors-chosen-to-be-the-default-palette-for-256-color-vga ?
  6. fountainware : vga color palettes
  7. A short Introducion to PAR Files by Laurent Chabin
  8. julian haight : filmer instructions
  9. Fractint doc index
  10. Fractint par files by Rupert Russell
  11. Video for FRACTINT by Chabin Laurent
  12. Fractint .par file page
  13. fractint Image Calculation Parameters
  14. [Fractint] FOTD 27-07-11 (Bad Moon on the Rise [No Rating])
  15. Rendering the Field Lines of the Mandelbrot Set by Richard A Thomson
  16. Fractint deep zoom
  17. Index of /spanky/pub/fractals/params
  18. nehee par collection
  19. fracton links
  20. Fractint .par file page by Hopy
  21. faqs.org : sci/fractals-faq