| #include <math.h> |
| #include <stdio.h> |
| #include "tex.h" |
| |
| void |
| devarc(double x1, double y1, double x2, double y2, double xc, double yc, int r) |
| { |
| double t, start, stop; |
| int rad; |
| |
| /* tpic arcs go clockwise, and angles are measured clockwise */ |
| start = atan2(y2-yc, x2-xc); |
| stop = atan2(y1-yc, x1-xc); |
| if (r<0) { |
| t = start; start = stop; stop = t; |
| } |
| rad = SCX(sqrt((x1-xc)*(x1-xc)+(y1-yc)*(y1-yc))); |
| fprintf(TEXFILE, " \\special{ar %d %d %d %d %6.3f %6.3f}%%\n", |
| TRX(xc), TRY(yc), rad, rad, -start, -stop); |
| } |
| |
| void |
| box(double x0, double y0, double x1, double y1) |
| { |
| fprintf(TEXFILE," \\special{pa %d %d}",TRX(x0),TRY(y0)); |
| fprintf(TEXFILE,"\\special{pa %d %d}",TRX(x1),TRY(y0)); |
| fprintf(TEXFILE,"\\special{pa %d %d}",TRX(x1),TRY(y1)); |
| fprintf(TEXFILE,"\\special{pa %d %d}",TRX(x0),TRY(y1)); |
| fprintf(TEXFILE,"\\special{pa %d %d}",TRX(x0),TRY(y0)); |
| switch(e1->pen){ |
| case DASHPEN: |
| fprintf(TEXFILE,"\\special{da %6.3f}%%\n", e1->dashlen); break; |
| case DOTPEN: |
| fprintf(TEXFILE,"\\special{dt %6.3f}%%\n", e1->dashlen); break; |
| case SOLIDPEN: |
| default: |
| fprintf(TEXFILE,"\\special{fp}%%\n"); break; |
| } |
| } |
| |
| void |
| circle(double xc, double yc, double r) |
| { |
| int rad = SCX(r); |
| |
| fprintf(TEXFILE, " \\special{ar %d %d %d %d 0.0 6.2832}%%\n", |
| TRX(xc), TRY(yc), rad, rad); |
| } |
| |
| void |
| closepl(void) |
| { |
| fprintf(TEXFILE, " \\kern %6.3fin\n }\\vss}%%\n", INCHES(e1->sidex)); |
| fprintf(TEXFILE, " \\kern %6.3fin\n}\n", INCHES(e1->sidey)); |
| } |
| |
| void |
| disc(double xc, double yc, double r) |
| { |
| fprintf(TEXFILE, " \\special{bk}%%\n"); |
| circle(xc, yc, r); |
| } |
| |
| void |
| erase(void) |
| { |
| } |
| |
| void |
| fill(int num[], double *ff[]) |
| { |
| double *xp, *yp, **fp, x0, y0; |
| int i, *n; |
| n = num; |
| fp = ff; |
| while((i = *n++)){ |
| xp = *fp++; |
| yp = xp+1; |
| x0 = *xp; |
| y0 = *yp; |
| move(x0, y0); |
| while(--i){ |
| xp += 2; |
| yp += 2; |
| vec(*xp, *yp); |
| } |
| if (*(xp-2) != x0 || *(yp-2) != y0) |
| vec(x0, y0); |
| } |
| } |
| |
| void |
| frame(double xs, double ys, double xf, double yf) |
| { |
| double osidex, osidey; |
| osidex = e1->sidex; |
| osidey = e1->sidey; |
| e1->left = xs * (e0->left + e0->sidex); |
| e1->bottom = ys* (e0->bottom + e0->sidey); |
| e1->sidex = (xf-xs) * e0->sidex; |
| e1->sidey = (yf-ys) * e0->sidey; |
| e1->scalex *= (e1->sidex / osidex); |
| e1->scaley *= (e1->sidey / osidey); |
| } |
| |
| void |
| line(double x0, double y0, double x1, double y1) |
| { |
| move(x0, y0); |
| vec(x1, y1); |
| } |
| |
| void |
| move(double xx, double yy) |
| { |
| e1->copyx = xx; |
| e1->copyy = yy; |
| } |
| |
| extern double xmin, ymin, xmax, ymax; |
| |
| /* tpic TeX coord system uses millinches, printer's points for pensize */ |
| /* positive y downward, origin at upper left */ |
| |
| #define pHEIGHT 5000. |
| #define pWIDTH 5000. |
| #define pPENSIZE 9 |
| #define pPSIZE 10 |
| #define pDLEN .05 |
| struct penvir E[2] = { |
| {0.,pHEIGHT,0.,0.,1.,-1.,pWIDTH,pHEIGHT,0.,0.,0,pPSIZE,SOLIDPEN,pPENSIZE,pDLEN}, |
| {0.,pHEIGHT,0.,0.,1.,-1.,pWIDTH,pHEIGHT,0.,0.,0,pPSIZE,SOLIDPEN,pPENSIZE,pDLEN} |
| }; |
| struct penvir *e0 = E, *e1 = &E[1]; |
| FILE *TEXFILE; |
| |
| void |
| openpl(void) |
| { |
| TEXFILE = stdout; |
| |
| space(xmin, ymin, xmax, ymax); |
| fprintf(TEXFILE,"\\catcode`@=11\n"); |
| fprintf(TEXFILE, "\\expandafter\\ifx\\csname graph\\endcsname\\relax"); |
| fprintf(TEXFILE, " \\alloc@4\\box\\chardef\\insc@unt\\graph\\fi\n"); |
| fprintf(TEXFILE, "\\catcode`@=12\n"); |
| fprintf(TEXFILE, "\\setbox\\graph=\\vtop{%%\n"); |
| fprintf(TEXFILE, " \\baselineskip=0pt \\lineskip=0pt "); |
| fprintf(TEXFILE, "\\lineskiplimit=0pt\n"); |
| fprintf(TEXFILE, " \\vbox to0pt{\\hbox{%%\n"); |
| fprintf(TEXFILE, " \\special{pn %d}%%\n", e1->pdiam); |
| } |
| |
| void |
| range(double x0, double y0, double x1, double y1) |
| { |
| e1->xmin = x0; |
| e1->ymin = y0; |
| if (x1-x0 < .0000001*e1->sidex) |
| x1=x0+.0000001; |
| if (y1-y0 < .0000001*e1->sidey) |
| y1=y0+.0000001; |
| e1->scalex = e0->scalex*e1->sidex / (x1 - x0); |
| e1->scaley = e0->scaley*e1->sidey / (y1 - y0); |
| } |
| |
| void |
| rmove(double xx, double yy) |
| { |
| e1->copyx += xx; |
| e1->copyy += yy; |
| } |
| |
| void |
| rvec(double xx, double yy) |
| { |
| vec(xx+e1->copyx, yy+e1->copyy); |
| } |
| |
| void |
| sbox(double x0, double y0, double x1, double y1) |
| { |
| fprintf(TEXFILE," \\special{bk}%%\n"); |
| box(x0, y0, x1, y1); |
| } |
| |
| void |
| vec(double xx, double yy) |
| { |
| fprintf(TEXFILE," \\special{pa %d %d}",TRX(e1->copyx),TRY(e1->copyy)); |
| e1->copyx = xx; |
| e1->copyy = yy; |
| fprintf(TEXFILE,"\\special{pa %d %d}",TRX(xx),TRY(yy)); |
| switch(e1->pen){ |
| case DASHPEN: |
| fprintf(TEXFILE,"\\special{da %6.3f}%%\n", e1->dashlen); break; |
| case DOTPEN: |
| fprintf(TEXFILE,"\\special{dt %6.3f}%%\n", e1->dashlen); break; |
| case SOLIDPEN: |
| default: |
| fprintf(TEXFILE,"\\special{fp}%%\n"); break; |
| } |
| } |