home *** CD-ROM | disk | FTP | other *** search
- /*
- This program will generate a three dimensional maze suitable for
- printing on a Hewlett-Packard LaserJet II printer. A different random
- number seed will produce a different maze.
-
- Written by James L. Dean
- 406 40th Street
- New Orleans, LA 70124
- */
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #include <malloc.h>
-
- #define TRUE 1
- #define FALSE 0
-
- #define EBCDIC 0
-
- /* printer constants */
- #define DOTS_PER_INCH 150
- #define WIDTH_IN_INCHES 8.5
- #define LENGTH_IN_INCHES 11.0
- #define DOTS_PER_STROKE 2 /* 300/DOTS_PER_INCH */
- #define NUM_X_BYTES 206 /* (int) (LENGTH_IN_INCHES*DOTS_PER_INCH/8) */
- #define X_BYTE_MAX 205 /* NUM_X_BYTES-1 */
- #define NUM_X_DOTS 1648 /* 8*NUM_X_BYTES */
- #define X_DOT_MAX 1647 /* NUM_X_DOTS-1 */
- #define NUM_Y_DOTS 1275 /* (int) (WIDTH_IN_INCHES*DOTS_PER_INCH) */
- #define Y_DOT_MAX 1274 /* NUM_Y_DOTS-1 */
- #define NUM_SLICES 3 /* smaller values run faster, use more memory */
- #define ROWS_PER_SLICE 425 /* (NUM_Y_DOTS+NUM_SLICES-1)/NUM_SLICES */
-
- /* maze constants */
- #define MIN_DOTS_PER_ROOM_WALL 40
- #define NUM_COLUMNS 20 /* <= NUM_X_DOTS/MIN_DOTS_PER_ROOM_WALL */
- #define MAX_X 40 /* 2*NUM_COLUMNS */
- #define MAX_X_PLUS_1 41 /* MAX_X+1 */
- #define NUM_ROWS 15 /* <= NUM_Y_DOTS/MIN_DOTS_PER_ROOM_WALL */
- #define MAX_Y 30 /* 2*NUM_ROWS */
- #define MAX_Y_PLUS_1 31 /* MAX_Y+1 */
- /* ((double) NUM_COLUMNS)/((double) NUM_ROWS) should be approximately
- LENGTH_IN_INCHES/WIDTH_IN_INCHES.
- Memory requirements and run time increase with NUM_COLUMNS*NUM_ROWS.
- */
-
- typedef struct pointtype_record
- {
- int x;
- int y;
- } pointtype;
-
- typedef struct prime_rec_record *prime_rec_ptr;
-
- typedef struct prime_rec_record
- {
- double x;
- double y;
- double z;
- char base_z;
- prime_rec_ptr left;
- prime_rec_ptr right;
- prime_rec_ptr down;
- prime_rec_ptr lesser_x;
- prime_rec_ptr greater_x;
- } prime_rec;
-
- typedef struct row_type_record
- {
- unsigned char column [NUM_X_BYTES];
- } row_type;
-
- typedef row_type *row_ptr_type;
-
- typedef struct up_rec_record *up_rec_ptr;
-
- typedef struct up_rec_record
- {
- prime_rec_ptr up;
- up_rec_ptr next;
- up_rec_ptr previous;
- } up_rec;
-
- static void add_room(void);
- static void adjust_perspective(prime_rec_ptr *,prime_rec_ptr *,
- prime_rec_ptr *,double *,double *,double *,double *,double *,
- int *);
- static void draw_line(int *,int *,int *,int *,int);
- static void evaluate_and_transform(double *,double *,double *,double *,int *,
- int *,double *,double *,prime_rec_ptr *,prime_rec_ptr *,
- prime_rec_ptr *,double *,double *,double *,double *,double *,
- int *);
- static double f(double,double);
- void main(void);
- static void plot(prime_rec_ptr *,double *,double *,double *,double *,int *,
- int *);
- static void pset(int *,int *,int);
-
- static unsigned char black [8] = {128, 64, 32, 16, 8, 4, 2, 1};
- static int delta_x [4] [24];
- static int delta_y [4] [24];
- static char page [MAX_Y_PLUS_1] [MAX_X_PLUS_1];
- static int r_n [8];
- static int r_n_index_1;
- static int r_n_index_2;
- static row_ptr_type row_ptr [ROWS_PER_SLICE];
- static int slice_y;
- static int slice_y_start;
- static int slice_y_stop;
- static int tem_int;
- static unsigned char white [8] = {127, 191, 223, 239, 247, 251, 253, 254};
- static int x;
- static double x_max;
- static int x_next;
- static int x_wall_1;
- static int y;
- static int y_next;
- static int y_wall_1;
-
- void main(void)
- {
- static unsigned char ascii_equivalent [6];
- #if EBCDIC
- static unsigned char *char_ptr;
- #endif
- register int column_num;
- static int cursor_x;
- static char cursor_x_prefix [3] = {'\033', '\052', '\160'};
- static char cursor_x_suffix = '\130';
- static int cursor_y;
- static char cursor_y_prefix [3] = {'\033', '\052', '\160'};
- static char cursor_y_suffix = '\131';
- static int delta_index_1a;
- static int delta_index_1b;
- static int delta_index_1c;
- static int delta_index_1d;
- static int delta_index_2;
- static int digit;
- static int digit_num;
- static char dpi_prefix [3] = {'\033', '\052', '\164'};
- static char dpi_suffix = '\122';
- register int ending_column_num;
- static int fatal_error;
- static char formfeed = '\014';
- static char landscape [5]
- = {'\033', '\046', '\154', '\061', '\117'};
- static char logical_mode [5]
- = {'\033', '\052', '\162', '\060', '\106'};
- static int max_y_out;
- static int max_z_out;
- FILE *maze;
- static int non_null_found;
- static int num_bytes;
- static int num_x_divisions;
- static int num_y_divisions;
- static prime_rec_ptr prime_cornor;
- static prime_rec_ptr prime_head;
- static prime_rec_ptr prime_ptr;
- static prime_rec_ptr prime_tail;
- static char raster_prefix [5]
- = {'\033', '\052', '\162', '\061', '\101'};
- static char raster_suffix [4]
- = {'\033', '\052', '\162', '\102'};
- static double rotation;
- static int row_num;
- static char row_prefix [3] = {'\033', '\052', '\142'};
- static char row_suffix = '\127';
- static char seed [256];
- static int seed_length;
- static int starting_column_num;
- static int sum;
- static double tilt;
- static double x_min;
- static int x_out;
- static double x_prime_max;
- static double y_max;
- static double y_min;
- static int y_out;
- static double y_prime_max;
- static double y_prime_min;
- static double z_prime_max;
- static double z_prime_min;
-
- fatal_error=FALSE;
- printf("\n The maze will be outputted to HP3DMAZE.\n\n");
- printf(" Random number seed? ");
- gets(&seed[0]);
- seed_length=strlen(&seed[0]);
- for (r_n_index_1=0; r_n_index_1 < seed_length; ++r_n_index_1)
- {
- tem_int=(int) seed[r_n_index_1];
- while (tem_int >= 29)
- tem_int-=29;
- r_n[r_n_index_1]=tem_int;
- }
- r_n_index_2=7;
- while (r_n_index_1 > 0)
- {
- r_n_index_1--;
- r_n[r_n_index_2]=r_n[r_n_index_1];
- r_n_index_2--;
- }
- while (r_n_index_2 >= 0)
- {
- r_n[r_n_index_2]=19;
- r_n_index_2--;
- }
- delta_x[0][0]=-1;
- delta_y[0][0]=0;
- delta_x[1][0]=0;
- delta_y[1][0]=1;
- delta_x[2][0]=1;
- delta_y[2][0]=0;
- delta_x[3][0]=0;
- delta_y[3][0]=-1;
- delta_index_2=0;
- for (delta_index_1a=0; delta_index_1a < 4; ++delta_index_1a)
- for (delta_index_1b=0; delta_index_1b < 4; ++delta_index_1b)
- if (delta_index_1a != delta_index_1b)
- for (delta_index_1c=0; delta_index_1c < 4; ++delta_index_1c)
- if ((delta_index_1a != delta_index_1c)
- && (delta_index_1b != delta_index_1c))
- for (delta_index_1d=0; delta_index_1d < 4; ++delta_index_1d)
- if ((delta_index_1a != delta_index_1d)
- && (delta_index_1b != delta_index_1d)
- && (delta_index_1c != delta_index_1d))
- {
- delta_x[delta_index_1a][delta_index_2]=delta_x[0][0];
- delta_y[delta_index_1a][delta_index_2]=delta_y[0][0];
- delta_x[delta_index_1b][delta_index_2]=delta_x[1][0];
- delta_y[delta_index_1b][delta_index_2]=delta_y[1][0];
- delta_x[delta_index_1c][delta_index_2]=delta_x[2][0];
- delta_y[delta_index_1c][delta_index_2]=delta_y[2][0];
- delta_x[delta_index_1d][delta_index_2]=delta_x[3][0];
- delta_y[delta_index_1d][delta_index_2]=delta_y[3][0];
- delta_index_2++;
- }
- for (row_num=0; ((row_num < ROWS_PER_SLICE) && (! fatal_error));
- ++row_num)
- {
- if ((row_ptr[row_num]=(row_type *) malloc(sizeof(row_type))) == NULL)
- {
- fatal_error=TRUE;
- printf("\n Fatal error: out of memory\n");
- }
- }
- if (! fatal_error)
- {
- max_y_out=X_DOT_MAX;
- max_z_out=Y_DOT_MAX;
- for (y_out=0; y_out <= MAX_Y; ++y_out)
- for (x_out=0; x_out <= MAX_X; ++x_out)
- page[y_out][x_out]='W';
- sum=0;
- for (digit_num=1; digit_num <= 3; ++digit_num)
- {
- digit=r_n[0];
- r_n_index_1=0;
- for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
- {
- tem_int=r_n[r_n_index_2];
- r_n[r_n_index_1]=tem_int;
- digit+=tem_int;
- if (digit >= 29)
- digit-=29;
- r_n_index_1=r_n_index_2;
- }
- r_n[7]=digit;
- sum=29*sum+digit;
- }
- x=2*(sum % NUM_COLUMNS)+1;
- sum=0;
- for (digit_num=1; digit_num <= 3; ++digit_num)
- {
- digit=r_n[0];
- r_n_index_1=0;
- for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
- {
- tem_int=r_n[r_n_index_2];
- r_n[r_n_index_1]=tem_int;
- digit+=tem_int;
- if (digit >= 29)
- digit-=29;
- r_n_index_1=r_n_index_2;
- }
- r_n[7]=digit;
- sum=29*sum+digit;
- }
- y=2*(sum % NUM_ROWS)+1;
- add_room();
- page[0][1]=' ';
- page[MAX_Y][MAX_X-1]=' ';
- x_min=1.0;
- x_max=(double) MAX_Y;
- x_max=2.0*x_max+5.0;
- y_min=1.0;
- y_max=(double) MAX_X;
- y_max=2.0*y_max+5.0;
- num_x_divisions=2*MAX_Y+5;
- num_y_divisions=2*MAX_X+5;
- prime_head=NULL;
- rotation=20.0;
- tilt=30.0;
- evaluate_and_transform(&x_min,&x_max,&y_min,&y_max,&num_x_divisions,
- &num_y_divisions,&rotation,&tilt,&prime_cornor,&prime_head,
- &prime_tail,&x_prime_max,&y_prime_min,&y_prime_max,&z_prime_min,
- &z_prime_max,&fatal_error);
- }
- if (! fatal_error)
- adjust_perspective(&prime_cornor,&prime_head,&prime_tail,&x_prime_max,
- &y_prime_min,&y_prime_max,&z_prime_min,&z_prime_max,&fatal_error);
- if (! fatal_error)
- {
- maze=fopen("HP3DMAZE","wb");
- fwrite(landscape,sizeof(landscape),1,maze);
- fwrite(dpi_prefix,sizeof(dpi_prefix),1,maze);
- sprintf((char *) ascii_equivalent,"%d",DOTS_PER_INCH);
- #if EBCDIC
- char_ptr=&(ascii_equivalent[0]);
- while (*char_ptr)
- {
- (*char_ptr)-=192;
- char_ptr++;
- }
- #endif
- fwrite(&(ascii_equivalent[0]),strlen((char *) ascii_equivalent),1,
- maze);
- fwrite(&dpi_suffix,sizeof(dpi_suffix),1,maze);
- fwrite(logical_mode,sizeof(logical_mode),1,maze);
- slice_y_start=0;
- while (slice_y_start <= Y_DOT_MAX)
- {
- slice_y_stop=slice_y_start+ROWS_PER_SLICE-1;
- if (slice_y_stop > Y_DOT_MAX)
- slice_y_stop=Y_DOT_MAX;
- for (row_num=0; row_num < ROWS_PER_SLICE; row_num++)
- for (column_num=0; column_num <= X_BYTE_MAX; column_num++)
- row_ptr[row_num]->column[column_num]=0;
- plot(&prime_tail,&y_prime_min,&y_prime_max,&z_prime_min,
- &z_prime_max,&max_y_out,&max_z_out);
- row_num=0;
- for (slice_y=slice_y_start; slice_y <= slice_y_stop; slice_y++)
- {
- starting_column_num=0;
- non_null_found=FALSE;
- while ((starting_column_num <= X_BYTE_MAX)
- && (! non_null_found))
- if (row_ptr[row_num]->column[starting_column_num] == 0)
- starting_column_num++;
- else
- non_null_found=TRUE;
- if (non_null_found)
- {
- non_null_found=FALSE;
- ending_column_num=X_BYTE_MAX;
- while ((ending_column_num >= 0) && (! non_null_found))
- if (row_ptr[row_num]->column[ending_column_num] == 0)
- ending_column_num--;
- else
- non_null_found=TRUE;
- fwrite(cursor_x_prefix,sizeof(cursor_x_prefix),1,maze);
- cursor_x=DOTS_PER_STROKE*8*starting_column_num;
- sprintf((char *) ascii_equivalent,"%d",cursor_x);
- #if EBCDIC
- char_ptr=&(ascii_equivalent[0]);
- while (*char_ptr)
- {
- (*char_ptr)-=192;
- char_ptr++;
- }
- #endif
- fwrite(&(ascii_equivalent[0]),strlen(ascii_equivalent),1,
- maze);
- fwrite(&cursor_x_suffix,sizeof(cursor_x_suffix),1,maze);
- fwrite(cursor_y_prefix,sizeof(cursor_y_prefix),1,maze);
- cursor_y=DOTS_PER_STROKE*slice_y;
- sprintf(ascii_equivalent,"%d",cursor_y);
- #if EBCDIC
- char_ptr=&(ascii_equivalent[0]);
- while (*char_ptr)
- {
- (*char_ptr)-=192;
- char_ptr++;
- }
- #endif
- fwrite(&(ascii_equivalent[0]),strlen(ascii_equivalent),1,
- maze);
- fwrite(&cursor_y_suffix,sizeof(cursor_y_suffix),1,maze);
- fwrite(raster_prefix,sizeof(raster_prefix),1,maze);
- fwrite(row_prefix,sizeof(row_prefix),1,maze);
- num_bytes=ending_column_num-starting_column_num+1;
- sprintf(ascii_equivalent,"%d",num_bytes);
- #if EBCDIC
- char_ptr=&(ascii_equivalent[0]);
- while (*char_ptr)
- {
- (*char_ptr)-=192;
- char_ptr++;
- }
- #endif
- fwrite(&(ascii_equivalent[0]),strlen(ascii_equivalent),1,
- maze);
- fwrite(&row_suffix,sizeof(row_suffix),1,maze);
- fwrite(&(row_ptr[row_num]->column[starting_column_num]),
- num_bytes,1,maze);
- fwrite(raster_suffix,sizeof(raster_suffix),1,maze);
- }
- row_num++;
- }
- slice_y_start+=ROWS_PER_SLICE;
- }
- fwrite(&formfeed,sizeof(formfeed),1,maze);
- fclose(maze);
- while (prime_head != NULL)
- {
- prime_ptr=prime_head->greater_x;
- free(prime_head);
- prime_head=prime_ptr;
- }
- for (row_num=0; row_num < ROWS_PER_SLICE; ++row_num)
- free(row_ptr[row_num]);
- }
- }
-
- static void add_room()
- {
- unsigned char delta_index_1;
- unsigned char delta_index_2;
-
- page[y][x]=' ';
- delta_index_1=0;
- do
- {
- delta_index_2=(unsigned char) r_n[0];
- r_n_index_1=0;
- for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
- {
- tem_int=r_n[r_n_index_2];
- r_n[r_n_index_1]=tem_int;
- delta_index_2+=(unsigned char) tem_int;
- if (delta_index_2 >= 29)
- delta_index_2-=29;
- r_n_index_1=r_n_index_2;
- }
- r_n[7]=delta_index_2;
- }
- while (delta_index_2 >= 24);
- while (delta_index_1 < 4)
- {
- x_next=x+2*delta_x[delta_index_1][delta_index_2];
- if ((x_next <= 0) || (x_next >= MAX_X))
- delta_index_1++;
- else
- {
- y_next=y+2*delta_y[delta_index_1][delta_index_2];
- if ((y_next <= 0) || (y_next >= MAX_Y))
- delta_index_1++;
- else
- if (page[y_next][x_next] == 'W')
- {
- if (x == x_next)
- {
- y_wall_1=(y+y_next)/2;
- page[y_wall_1][x_next]=' ';
- }
- else
- {
- x_wall_1=(x+x_next)/2;
- page[y_next][x_wall_1]=' ';
- }
- x=x_next;
- y=y_next;
- add_room();
- x-=2*delta_x[delta_index_1][delta_index_2];
- y-=2*delta_y[delta_index_1][delta_index_2];
- }
- else
- delta_index_1++;
- }
- }
- }
-
- static double f(x,y)
- double x;
- double y;
- {
- register int x_out;
- register int y_out;
- static double z;
-
- y_out=((int) x)-2;
- if (y_out < 0)
- z=0.0;
- else
- if (y_out > 2*MAX_Y+1)
- z=0.0;
- else
- {
- x_out=((int) y)-2;
- if (x_out < 0)
- z=0.0;
- else
- if (x_out > 2*MAX_X+1)
- z=0.0;
- else
- if (page[y_out/2][x_out/2] == 'W')
- z=7.0;
- else
- z=0.0;
- }
- return(z);
- }
-
- static void evaluate_and_transform(x_min,x_max,y_min,y_max,num_x_divisions,
- num_y_divisions,rotation,tilt,prime_cornor,prime_head,prime_tail,x_prime_max,
- y_prime_min,y_prime_max,z_prime_min,z_prime_max,fatal_error)
- double *x_min;
- double *x_max;
- double *y_min;
- double *y_max;
- int *num_x_divisions;
- int *num_y_divisions;
- double *rotation;
- double *tilt;
- prime_rec_ptr *prime_cornor;
- prime_rec_ptr *prime_head;
- prime_rec_ptr *prime_tail;
- double *x_prime_max;
- double *y_prime_min;
- double *y_prime_max;
- double *z_prime_min;
- double *z_prime_max;
- int *fatal_error;
- {
- static double cos_rotation;
- static double cos_tilt;
- static double delta_x;
- static double delta_y;
- static prime_rec_ptr last_prime_ptr;
- static prime_rec_ptr prime_ptr;
- static double radians;
- static double radians_per_degree;
- static prime_rec_ptr left;
- static double sin_rotation;
- static double sin_tilt;
- static up_rec_ptr up_head;
- static up_rec_ptr up_ptr;
- static up_rec_ptr up_tail;
- static double x;
- register int x_division_num;
- static double y;
- register int y_division_num;
- static double x_rotated;
- static double z;
-
- radians_per_degree=atan((double) 1.0)/45.0;
- radians=(*tilt)*radians_per_degree;
- cos_tilt=cos(radians);
- sin_tilt=sin(radians);
- radians=(*rotation)*radians_per_degree;
- cos_rotation=cos(radians);
- sin_rotation=sin(radians);
- z=f(*x_min,*y_min);
- x_rotated=(*x_min)*cos_rotation+(*y_min)*sin_rotation;
- (*y_prime_min)=-(*x_min)*sin_rotation+(*y_min)*cos_rotation;
- (*z_prime_min)=-x_rotated*sin_tilt+z*cos_tilt;
- (*x_prime_max)=x_rotated*cos_tilt+z*sin_tilt;
- (*y_prime_max)=(*y_prime_min);
- (*z_prime_max)=(*z_prime_min);
- last_prime_ptr=NULL;
- delta_x=(double) (*num_x_divisions);
- delta_x=((*x_max)-(*x_min))/delta_x;
- delta_y=(double) (*num_y_divisions);
- delta_y=((*y_max)-(*y_min))/delta_y;
- up_head=NULL;
- up_tail=NULL;
- for (y_division_num=1;
- ((y_division_num <= (*num_y_divisions)) && (! *fatal_error));
- ++y_division_num)
- {
- if ((up_ptr=(up_rec *) malloc(sizeof(up_rec))) == NULL)
- {
- *fatal_error=TRUE;
- printf("\n Fatal error: out of memory\n");
- }
- else
- {
- up_ptr->up=NULL;
- if (up_head == NULL)
- {
- up_head=up_ptr;
- up_ptr->previous=NULL;
- }
- else
- {
- up_tail->next=up_ptr;
- up_ptr->previous=up_tail;
- }
- up_ptr->next=NULL;
- up_tail=up_ptr;
- }
- }
- x=(*x_min);
- for (x_division_num=1;
- ((x_division_num <= (*num_x_divisions)) && (! *fatal_error));
- ++x_division_num)
- {
- left=NULL;
- up_ptr=up_head;
- y=(*y_min);
- for (y_division_num=1;
- ((y_division_num <= (*num_y_divisions)) && (! *fatal_error));
- ++y_division_num)
- {
- z=f(x,y);
- if ((prime_ptr=(prime_rec *) malloc(sizeof(prime_rec)))
- == NULL)
- {
- *fatal_error=TRUE;
- printf("\n Fatal error: out of memory\n");
- }
- else
- {
- prime_ptr->left=left;
- if (z > 0.0)
- prime_ptr->base_z=(char) 1;
- else
- prime_ptr->base_z=(char) 0;
- if (left != NULL)
- left->right=prime_ptr;
- if (up_ptr->up != NULL)
- up_ptr->up->down=prime_ptr;
- x_rotated=x*cos_rotation+y*sin_rotation;
- prime_ptr->y=-x*sin_rotation+y*cos_rotation;
- prime_ptr->x=x_rotated*cos_tilt+z*sin_tilt;
- prime_ptr->z=-x_rotated*sin_tilt+z*cos_tilt;
- if (prime_ptr->x > (*x_prime_max))
- (*x_prime_max)=prime_ptr->x;
- if (prime_ptr->y < (*y_prime_min))
- (*y_prime_min)=prime_ptr->y;
- if (prime_ptr->y > (*y_prime_max))
- (*y_prime_max)=prime_ptr->y;
- if (prime_ptr->z < (*z_prime_min))
- (*z_prime_min)=prime_ptr->z;
- if (prime_ptr->z > (*z_prime_max))
- (*z_prime_max)=prime_ptr->z;
- prime_ptr->lesser_x=NULL;
- if (last_prime_ptr == NULL)
- {
- (*prime_tail)=prime_ptr;
- (*prime_cornor)=prime_ptr;
- prime_ptr->greater_x=NULL;
- }
- else
- {
- (*prime_head)->lesser_x=prime_ptr;
- prime_ptr->greater_x=(*prime_head);
- }
- (*prime_head)=prime_ptr;
- left=prime_ptr;
- up_ptr->up=prime_ptr;
- up_ptr=up_ptr->next;
- last_prime_ptr=prime_ptr;
- y+=delta_y;
- }
- }
- if (! *fatal_error)
- {
- left->right=NULL;
- x+=delta_x;
- }
- }
- if (! *fatal_error)
- while (up_head != NULL)
- {
- up_head->up->down=NULL;
- up_ptr=up_head->next;
- free(up_head);
- up_head=up_ptr;
- }
- }
-
- static void adjust_perspective(prime_cornor,prime_head,prime_tail,x_prime_max,
- y_prime_min,y_prime_max,z_prime_min,z_prime_max,fatal_error)
- prime_rec_ptr *prime_cornor;
- prime_rec_ptr *prime_head;
- prime_rec_ptr *prime_tail;
- double *x_prime_max;
- double *y_prime_min;
- double *y_prime_max;
- double *z_prime_min;
- double *z_prime_max;
- int *fatal_error;
- {
- static double delta_x;
- static double delta_y;
- static double delta_z;
- register int finished;
- static prime_rec_ptr last_prime_ptr;
- static prime_rec_ptr left;
- static prime_rec_ptr new_prime_head;
- static prime_rec_ptr new_prime_ptr;
- static prime_rec_ptr new_prime_tail;
- static prime_rec_ptr next_prime_row;
- static prime_rec_ptr prime_column;
- static prime_rec_ptr prime_ptr;
- static prime_rec_ptr prime_row;
- static up_rec_ptr up_head;
- static up_rec_ptr up_ptr;
- static up_rec_ptr up_tail;
- static double x_eye;
- static double y_center;
- static double z_center;
-
- if (((*y_prime_max)-(*y_prime_min)) > ((*z_prime_max)-(*z_prime_min)))
- x_eye=2.0*((*y_prime_max)-(*y_prime_min))+(*x_prime_max);
- else
- x_eye=2.0*((*z_prime_max)-(*z_prime_min))+(*x_prime_max);
- if (x_eye != (*x_prime_max))
- {
- up_head=NULL;
- up_tail=NULL;
- prime_column=(*prime_cornor);
- while ((prime_column != NULL) && (! *fatal_error))
- {
- if ((up_ptr=(up_rec *) malloc(sizeof(up_rec))) == NULL)
- {
- *fatal_error=TRUE;
- printf("\n Fatal error: out of memory\n");
- }
- else
- {
- up_ptr->up=NULL;
- if (up_head == NULL)
- {
- up_head=up_ptr;
- up_ptr->previous=NULL;
- }
- else
- {
- up_tail->next=up_ptr;
- up_ptr->previous=up_tail;
- }
- up_ptr->next=NULL;
- up_tail=up_ptr;
- prime_column=prime_column->right;
- }
- }
- y_center=(double) ((*y_prime_max)+(*y_prime_min))/2.0;
- z_center=(double) ((*z_prime_max)+(*z_prime_min))/2.0;
- last_prime_ptr=NULL;
- new_prime_head=NULL;
- new_prime_tail=NULL;
- prime_row=(*prime_cornor);
- while ((prime_row != NULL) && (! *fatal_error))
- {
- left=NULL;
- up_ptr=up_head;
- next_prime_row=prime_row->down;
- prime_column=prime_row;
- while ((prime_column != NULL) && (! *fatal_error))
- {
- if ((new_prime_ptr=(prime_rec *) malloc(sizeof(prime_rec)))
- == NULL)
- {
- *fatal_error=TRUE;
- printf("\n Fatal error: out of memory\n");
- }
- else
- {
- new_prime_ptr->left=left;
- new_prime_ptr->base_z=prime_column->base_z;
- if (left != NULL)
- left->right=new_prime_ptr;
- if (up_ptr->up != NULL)
- up_ptr->up->down=new_prime_ptr;
- delta_x=prime_column->x-x_eye;
- delta_y=prime_column->y-y_center;
- delta_z=prime_column->z-z_center;
- new_prime_ptr->x
- =sqrt(delta_x*delta_x+delta_y*delta_y+delta_z*delta_z);
- new_prime_ptr->y
- =y_center+(double)(prime_column->y-y_center)
- *(x_eye-(*x_prime_max))/(x_eye-prime_column->x);
- new_prime_ptr->z
- =z_center+(double)(prime_column->z-z_center)
- *(x_eye-(*x_prime_max))/(x_eye-prime_column->x);
- if (last_prime_ptr == NULL)
- {
- new_prime_head=new_prime_ptr;
- new_prime_tail=new_prime_ptr;
- new_prime_ptr->lesser_x=NULL;
- new_prime_ptr->greater_x=NULL;
- }
- else
- if (new_prime_ptr->x < last_prime_ptr->x)
- {
- finished=FALSE;
- while (! finished)
- {
- last_prime_ptr=last_prime_ptr->lesser_x;
- if (last_prime_ptr == NULL)
- finished=TRUE;
- else
- {
- if (new_prime_ptr->x >= last_prime_ptr->x)
- finished=TRUE;
- }
- }
- new_prime_ptr->lesser_x=last_prime_ptr;
- if (last_prime_ptr == NULL)
- {
- new_prime_head->lesser_x=new_prime_ptr;
- new_prime_ptr->greater_x=new_prime_head;
- new_prime_head=new_prime_ptr;
- }
- else
- {
- new_prime_ptr->greater_x
- =last_prime_ptr->greater_x;
- last_prime_ptr->greater_x->lesser_x
- =new_prime_ptr;
- last_prime_ptr->greater_x=new_prime_ptr;
- }
- }
- else
- {
- finished=FALSE;
- while (! finished)
- {
- last_prime_ptr=last_prime_ptr->greater_x;
- if (last_prime_ptr == NULL)
- finished=TRUE;
- else
- {
- if (new_prime_ptr->x <= last_prime_ptr->x)
- finished=TRUE;
- }
- }
- new_prime_ptr->greater_x=last_prime_ptr;
- if (last_prime_ptr == NULL)
- {
- new_prime_tail->greater_x=new_prime_ptr;
- new_prime_ptr->lesser_x=new_prime_tail;
- new_prime_tail=new_prime_ptr;
- }
- else
- {
- new_prime_ptr->lesser_x
- =last_prime_ptr->lesser_x;
- last_prime_ptr->lesser_x->greater_x
- =new_prime_ptr;
- last_prime_ptr->lesser_x=new_prime_ptr;
- }
- }
- }
- if (! *fatal_error)
- {
- left=new_prime_ptr;
- up_ptr->up=new_prime_ptr;
- up_ptr=up_ptr->next;
- last_prime_ptr=new_prime_ptr;
- prime_ptr=prime_column->right;
- free(prime_column);
- prime_column=prime_ptr;
- }
- }
- if (! *fatal_error)
- {
- left->right=NULL;
- prime_row=next_prime_row;
- }
- }
- if (! *fatal_error)
- {
- (*prime_head)=new_prime_head;
- (*prime_tail)=new_prime_tail;
- while (up_head != NULL)
- {
- up_head->up->down=NULL;
- up_ptr=up_head->next;
- free(up_head);
- up_head=up_ptr;
- }
- }
- }
- }
-
- static void pset(x,y,shading)
- int *x;
- int *y;
- int shading;
- {
- register int bit_num;
- register int byte_num;
- static int dot;
- static int slice_y;
-
- if ((*y) >= slice_y_start)
- {
- if ((*y) <= slice_y_stop)
- {
- byte_num=(*x)/8;
- bit_num=(*x)-8*byte_num;
- switch (shading)
- {
- case 0:
- switch ((*y) % 4)
- {
- case 0:
- if (((*x) % 4) == 3)
- dot=TRUE;
- else
- dot=FALSE;
- break;
- case 1:
- if (((*x) % 4) == 1)
- dot=TRUE;
- else
- dot=FALSE;
- break;
- case 2:
- if (((*x) % 4) == 2)
- dot=TRUE;
- else
- dot=FALSE;
- break;
- default:
- if (((*x) % 4) == 0)
- dot=TRUE;
- else
- dot=FALSE;
- break;
- }
- break;
- case 1:
- if ((*y) % 2)
- if (((*x) % 4) == 1)
- dot=TRUE;
- else
- dot=FALSE;
- else
- if ((*x) % 2)
- dot=FALSE;
- else
- dot=TRUE;
- break;
- case 2:
- if ((*y) % 2)
- if ((*x) % 2)
- dot=TRUE;
- else
- dot=FALSE;
- else
- if ((*x) % 2)
- dot=FALSE;
- else
- dot=TRUE;
- break;
- default:
- dot=TRUE;
- break;
- };
- slice_y=(*y)-slice_y_start;
- if (dot)
- row_ptr[slice_y]->column[byte_num]
- =(row_ptr[slice_y]->column[byte_num] | black[bit_num]);
- else
- row_ptr[slice_y]->column[byte_num]
- =(row_ptr[slice_y]->column[byte_num] & white[bit_num]);
- }
- }
- }
-
- static void draw_line(x1,y1,x2,y2,shading)
- int *x1;
- int *y1;
- int *x2;
- int *y2;
- int shading;
- {
- static int error;
- static int error_prime_x;
- static int error_prime_y;
- register int permissible_delta_x;
- register int permissible_delta_y;
- static int x;
- static int x_diff;
- static int y;
- static int y_diff;
-
- if ((*x2) >= (*x1))
- permissible_delta_x=1;
- else
- permissible_delta_x=-1;
- if ((*y2) >= (*y1))
- permissible_delta_y=1;
- else
- permissible_delta_y=-1;
- x=(*x1);
- y=(*y1);
- x_diff=(*x2)-(*x1);
- y_diff=(*y2)-(*y1);
- error=0;
- pset(&x,&y,shading);
- while ((x != (*x2)) || (y != (*y2)))
- {
- error_prime_x=error+permissible_delta_x*y_diff;
- error_prime_y=error-permissible_delta_y*x_diff;
- if (abs(error_prime_x) <= abs(error_prime_y))
- {
- x+=permissible_delta_x;
- error=error_prime_x;
- }
- else
- {
- y+=permissible_delta_y;
- error=error_prime_y;
- }
- pset(&x,&y,shading);
- }
- }
-
- static void plot(prime_tail,y_prime_min,y_prime_max,z_prime_min,z_prime_max,
- max_y_out,max_z_out)
- prime_rec_ptr *prime_tail;
- double *y_prime_min;
- double *y_prime_max;
- double *z_prime_min;
- double *z_prime_max;
- int *max_y_out;
- int *max_z_out;
- {
- static pointtype box [4];
- static long box_delta_x;
- static long box_delta_y;
- register int box_num_1;
- register int box_num_2;
- static long box_x_intercept;
- static int box_x1;
- static int box_x2;
- static int box_y_max;
- static int box_y_min;
- static long box_y_offset;
- static int box_y1;
- static int intercept_count_mod_2;
- static int line_x1;
- static int line_x2;
- static int line_y1;
- static int line_y2;
- static double pixels_per_unit;
- static prime_rec_ptr prime_ptr;
- static int shading;
- static double y_offset;
- static double y_out_max;
- static double z_offset;
- static double z_out_max;
-
- y_out_max=(double) (*max_y_out);
- z_out_max=(double) (*max_z_out);
- if (z_out_max*((*y_prime_max)-(*y_prime_min))
- > y_out_max*((*z_prime_max)-(*z_prime_min)))
- {
- pixels_per_unit=y_out_max/((*y_prime_max)-(*y_prime_min));
- y_offset=0.0;
- z_offset
- =-(z_out_max-pixels_per_unit*((*z_prime_max)-(*z_prime_min)))/2.0;
- }
- else
- if (z_out_max*((*y_prime_max)-(*y_prime_min))
- < y_out_max*((*z_prime_max)-(*z_prime_min)))
- {
- pixels_per_unit=z_out_max/((*z_prime_max)-(*z_prime_min));
- y_offset
- =(y_out_max-pixels_per_unit*((*y_prime_max)-(*y_prime_min)))/2.0;
- z_offset=0.0;
- }
- else
- /* plot degenerates to a single point */
- {
- pixels_per_unit=1.0;
- y_offset=y_out_max/2.0;
- z_offset=-z_out_max/2.0;
- }
- prime_ptr=(*prime_tail);
- while ((prime_ptr != NULL))
- {
- if ((prime_ptr->right != NULL))
- {
- if ((prime_ptr->down != NULL))
- {
- box[0].x=(int) (y_offset+pixels_per_unit
- *(prime_ptr->y-(*y_prime_min)));
- box[0].y=(int) (z_offset+z_out_max-pixels_per_unit
- *(prime_ptr->z-(*z_prime_min)));
- box[1].x=(int) (y_offset+pixels_per_unit
- *(prime_ptr->right->y-(*y_prime_min)));
- box[1].y=(int) (z_offset+z_out_max-pixels_per_unit
- *(prime_ptr->right->z-(*z_prime_min)));
- box[3].x=(int) (y_offset+pixels_per_unit
- *(prime_ptr->down->y-(*y_prime_min)));
- box[3].y=(int) (z_offset+z_out_max-pixels_per_unit
- *(prime_ptr->down->z-(*z_prime_min)));
- box[2].x=(int) (y_offset+pixels_per_unit
- *(prime_ptr->down->right->y-(*y_prime_min)));
- box[2].y=(int) (z_offset+z_out_max-pixels_per_unit
- *(prime_ptr->down->right->z-(*z_prime_min)));
- box_y_min=box[0].y;
- box_y_max=box_y_min;
- if ((prime_ptr->base_z == (char) 1)
- && (prime_ptr->right->base_z == (char) 1)
- && (prime_ptr->down->base_z == (char) 1)
- && (prime_ptr->down->right->base_z == (char) 1))
- shading=0;
- else
- if ((prime_ptr->base_z == (char) 0)
- && (prime_ptr->right->base_z == (char) 0)
- && (prime_ptr->down->base_z == (char) 0)
- && (prime_ptr->down->right->base_z == (char) 0))
- shading=1;
- else
- if ((prime_ptr->base_z == (char) 1)
- && (prime_ptr->right->base_z == (char) 1)
- && (prime_ptr->down->base_z == (char) 0)
- && (prime_ptr->down->right->base_z == (char) 0))
- shading=2;
- else
- if ((prime_ptr->base_z == (char) 1)
- && (prime_ptr->right->base_z == (char) 0)
- && (prime_ptr->down->base_z == (char) 1)
- && (prime_ptr->down->right->base_z == (char) 0))
- shading=3;
- else
- if ((prime_ptr->down->down == NULL)
- && (prime_ptr->base_z == (char) 0))
- shading=1;
- else
- shading=2;
- for (box_num_1=1; box_num_1 < 4; ++box_num_1)
- {
- if (box[box_num_1].y < box_y_min)
- box_y_min=box[box_num_1].y;
- if (box[box_num_1].y > box_y_max)
- box_y_max=box[box_num_1].y;
- }
- for (box_y1=box_y_min; box_y1 <= box_y_max; ++box_y1)
- {
- intercept_count_mod_2=0;
- box_num_2=1;
- for (box_num_1=0; box_num_1 < 4; ++box_num_1)
- {
- if (box[box_num_1].y >= box_y1)
- {
- if (box_y1 > box[box_num_2].y)
- {
- box_delta_y=box[box_num_2].y-box[box_num_1].y;
- box_delta_x=box[box_num_2].x-box[box_num_1].x;
- box_y_offset=box_y1-box[box_num_1].y;
- box_x_intercept=box[box_num_1].x;
- box_x1=(int) ((box_delta_x*box_y_offset)
- /box_delta_y+box_x_intercept);
- if (intercept_count_mod_2 == 0)
- box_x2=box_x1;
- else
- {
- if (box_x1 < box_x2)
- {
- line_x1=box_x1;
- line_x2=box_x2;
- }
- else
- {
- line_x1=box_x2;
- line_x2=box_x1;
- }
- pset(&line_x1,&box_y1,shading);
- while (line_x1 < line_x2)
- {
- line_x1++;
- pset(&line_x1,&box_y1,shading);
- }
- }
- intercept_count_mod_2=1-intercept_count_mod_2;
- }
- }
- else
- {
- if (box_y1 <= box[box_num_2].y)
- {
- box_delta_y=box[box_num_2].y-box[box_num_1].y;
- box_delta_x=box[box_num_2].x-box[box_num_1].x;
- box_y_offset=box_y1-box[box_num_1].y;
- box_x_intercept=box[box_num_1].x;
- box_x1=(int) ((box_delta_x*box_y_offset)
- /box_delta_y+box_x_intercept);
- if (intercept_count_mod_2 == 0)
- box_x2=box_x1;
- else
- {
- if (box_x1 < box_x2)
- {
- line_x1=box_x1;
- line_x2=box_x2;
- }
- else
- {
- line_x1=box_x2;
- line_x2=box_x1;
- }
- pset(&line_x1,&box_y1,shading);
- while (line_x1 < line_x2)
- {
- line_x1++;
- pset(&line_x1,&box_y1,shading);
- }
- }
- intercept_count_mod_2=1-intercept_count_mod_2;
- }
- }
- box_num_2++;
- if (box_num_2 >= 4)
- box_num_2=0;
- }
- }
- box_num_2=1;
- for (box_num_1=0; box_num_1 < 4; ++box_num_1)
- {
- line_x1=box[box_num_1].x;
- line_y1=box[box_num_1].y;
- line_x2=box[box_num_2].x;
- line_y2=box[box_num_2].y;
- box_num_2++;
- draw_line(&line_x1,&line_y1,&line_x2,&line_y2,shading);
- if (box_num_2 >= 4)
- box_num_2=0;
- }
- if ((prime_ptr->base_z == (char) 1)
- && (prime_ptr->right->base_z == (char) 1)
- && (prime_ptr->down->base_z == (char) 0)
- && (prime_ptr->down->right->base_z == (char) 0))
- {
- if (prime_ptr->left != NULL)
- {
- if (prime_ptr->left->base_z == (char) 0)
- {
- shading=0;
- line_x1=box[0].x;
- line_y1=box[0].y;
- line_x2=box[3].x;
- line_y2=box[3].y;
- draw_line(&line_x1,&line_y1,&line_x2,&line_y2,
- shading);
- }
- }
- }
- }
- }
- prime_ptr=prime_ptr->lesser_x;
- }
- }