|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 7628 (0x1dcc) Types: TextFile Names: »mandisp.c«
└─⟦87ddcff64⟧ Bits:30001253 CPHDIST85 Tape, 1985 Autumn Conference Copenhagen └─⟦this⟧ »cph85dist/mandelbrot/mandisp.c«
/* * Display Mandelbrot set pixels. (Gidis format) * * This version uses the Gidis display protocol (for DEC PRO/350) * It should be "fairly" easy to adapt it for other displays. */ #include <stdio.h> #include <ctype.h> #ifdef vms #include errno #define IO_ERROR errno #endif #define FALSE 0 #define TRUE 1 #define EOS '\0' #ifdef decus int $$narg = 1; /* Don't prompt for commands */ #define R_BIN_MODE "rn" /* Read binary file in Decus C */ #else #define R_BIN_MODE "r" #endif #define MAX_NITER 1000 /* Max. number of iterations */ #define MAX_NPIXEL 400 #define DEF_FILENAME "mandel" /* * Screen coordinates (set by mangidis.c, manregis.c) */ extern int max_npixel; extern int smaxx; extern int smaxy; extern int xorigin; extern int yorigin; extern int gray_scale; extern int tick; extern int cxsize; extern int cysize; /* * These values are read from the .his file */ int niter; /* Number of iterations */ int npixel; /* Number of pixels/side */ double orig_real; double orig_imag; double side; int pixel[MAX_NPIXEL]; /* Holds one row */ int factor; /* Scan lines per pixel */ double hist[MAX_NITER]; /* Pixel density histogram */ int density[MAX_NITER]; /* Initialization fills this in */ double hist_sum; /* Sum of histogram values */ char line[81]; char filename[81]; extern double atof(); extern char *strchr(); FILE *pixfd; FILE *hisfd; \f main(argc, argv) int argc; char *argv[]; { register int i; /* show_gray(); -- no longer needed */ if (argc <= 1) { while (interactive()) { doit(); } } else { for (i = 1; i < argc; i++) { strcpy(filename, argv[i]); doit(); } } dsp_finis(); scr_clear(); } doit() { if (setup()) { dsp_init(); boarder(); process(); finish(); } } \f process() { register int i, j; int value; int new_density, old_density; int oldx, newx; set_gray_scale(); factor = max_npixel / npixel; /* Scan lines/pixel */ for (i = 0; i < npixel; i++) { j = fread(pixel, npixel * sizeof (pixel[0]), 1, pixfd); if (feof(pixfd)) { perror("pixel file"); dsp_done(); scr_move(5, 1); printf("read error at scan row %d, expected %d, read %d\n", i, npixel, j); sleep(2); return; } /* * Position to Left edge of this scan line */ dsp_move(xorigin, yorigin - (i * factor)); old_density = -1; oldx = xorigin;; for (j = 0; j < npixel; j++) { value = pixel[j]; new_density = density[value]; if (new_density != old_density) { newx = xorigin + (j * factor); /* * If the luminance has just changed, * write the vector from "old" to "new" */ if (old_density >= 0) { dsp_draw(old_density, newx - oldx); } old_density = new_density; oldx = newx; } } /* * Write the last vector and reset display. */ dsp_draw(old_density, xorigin + ((npixel - 1) * factor) - oldx); dsp_endline(); } stall(); } \f show_gray() /* * Used to debug the gray scale, this routine prints each gray scale * value in turn. */ { register int i; register int j; register int y; int lines_per_gray; y = yorigin; lines_per_gray = max_npixel / gray_scale; scr_clear(); dsp_init(); for (i = 0; i < gray_scale; i++) { sprintf(line, "%2d", i); dsp_text(xorigin - (cxsize * 3), y - cysize, line); for (j = 0; j < lines_per_gray; j++, y--) { dsp_move(xorigin, y); dsp_draw(i, max_npixel); dsp_endline(); } y -= 2; /* Spacing */ } stall(); } \f /* * This is crude and should be replaced by something suitable to * your (hopefully) color display. */ static int gray_select[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; #define NGRAY (sizeof gray_select / sizeof (gray_select[0])) set_gray_scale() /* * Take the density histogram and turn it into a gray scale. * (should this be interactive or make better use of the * histogram prepared by mancomp?) */ { register int i; for (i = niter; i >= 0; --i) { density[i] = gray_select[i % NGRAY]; } } \f boarder() /* * Draw a pretty boarder */ { register int i; int xleft, xright, ytop, ybottom; int tick_gap; int do_value; double temp; double offset; double gap; xleft = xorigin - 2; xright = xorigin + max_npixel + 2; ytop = yorigin - max_npixel - 2; ybottom = yorigin + 2; tick_gap = max_npixel / 10; gap = side / ((double) max_npixel); dsp_draw(gray_scale - 1, 0); /* White line */ dsp_line(xleft, ytop, xright, ytop); dsp_line(xright, ytop, xright, ybottom); dsp_line(xright, ybottom, xleft, ybottom); dsp_line(xleft, ybottom, xleft, ytop); do_value = TRUE; offset = 0.0; for (i = xorigin; i < xright; i += tick_gap) { dsp_line(i, ybottom, i, ybottom + tick); dsp_line(i, ytop, i, ytop - tick); if (do_value) { temp = orig_real + (offset * gap); sprintf(line, "%7.4f", temp); dsp_text(i - (3 * cxsize), ybottom + (tick * 2), line); } do_value = !do_value; offset += ((double) tick_gap); } do_value = TRUE; offset = 0.0; for (i = yorigin; i > ytop; i -= tick_gap) { dsp_line(xleft, i, xleft - tick, i); dsp_line(xright, i, xright + tick, i); if (do_value) { temp = orig_imag + (offset * gap); sprintf(line, "%7.4f", temp); dsp_text(xleft - (10 * cxsize), i - (cysize / 2), line); } do_value = !do_value; offset += ((double) tick_gap); } } int setup() /* * Open the .pix and .his files. Zero the vectors. */ { register int i; auto int bottom, top; sprintf(line, "%s.pix", filename); if ((pixfd = fopen(line, R_BIN_MODE)) == NULL) { perror(line); goto nogood; } sprintf(line, "%s.his", filename); if ((hisfd = fopen(line, "r")) == NULL) { perror(line); goto close_pix; } if (fgets(line, sizeof line, hisfd) == NULL) { perror("histogram file -- first line"); goto close_both; } if (sscanf(line, #ifdef decus "%lf %lf %lf %d %d", #else "%f %f %f %d %d", #endif &orig_real, &orig_imag, &side, &npixel, &niter) != 5) { printf("First hist line didn't scan\n\"%s\"\n", line); goto close_both; } scr_clear(); scr_move(2, 1); printf("Origin %f", orig_real); printf(", %f\n", orig_imag); printf("side %f\n", side); printf("npixel %d\n", npixel); printf("niter %d\n", niter); for (i = 0; i < MAX_NITER; i++) hist[i] = 0.0; if (fgets(line, sizeof line, hisfd) == NULL) { perror("histogram file -- second line"); goto close_both; } if (sscanf(line, #ifdef decus "%d %d %lf", #else "%d %d %f", #endif &bottom, &top, &hist_sum) != 3) { printf("Second line didn't scan\n\"%s\"\n", line); goto close_both; } for (i = bottom; i <= top; i++) { if (fgets(line, sizeof line, hisfd) == NULL) { perror("histogram file -- data"); goto close_both; } if (sscanf(line, #ifdef decus "%lf", #else "%f", #endif &hist[i]) != 1) { printf("Histogram[%d] didn't scan\n\"%s\"", i, line); goto close_both; } } fclose(hisfd); return (TRUE); /* * Error exits */ close_both: fclose(hisfd); close_pix: fclose(pixfd); nogood: if (isatty(fileno(stdin))) { printf("Press return to continue.\n"); gets(line); } return (FALSE); } \f finish() { fclose(hisfd); fclose(pixfd); hisfd = NULL; pixfd = NULL; } int interactive() { if (isatty(fileno(stdin))) scr_clear(); if (!getstring(1, "Input filename", filename, DEF_FILENAME)) return (FALSE); return (TRUE); } stall() { dsp_draw(gray_scale - 1, 0); /* Force white */ dsp_text(0, 0, "Press return to continue"); dsp_done(); gets(line); dsp_finis(); }