Metropoli BBS
VIEWER: msetjset.c MODE: TEXT (ASCII)
/* ***********************************************************************
   *									 *
   *	   Walk on the Mandlebrot Set - Display the Julia Set		 *
   *									 *
   *									 *
   *			       Program by				 *
   *			 Christopher D. Watkins				 *
   *									 *
   *			     'C' conversion				 *
   *				  by					 *
   *			      Larry Sharp				 *
   *									 *
   ***********************************************************************
*/

#include "stdio.h"
#include "stdlib.h"
#include "dos.h"
#include "conio.h"
#include "math.h"
#include "mem.h"
#include "math.inc"
#include "graph.inc"

#define XMin    -2.20
#define XMax     0.60
#define YMin    -1.20
#define YMax     1.20
#define MaxIter  30.0
#define Res      160.0

char source[160];
int srcoff,srcseg;

int Iterate(float cx, float cy)
{
  int   Iters;
  float x, y;
  float x2, y2;
  float temp;

  x=cx;
  x2=SqrFP(x);
  y=cy;
  y2=SqrFP(y);
  Iters=0;
  while((Iters<MaxIter) && (x2+y2<4))
  {
    temp=cx+x2-y2;
    y=cy+2*x*y;
    y2=SqrFP(y);
    x=temp;
    x2=SqrFP(x);
    ++Iters;
  }
  return(Iters);
}

void Pix(int x, int y, int col)
{
  int a;

  Plot(x, y, col);
  Plot(x, Res-y-1, col);
}

void CalcMSet()
{
  int   ix, iy;
  int   Iters;
  float cx, cy;
  float dx, dy;
  int   L1, L2;

  Draw(0, 0, Res-1, 0, 35);
  Draw(Res-1, 0, Res-1, Res-1, 35);
  Draw(Res-1, Res, 0, Res, 35);
  Draw(0, Res, 0, 0, 35);
  Draw(Res, 0, 2*Res-1, 0, 35);
  Draw(2*Res-1, 0, 2*Res-1, Res-1, 35);
  Draw(2*Res-1, Res, Res, Res, 35);
  L1=(MaxIter-(MaxIter*2)/3);
  L2=(MaxIter-(MaxIter*5)/6);
  dx=(XMax-XMin)/(Res-1);
  dy=(YMax-YMin)/(Res-1);
  for(iy=2; iy<=((Res-1)/2); iy++)
  {
    cy=YMin+iy*dy;
    for(ix=2; ix<=Res-3; ix++)
    {
      cx=XMin+ix*dx;
      Iters=Iterate(cx, cy);
      if(Iters==MaxIter)
	Pix(ix, iy, 143);
      else
      {
	if(Iters>L1)
	  Pix(ix, iy, 215);
	else
	{
	  if(Iters>L2)
	    Pix(ix, iy, 35);
	}
      }
    }
  }
}

void CalcJSet(float cx, float cy)
{
  int   xp, yp;
  float dx, dy;
  float r;
  float Theta;
  float x, y;

  x=0;
  y=0;
  do
  {
    dx=x-cx;
    dy=y-cy;
    if(dx>0)
      Theta=atan(dy/dx)*0.5;
    else
    {
      if(dx<0)
	Theta=(Pi+atan(dy/dx))*0.5;
      else
	Theta=Pi*0.25;
    }
    r=sqrt(sqrt(SqrFP(dx)+SqrFP(dy)));
    if(random(100)<50)
      r=-r;
    x=r*cos(Theta);
    y=r*sin(Theta);
    xp=Res/2+Round(x*36)+Res;
    yp=Res/2+Round(y*36);
    Plot(xp, yp, 143);
  }
  while(!(kbhit()));
}

Byte ColrArray[10];
Byte xx;

void InitCursor()
{
  for(xx=1; xx<=9; xx++)
    ColrArray[xx]=0;
}

void PutCursor(int x, int y, int ox, int oy)
{
  for(xx=1; xx<=5; xx++)
    Plot(ox+xx-3, oy, ColrArray[xx]);
  for(xx=6; xx<=7; xx++)
    Plot(ox, oy+xx-8, ColrArray[xx]);
  for(xx=8; xx<=9; xx++)
    Plot(ox, oy+xx-7, ColrArray[xx]);
  for(xx=1; xx<=5; xx++)
    ColrArray[xx]=GetPixel(x+xx-3, y);
  for(xx=6; xx<=7; xx++)
    ColrArray[xx]=GetPixel(x, y+xx-8);
  for(xx=8; xx<=9; xx++)
    ColrArray[xx]=GetPixel(x, y+xx-7);
  Draw(x-2, y, x+2, y, 71);
  Draw(x, y-2, x, y+2, 71);
}

void BlockClearHalfScreen()
{
  unsigned int t, i, Offset;
  char far *address;

  for(t=1; t<=Res-1; t++)
  {
      Offset=(t*320)+Res;
	  movedata(srcseg,srcoff,0xA000,Offset, Res-3);
  }
}

float cx, cy;

void ViewStats()
{
  ungetch(32);
  ExitGraphics();
  Title();
  printf("Mandlebrot Set :\n\n");
  printf("   XMin = %f\n",XMin);
  printf("   XMax = %f\n",XMax);
  printf("   YMin = %f\n",YMin);
  printf("   YMax = %f\n\n",YMax);
  printf("Julia Set :\n\n");
  printf("   cx = %f\n",cx);
  printf("   cy = %f\n",cy);
  while(!(kbhit()));
  InitGraphics();
  CalcMSet();
}

void CheckCursor(int *X, int *Y)
{
  if(*X<1)
    *X=1;
  if(*X>158)
    *X=158;
  if(*Y<1)
    *Y=1;
  if(*Y>159)
    *Y=159;
}

void WalkAbout()
{
  int   oCursX, oCursY;
  int   CursX, CursY;
  char  Dir;
  float dx, dy;

  dx=(XMax-XMin)/(Res-1);
  dy=(YMax-YMin)/(Res-1);
  oCursX=3;
  oCursY=3;
  CursX=oCursX;
  CursY=oCursY;
  PutCursor(CursX, CursY, oCursX, oCursY);
  do
  {
    Dir=getch();
    switch(Dir)
    {
      case ' ': ViewStats(); break;
      case 'K': CursX-=1; break;
      case 'M': CursX+=1; break;
      case 'H': CursY-=1; break;
      case 'P': CursY+=1; break;
      case 'G': CursX-=1; CursY-=1; break;
      case 'I': CursX+=1; CursY-=1; break;
      case 'O': CursX-=1; CursY+=1; break;
      case 'Q': CursX+=1; CursY+=1; break;
    }
    if(Dir!=27)
    {
      CheckCursor(&CursX, &CursY);
      PutCursor(CursX, CursY, oCursX, oCursY);
      oCursX=CursX;
      oCursY=CursY;
      cx=XMin+dx*CursX;
      cy=YMin+dy*CursY;
      BlockClearHalfScreen();
      CalcJSet(cx, cy);
    }
  }
  while(Dir!=27);
}

void main()
{
  int i;
  struct SREGS segregs;

  segread(&segregs);
  srcseg = segregs.ds;
  srcoff = (int) source;

  for (i=0; i<Res; i++)
	  source[i] = 0;

  InitGraphics();
  InitCursor();
  CalcMSet();
  WalkAbout();
  ungetch(32);
  ExitGraphics();
}

[ RETURN TO DIRECTORY ]