/* * MandelVroom 2.0 * * (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA * * All rights reserved. * * Permission is hereby granted to distribute this program's source * executable, and documentation for non-comercial purposes, so long as the * copyright notices are not removed from the sources, executable or * documentation. This program may not be distributed for a profit without * the express written consent of the author Kevin L. Clague. * * This program is not in the public domain. * * Fred Fish is expressly granted permission to distribute this program's * source and executable as part of the "Fred Fish freely redistributable * Amiga software library." * * Permission is expressly granted for this program and it's source to be * distributed as part of the Amicus Amiga software disks, and the * First Amiga User Group's Hot Mix disks. * * contents: this file contains the Mandelbrot and Julia picture generators * in IEEE floating point format. */ #include "mandp.h" #include "parms.h" extern SHORT MaxOrbit; extern char *IEEELib; /* * IEEE Floating Point Mandelbrot Generator */ int MandelbrotIEEE( Pict ) register struct Picture *Pict; { register int i, j, k; register SHORT *CountPtr; register int MathMode; struct PotentialParms Parms; struct RastPort *Rp; struct MathIeeeDoubBasBase *LocalMathBase; LocalMathBase = (struct MathIeeeDoubBasBase *) OpenLibrary( IEEELib, 0L ); if (LocalMathBase == NULL) return; MathMode = Pict->MathMode; if (Pict->Flags & NO_RAM_GENERATE) CountPtr = Pict->Counts; else CountPtr = Pict->Counts + (Pict->CurLine*Pict->CountX); Parms.ScreenReal = Pict->Real; Parms.ScreenImag = Pict->Imag; /* start in the upper left hand corner */ Parms.C_Imag = Pict->ImagLow; Parms.C_Imag += Pict->CurLine*Pict->ImagGap; Parms.MaxIteration = Pict->MaxIteration; /* * for each pixel, calculate mandelbrot */ for (i = Pict->CurLine; i < Pict->CountY; i++) { Parms.C_Real = Pict->RealLow; if ( Pict->Flags & NO_RAM_GENERATE ) CountPtr = Pict->Counts; for (j = 0; j < Pict->CountX; j++) { if (*CountPtr == 0) { if (MathMode == 4) { k = Height_68881( &Parms ); } else { k = IEEE_Height( &Parms ); } *CountPtr = k; } CountPtr++; Parms.C_Real += Pict->RealGap; ChildPause( Pict ); } Parms.C_Imag += Pict->ImagGap; CheckEOL( Pict ); } CloseLibrary( LocalMathBase ); } /* MandelbrotIEEE */ /* * IEEE Floating Point Juliaelbrot Generator */ JuliaIEEE( Pict ) register struct Picture *Pict; { register int i, j, k; register SHORT *CountPtr; struct PotentialParms Parms; struct MathIeeeDoubBasBase *LocalMathBase; LocalMathBase = (struct MathIeeeDoubBasBase *) OpenLibrary( IEEELib, 0L ); if (Pict->Flags & NO_RAM_GENERATE) CountPtr = Pict->Counts; else CountPtr = Pict->Counts + (Pict->CurLine*Pict->CountX); Parms.C_Real = Pict->Real; Parms.C_Imag = Pict->Imag; Parms.C_Imag += Pict->CurLine*Pict->ImagGap; /* start in the upper left hand corner */ Parms.ScreenImag = Pict->ImagLow; Parms.MaxIteration = Pict->MaxIteration; /* * for each pixel, calculate mandelbrot */ for (i = Pict->CurLine; i < Pict->CountY; i++) { Parms.ScreenReal = Pict->RealLow; if ( Pict->Flags & NO_RAM_GENERATE ) CountPtr = Pict->Counts; for (j = 0; j < Pict->CountX; j++) { if (*CountPtr == 0) { if (Pict->MathMode == 2) { k = IEEE_Height( &Parms ); } else { k = Height_68881( &Parms ); } *CountPtr = k; } CountPtr++; Parms.ScreenReal += Pict->RealGap; ChildPause( Pict ); } Parms.ScreenImag += Pict->ImagGap; CheckEOL( Pict ); } CloseLibrary( LocalMathBase ); } /* JuliaIEEE */ IEEE_Height( Parms ) register struct PotentialParms *Parms; { register double cura, curb; double cura2, curb2; int k; #ifdef CHECK_TASK_STACK CheckStack(); #endif cura = cura2 = Parms->ScreenReal; curb = curb2 = Parms->ScreenImag; cura2 *= cura2; curb2 *= curb2; for (k = 0; k < Parms->MaxIteration; k++ ) { curb *= cura; curb += curb + Parms->C_Imag; cura = cura2 - curb2 + Parms->C_Real; cura2 = cura * cura; curb2 = curb * curb; if (cura2+curb2 >= 16.0) return( k ); } return( k ); } DrawOrbitIEEE( Pict ) register struct Picture *Pict; { register struct RastPort *Rp; register double cura, curb; double cura2, curb2; double realc, imagc; register int k; double x_scale, y_scale; int x_center, y_center; int width, height; int x, y; struct Window *Window; Window = OrbitWind; Rp = Window->RPort; width = (Window->Width-Pict->LeftMarg-Pict->RightMarg); height = (Window->Height-Pict->TopMarg-Pict->BotMarg); x_center = width/2 + Pict->LeftMarg; y_center = height/2 + Pict->TopMarg; y_scale = x_scale = (float) height / 2.0; /*x_scale *= AspectRatio( Pict );*/ realc = Pict->RealLow + (float) (MouseX-Pict->LeftMarg) * Pict->RealGap; imagc = Pict->ImagLow + (float) (MouseY-Pict->TopMarg) * Pict->ImagGap; if ( Pict->pNode.ln_Type == MANDPICT ) { cura = cura2 = Pict->Real; curb = curb2 = Pict->Imag; } else { cura = cura2 = realc; curb = curb2 = imagc; realc = Pict->Real; imagc = Pict->Imag; } cura2 *= cura2; curb2 *= curb2; SetAPen( Rp, 0 ); RectFill( Rp, Pict->LeftMarg, Pict->TopMarg, width+Pict->LeftMarg-1, height+Pict->TopMarg-1); SetAPen( Rp, HIGHLIGHTPEN); for (k = 0; k < MaxOrbit; k++ ) { curb *= cura; curb += curb + imagc; cura = cura2 - curb2 + realc; cura2 = cura * cura; curb2 = curb * curb; if (cura2+curb2 >= 16.0) return( k ); /* map real and imaginary parts into window coordinates */ x = x_center + (int)(x_scale*cura); y = y_center + (int)(y_scale*curb); if ( x >= Pict->LeftMarg && x < Window->Width-Pict->RightMarg && y >= Pict->TopMarg && y < Window->Height-Pict->BotMarg ) { /* plot pixel location */ WritePixel( Rp, x, y); } } return( k ); }