home *** CD-ROM | disk | FTP | other *** search
- /* 2DtoHPGL.c - convert 2-D list to HPGL plotter commands */
-
- /* Oscar Garcia <garciao@mof.govt.nz>, May 1992 */
-
- /* uses getopt */
- int getopt(int argc, char *argv[], char *options);
- extern int optind;
- extern char *optarg;
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include <ctype.h>
- #include <string.h>
-
- #define USAGE "usage: 2DtoHPGL [/s] [/xn] [/yn] [/wn] [/hn] [/pn]\
- [input_file [output_file]]\n\
- \tIf file names are omitted, the standard i/o streams are used.\n\
- \tOptions (with defaults, numbers in plotter units):\n\
- \t\t/s - Fit full (-1,-1) to (1,1) square\n\
- \t\t (default is maximum magnification)\n\
- \t\t/x5450 - Center x coordinate\n\
- \t\t/y3825 - Center y coordinate\n\
- \t\t/w10000 - Maximum width\n\
- \t\t/h7200 - Maximum height\n\
- \t\t/p123456781234567 - Mapping colours to pens\n"
-
- #define ERROR(msg) {fputs(msg,stderr),exit(1);}
- #define PERROR(msg) {perror(msg),exit(1);}
-
- #define RECLEN 81
-
- void main(int argc, char* argv[])
- {
- int i, c, n, currpen = 0, pen[] = {0,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7};
- int cenx=5450, ceny=3825, width=5000, height=3600, square=0;
- /* HALF of width and height, actually */
- double x, y, xmin=-1, xmax=1, ymin=-1, ymax=1; /* if square */
- char comment[RECLEN + 1], *s;
- char options[] = "x:y:w:h:sp:";
- FILE *infile = stdin, *outfile = stdout;
-
-
- /* get options */
- while ((c = getopt(argc, argv, options)) != EOF)
- if (c == '?')
- ERROR(USAGE)
- else
- switch (c)
- { case 'x': cenx = atoi(optarg); break;
- case 'y': ceny = atoi(optarg); break;
- case 'w': width = atoi(optarg) / 2; break;
- case 'h': height = atoi(optarg) / 2; break;
- case 's': square = 1; break;
- case 'p':
- i = 0;
- while (isdigit(n = *(optarg + i)))
- pen[++i] = n;
- break;
- }
-
- /* open files */
- if (optind < argc - 2)
- ERROR(USAGE); /* too many */
- if (optind < argc)
- { infile = fopen(argv[optind], "rt");
- if (infile == NULL)
- ERROR("Can't open input file");
- if (++optind < argc)
- { outfile = fopen(argv[optind], "wt");
- if (outfile == NULL)
- ERROR("Can't open output file");
- }
- }
-
- /* get bounds, if necessary */
- if (!square)
- { fgets(comment, RECLEN, infile);
- s = strstr(comment, "x_range");
- if (s == NULL || sscanf(s, "x_range=[%lf:%lf]", &xmin, &xmax) != 2)
- ERROR("Bad or invalid x_range");
- s = strstr(comment, "y_range");
- if (s == NULL || sscanf(s, "y_range=[%lf:%lf]", &ymin, &ymax) != 2)
- ERROR("Bad or invalid y_range");
- }
-
- /* adjust aspect-ratio */
- if (height * (xmax - xmin) > width * (ymax - ymin))
- height = width * (ymax - ymin) / (xmax - xmin);
- else
- width = height * (xmax - xmin) / (ymax - ymin);
-
- /* set defaults, and plotter P1 and P2 */
- fprintf(outfile, "DF;\nIP %d,%d,%d,%d;\n",
- cenx - width, ceny - height, cenx + width, ceny + height);
-
- /* set scale */
- fprintf(outfile, "SC %.4f,%.4f,%.4f,%.4f;\n",
- 100 * xmin, 100 * xmax, 100 * ymin, 100 * ymax);
- /* (scale by 100 for better precision) */
-
- /* skip comments */
- while ((c = getc(infile)) == '#')
- fgets(comment, RECLEN, infile);
- if (ferror(infile))
- PERROR("Bad input");
- ungetc(c, outfile);
-
- /* do it */
- while (3 == fscanf(infile, "%lf %lf %d", &x, &y, &c))
- if (c == 0)
- /* move */
- fprintf(outfile, "PU %.4f,%.4f;\n", 100 * x, 100 * y);
- else
- { /* draw */
- if (currpen != pen[c])
- { /* new pen */
- currpen = pen[c];
- fprintf(outfile, "SP %d;\n", currpen);
- }
- fprintf(outfile, "PD %.4f,%.4f;\n", 100 * x, 100 * y);
- }
- fputs("PU;SP;", outfile); /* put pen away when finished */
-
- if (ferror(infile))
- PERROR("Error on input");
- fclose(infile);
-
- if (ferror(outfile))
- PERROR("Error on output");
- fclose(outfile);
- }