/* Apfelmännchen, Ausgabe als PGM-File (2 oder 5) */
/* (C) 1996 Rene' Scholz <mrz@informatik.uni-jena.de> */
/* compile: gcc -O6 -s -o Apfel Apfel.c -lm */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
float m, xmin=-2.5,ymin=-1.5,xmax=1.5,ymax=1.5; /* Grenzen des Bildausschnittes/Fractals */
int DEBUG=0;
int LOG=0;
int P2=0;
int P5=1;
int ScreenMaxX=1024, ScreenMaxY=768;
int MaxIter=150; // max. Anzahl der Iterationen --> auch Anzahl der Farben, def: 150
int mandel(register float Cx,register float Cy)
// Berechnet zum Punkt C=(Cx,Cy) aus Z den Farbwert des Fractals
// Z_n+1=(Z_n)²+C Z_0=(0,0)
{
const BLAU=1;
register int i;
register float x=0,y=0,x_old=0;
for(i=1;i<MaxIter;i++)
{ x=x*x-y*y +Cx;
y=2*x_old*y +Cy;
x_old=x;
if (x*x+y*y >4)
if (LOG==1) { return(m*log(i+1)+1.0); }
else { return(i); }
}
return(BLAU);
}
void show_options()
{
printf("Optionen:\n\n");
printf("\t -help Anzeige dieser Hilfe\n");
printf("\t -xmin <Zahl> linke Begrenzung (-4 < xmin < 4) \n");
printf("\t -ymin <Zahl> untere Begrenzung (-4 < ymin < 4) \n");
printf("\t -xmax <Zahl> rechte Begrenzung (-4 < xmax < 4) \n");
printf("\t -ymax <Zahl> obere Begrenzung (-4 < xmax < 4) \n");
printf("\t -iter <1..255> max. Iterationen <Default=150>\n");
printf("\t -log Palette logarithmisch <Default=normale Palette>\n");
printf("\t -size XxY Bildgröße <Default=1024x768>\n");
printf("\t -P5 Ausgabe als Bildtyp PGM5 auf stdout <Default>\n");
printf("\t -P2 Ausgabe als Bildtyp PGM2 auf stdout \n");
printf("\t -debug Anzeige von Debugging-Informationen \n");
}
void show_help()
{
system("clear");
printf("\n\t\t\t Ausgabe eines Apfelmännchens als PGM-file \n\n\n");
show_options();
}
void scan_options(int argc, char *argv[])
{
int i,t,i1,i2;
double f,f1,f2;
char *s,*s1,*s2;
for (i=1; i<argc; i++)
{
if (!strcmp ("-help", argv[i]) || !strcmp ("-h", argv[i]) )
{ show_help(); exit(0); }
if (!strcmp ("-debug", argv[i]) ) { DEBUG=1; continue; }
if (!strcmp ("-log", argv[i]) ) { LOG=1; continue; }
if (!strcmp ("-P2", argv[i]) ) { P2=1; P5=0; continue; }
if (!strcmp ("-P5", argv[i]) ) { P5=1; P2=0; continue; }
if (!strcmp ("-size", argv[i]))
{
if (++i<argc)
{
s=argv[i];
i1=atoi(strtok(s,"x")); i2=atoi(strtok(NULL,"x"));
if ((i1>0) && (i1<=2048)) { ScreenMaxX=i1; }
else {
printf("\nFehler: ScreenMaxX nicht zwischen 1 und 2048!\n");
show_options(); exit(-1);
}
if ((i2>0) && (i1<=2048)) { ScreenMaxY=i2; }
else {
printf("\nFehler: ScreenMaxY nicht zwischen 1 und 2048!\n");
show_options(); exit(-1);
}
}
else { printf("\nBildgröße fehlt !\n"); show_options(); exit(0); }
continue;
}
if (!strcmp ("-iter", argv[i]))
{
if (++i<argc)
{
t=atoi(argv[i]);
if ((1<=t) && (t<=255)) { MaxIter=t; }
else {
printf("\nFehler: Anzahl der Iterationen nicht zwischen 1 und 255 !\n");
show_options(); exit(-1);
}
}
else { printf("\nIterationsanzahl fehlt !\n"); show_options(); exit(0); }
continue;
}
if (!strcmp ("-xmin", argv[i]))
{
if (++i<argc)
{
f=atof(argv[i]);
if ((f<4) && (f>-4)) { xmin=f; }
else { printf("\nFehler: xmin nicht zwischen -4 und 4 !\n");
show_options(); exit(-1);
}
}
else { printf("\nParameter fehlt !\n"); show_options(); exit(-1); }
continue;
}
if (!strcmp ("-ymin", argv[i]))
{
if (++i<argc)
{
f=atof(argv[i]);
if ((f<4) && (f>-4)) { ymin=f; }
else { printf("\nFehler: ymin nicht zwischen -4 und 4 !\n");
show_options(); exit(-1);
}
}
else { printf("\nParameter fehlt !\n"); show_options(); exit(-1); }
continue;
}
if (!strcmp ("-xmax", argv[i]))
{
if (++i<argc)
{
f=atof(argv[i]);
if ((f<4) && (f>-4)) { xmax=f; }
else { printf("\nFehler: xmax nicht zwischen -4 und 4 !\n");
show_options(); exit(-1);
}
}
else { printf("\nParameter fehlt !\n"); show_options(); exit(-1); }
continue;
}
if (!strcmp ("-ymax", argv[i]))
{
if (++i<argc)
{
f=atof(argv[i]);
if ((f<4) && (f>-4)) { ymax=f; }
else { printf("\nFehler: ymax nicht zwischen -4 und 4 !\n");
show_options();
exit(-1);
}
}
else { printf("\nParameter fehlt !\n"); show_options(); exit(-1); }
continue;
}
printf("\nFalsche Option !\n"); show_options(); exit(-1);
}
}
void show_debugging_infos()
{
fprintf(stderr,"\n\t\t Anzeige von Debugging-Informationen \n\n");
fprintf(stderr,"\txmin = %f \n",xmin);
fprintf(stderr,"\tymin = %f \n",ymin);
fprintf(stderr,"\txmax = %f \n",xmax);
fprintf(stderr,"\tymax = %f \n",ymax);
fprintf(stderr,"\tScreenMaxX = %i \n",ScreenMaxX);
fprintf(stderr,"\tScreenMaxY = %i \n",ScreenMaxY);
fprintf(stderr,"\tMaxIter = %i \n",MaxIter);
fprintf(stderr,"\tm = %f \n",m);
}
void print_pgm_header(int x,int y,char *pgm_type,int colors,char *name)
{
printf("%s\n# created by %s\n# written by René Scholz <mrz@informatik.uni-jena.de>\n",pgm_type,name);
printf("%d %d\n%d\n",x,y,colors);
}
void main(int argc, char *argv[])
{
int x, y;
float a,b; /* C=(a,b) wird an mandel() übergeben */
float StepX,StepY;
scan_options(argc,argv);
if (LOG==1) m=256.0/log((float)MaxIter);
StepX=(xmax-xmin)/(ScreenMaxX-1);
StepY=(ymax-ymin)/(ScreenMaxY-1);
a=xmin; b=ymax;
if (P5==1) { print_pgm_header(ScreenMaxX,ScreenMaxY,"P5",255,argv[0]); }
else { print_pgm_header(ScreenMaxX,ScreenMaxY,"P2",255,argv[0]); }
for (y=1; y<=ScreenMaxY; y++) // Reihenfolge vertauscht, wegen Aufbau pgm-File
{
for (x=1; x<=ScreenMaxX; x++)
{
if (P5==1) { printf("%c",(char)mandel(a,b)); } // pgm-5
else { printf("%d ",mandel(a,b)); } // pgm-2
a+=StepX;
}
if (P2==1) printf("\n"); // pgm-2, besser lesbar
a=xmin;
b-=StepY;
}
if (DEBUG==1) show_debugging_infos();
exit(0);
}