#include <stdio.h>
#include <math.h>
#include <stdlib.h>
/*
v1.1 29 December 2007
This program outputs a pretty fractal image in julia.ppm
Compile with: cc -o juliac julia.c -lm
Then run with simply: juliac 
or:                   juliac 500 500 
or:                   juliac 500 500 100 200
juliac will accept up to six arguments from the command line, 
see below.  The command line interface for this program is very clumsy.
For example,  to change the sixth argument (ci) without changing
the others, you will need to type in the first five default
values before changing only the sixth.

Here is what the program does.  For every (x,y) point within
a rectangular grid, the point is treated as complex number z.
The following very simple equation is interated for up to
itermax times:
z=z^2 +c
Depending on whether that iteration converges or diverges,
a color is assigned to the (x,y) point.  By diverge ("breakout"), it is
meant that |z|^2 becomes greater than the number breakout
with itermax iterations.
*/
main(int argc, char *argv[])
{
  int hxres = 600;    /* horizontal resolution */ 
  int hyres = 400;    /* vertical resolution */  
  double magnify=10;    /* 10 is standard magnification */  
  int itermax = 100;    /* maximum iters to do*/ 
  double breakout=64.;  /* |z|^2 greater than this is a breakout */ 
  double cr=-.7492; /*real part of c in z=z^2 +c */  
  double ci=.1; /*imaginary part of c in z=z^2 +c */ 
  double x0=.09950; /*center of picture */
  double y0=-.00062;/*center of picture */
  double x,xx,y,xl,yl,zsq,zm,rb;
  int iter,hx,hy;
  int red,green,blue;
  FILE *ofp;

  rb=sqrt(breakout);
  ofp=fopen("fromc.ppm","wb"); /*b means binary, for possible MS Windows compilation*/
  /* next six lines get up to six numbers from the command line, assigning them
     to hxres, hyres, magnify, itermax, cr, ci, x0 and y0 */
  if (argc>1) sscanf(argv[1],"%d",&hxres); 
  if (argc>2) sscanf(argv[2],"%d",&hyres); 
  if (argc>3) sscanf(argv[3],"%lf",&magnify); 
  if (argc>4) sscanf(argv[4],"%d",&itermax); 
  if (argc>5) sscanf(argv[5],"%lf",&cr); 
  if (argc>6) sscanf(argv[6],"%lf",&ci); 
  if (argc>7) sscanf(argv[7],"%lf",&x0); 
  if (argc>8) sscanf(argv[8],"%lf",&y0); 
  if (argc>9) sscanf(argv[9],"%lf",&breakout); 
  /* write header for PPM output: */
  fprintf(ofp,"P6\n# magnify=%lf itermax=%d\n",magnify,itermax);
  fprintf(ofp,"%d %d\n255\n",hxres,hyres);

  for (hy=1;hy<=hyres;hy++)  {
    for (hx=1;hx<=hxres;hx++)  {
      y = (4.*hyres/hxres)*((hyres+1-hy-.5)/hyres-0.5)/magnify+y0;
      x = 4.*((hx-.5)/hxres-0.5)/magnify+x0;
      zm=0;
      for (iter=1;iter<itermax;iter++)  {
        xl=x;
        yl=y;
        xx = x*x-y*y+cr;
        y = 2.0*x*y+ci;
        x = xx;
        zsq=x*x+y*y;
        if (zsq > zm) zm=zsq;
        if (zsq>breakout) break;
      }
      if (iter>=itermax){  /*if no "breakout" occured, color by maximum |z|^2 achieved*/
        red=0;
        green=255.*zm/breakout;
        blue=255.*zm/breakout;
      }
      else{  /*else color using the last x and y before "breakout" occured*/
        red=255*(rb+xl)/(2*rb);
        green=0;
        blue=.5*255*(rb+yl)/(2*rb);
      }
      /* write out the color triplet in binary ppm format, one byte per integer*/  
      fputc((char)red,ofp);
      fputc((char)green,ofp);
      fputc((char)blue,ofp);
    }
  }
  fclose(ofp);
  printf(" wrote %d by %d ppm file: %s \n", hxres,hyres,"fromc.ppm");
 // system("display julia.ppm");
}
