/* 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); }