|
|
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();
}