/**************************************************************
 *                                                            *
 *           Order From Chaos: A Fractal Sampler              *
 *                                                            *
 *          Written by Eric Giguere for AMIGA Plus            *
 *                                                            *
 *------------------------------------------------------------*
 *                                                            *
 * File: mandelbrot.c                                         *
 *                                                            *
 * Displays the Mandelbrot Set as computed by the Level Set   *
 * Method from the algorithms on page 188 of The Science of   *
 * Fractal Images.                                            *
 *                                                            *
 * This one takes a while and is heavily CPU-bound.  If you   *
 * have a high-speed floating-point library or a co-processor *
 * chip, use it!  Manx 3.6a users might want to try the +ff   *
 * option when they compile.                                  *
 *                                                            *
 * Compile and link with `fractal.o'.                         *
 *                                                            *
 **************************************************************/

#include <stdio.h>
#include <math.h>
#include "exec/types.h"
#include "intuition/intuition.h"

/*
 * Define the boundaries of the set -- change these to zoom
 * in on a particular area
 */

#define XMIN (-1.95)
#define XMAX ( 1.0)
#define YMIN (-1.4)
#define YMAX ( 1.6)
#define DEPTH    4     /*Screen Depth  */
#define XLENGTH  640   /*320 for LORES */
#define YLENGTH  400   /*200 for non-interlace */


/*
 * From fractal.c
 */

extern struct Window *FWindow;

extern int            Done();
extern void           DrawPoint();

/*
 * Set the window title
 */

char *FTitle = "Mandelbrot Set";

/*
 * Calculate the `level' (i.e., colour) of a
 * particular point
 */

long MSetLevel( cx, cy, maxiter )
  double cx, cy;
  long   maxiter;
  {
    register long   iter;
    register double x, y, x2, y2;
    register double temp;

    x = y = x2 = y2 = 0.0;

    iter = 0L;

    while( iter < maxiter && ( x2 + y2 ) < 10000.0 )
      {
        temp = x2 - y2 + cx;
        y *= 2.0 * x;
        y += cy;
        x = temp;
        x2 = x * x;
        y2 = y * y;
        ++iter;
      }

    return( iter );
  }

/*
 * Display the Mandelbrot Set
 */

void RunFractals()
  {
    register long   ix, iy;
    register double cx, cy;

    for( iy = 0L; iy < YLENGTH; ++iy )
      {
        cy = YMIN + iy * ( ( YMAX - YMIN ) / (YLENGTH-1.0) );

        for( ix = 0L; ix < XLENGTH; ++ix )
          {
            cx = XMIN + ix * ( ( XMAX - XMIN ) / (XLENGTH-1.0) );
            DrawPoint( ( MSetLevel( cx, cy, ((1L<<DEPTH)-1L)) + 1L ) % (1L<<DEPTH), ix, iy );

            if( Done() )
                return;
          }

        if( Done() )
            return;
      }


    /*
     * Use WaitPort to avoid busy-wait loops
     */

    while( !Done() )
        WaitPort( FWindow->UserPort );
  }


