Super Plot (4 of 8)
Marc Majka
majka at ubc-vision.UUCP
Mon Apr 28 08:49:45 AEST 1986
- - - CUT - - - CUT - - - CUT - - - CUT - - - CUT - - - CUT - - - CUT - - -
#!/bin/sh
#
# shell archive - extract with /bin/sh
#
echo Plot archive part 4 of 8
echo
echo extracting file plps.man
sed 's/^X//' > plps.man <<'!FUNKY!STUFF!'
XPLPS(1) UNIX Programmer's Manual PLPS(1)
X
XNAME
X plps - convert plot files to PostScript
X
XSYNOPSIS
X plps [plotfile] [-s] [-b] [-w r1 c1 r2 c2]
X
XDESCRIPTION
X plps converts a plot file into postcript language, which may
X then be printed on a LaserWriter. The conversion is fast,
X making use of many of PostScript's wonderful features.
X
X The following options are recognized:
X
X -s The image will be square. This option casues plps to
X use only the upper 8 1/2 inch square on the page.
X
X -b Prints all gray levels as black, supressing
X PostScript's halftoning.
X
X -w plots in a window with upper left corner (r1 c1) and
X lower right corner (r2 c2). At 300dpi, a normal page
X goes from (0 0) to (3300 2550), although a margin at
X the edges of the pages does not get inked.
X
XAUTHOR
X Marc Majka
!FUNKY!STUFF!
echo extracting file plpsfns.c
sed 's/^X//' > plpsfns.c <<'!FUNKY!STUFF!'
X/*************************************************************/
X/* */
X/* Copyright (c) 1986 */
X/* Marc S. Majka - UBC Laboratory for Computational Vision */
X/* */
X/* Permission is hereby granted to copy all or any part of */
X/* this program for free distribution. The author's name */
X/* and this copyright notice must be included in any copy. */
X/* */
X/*************************************************************/
X
X#include <stdio.h>
X#define MAXPATS 128
X#define FPMAX 32
X
Xstruct implstruct {
X double x1, y1, x2, y2; /* min and max points */
X double xr, yr; /* x and y range */
X double xc, yc; /* current point */
X int uhv; /* user space is hv */
X int ubpp; /* user bits per pixel */
X double ubppr; /* user bpp range */
X int gray; /* current gray level */
X int fpn; /* current fill pattern */
X int dot; /* current pen size */
X double r1, c1, r2, c2; /* max and min row and col */
X double rr, cr; /* row and col range */
X double rc, cc; /* current row and col */
X int dhv; /* frame hv */
X int fbpp; /* image bits per pixel */
X int fill, fstat; /* fill mode */
X};
Xstruct implstruct impl;
X
Xstruct fpstruct {
X char grid[FPMAX][FPMAX];
X int nr, nc;
X};
Xstruct fpstruct fpat[MAXPATS];
X
X#define FILLMAX 2048
Xstatic double fstack[FILLMAX][2];
Xstatic short knotn, knotk;
Xstatic int ftop;
X
XFILE *pfp;
X
Xmanfeed()
X{
X fprintf(pfp,"statusdict /manualfeed true put\n");
X}
X
Xlegal()
X{
X fprintf(pfp,"legal initmatrix\n");
X fprintf(pfp,"0.24 0.24 scale\n");
X fprintf(pfp,"0 900 translate\n");
X}
X
X/************************************************************************/
X/* plotopen: open file for output, initialize plot structure */
X/************************************************************************/
X
Xplotopen(fname)
Xchar *fname;
X{
X FILE *fopen();
X
X if (fname == 0 || fname[0] == '\0') pfp = stdout;
X else pfp = fopen(fname);
X if (pfp == NULL) {
X fprintf(stderr,"plotopen: can't write to ps file: %s\n",fname);
X exit(1);
X }
X
X prologue();
X
X space(100,3200,2500,100,1);
X frame(100,3200,2500,100,1);
X bppin(8);
X bppout(1);
X gray(255);
X linemod("1");
X fillpat(0,1,8,"1");
X font("sr");
X fspec(1.0,1.0,0.0);
X impl.fill = 0;
X impl.fstat = 0;
X
X}
X
X/************************************************************************/
X/* frame: specify frame buffer coordinate system */
X/************************************************************************/
X
Xframe(x1,y1,x2,y2,hv)
Xshort x1,y1,x2,y2,hv;
X{
X impl.r1 = x1; impl.c1 = y1;
X impl.r2 = x2; impl.c2 = y2;
X impl.dhv = hv;
X impl.rr = x2 - x1; impl.cr = y2 - y1;
X}
X
Xhvmatch()
X{
X if (impl.uhv = impl.dhv) return(1);
X return(0);
X}
X
X/************************************************************************/
X/* bppout: set number of bits per pixel for output */
X/************************************************************************/
X
Xbppout(b)
Xshort b;
X{
X if (b) impl.fbpp = 1;
X else impl.fbpp = 0;
X}
X
X/************************************************************************/
X/* bppin: set number of bits per pixel for input */
X/************************************************************************/
X
Xbppin(b)
Xshort b;
X{
X impl.ubpp = b;
X impl.ubppr = (1 << b) - 1;
X}
X
X/************************************************************************/
X/* plotclose: end it all */
X/************************************************************************/
X
Xplotclose()
X{
X epilogue();
X fclose(pfp);
X}
X
X/************************************************************************/
X/* space: define user coordinate system */
X/************************************************************************/
X
Xspace(x1,y1,x2,y2,hv)
Xshort x1, y1, x2, y2, hv;
X{
X impl.x1 = x1; impl.y1 = y1;
X impl.x2 = x2; impl.y2 = y2;
X impl.xr = x2 - x1;
X impl.yr = y2 - y1;
X impl.uhv = hv;
X}
X
X/************************************************************************/
X/* erase: reset frame buffer */
X/************************************************************************/
X
Xerase()
X{
X fprintf(pfp,"showpage\n");
X}
X
X/************************************************************************/
X/* move: change the current point to (x, y). */
X/************************************************************************/
X
Xmove(x,y)
Xshort x, y;
X{
X impl.xc = x; impl.yc = y;
X dblmove();
X}
X
Xdblmove()
X{
X scale(impl.xc,impl.yc);
X
X if ((impl.fill) && (impl.fstat)) {
X fstack[ftop][0] = impl.rc;
X fstack[ftop][1] = impl.cc;
X ftop++;
X impl.fstat = 0;
X }
X PSmoveto(impl.rc,impl.cc);
X}
X
X/************************************************************************/
X/* scale: convert user coordinates to frame coordinates */
X/************************************************************************/
X
Xscale(x,y)
Xdouble x,y;
X{
X if (impl.uhv != impl.dhv) {
X impl.cc = impl.c1 + (x - impl.x1) * (impl.cr / impl.xr);
X impl.rc = impl.r1 + (y - impl.y1) * (impl.rr / impl.yr);
X }
X else {
X impl.rc = impl.r1 + (x - impl.x1) * (impl.rr / impl.xr);
X impl.cc = impl.c1 + (y - impl.y1) * (impl.cr / impl.yr);
X }
X}
X
X/************************************************************************/
X/* point: plot a point */
X/************************************************************************/
X
Xpoint(x,y)
Xshort x, y;
X{
X scale((double)x,(double)y);
X
X PSpoint(impl.rc,impl.cc);
X PSstroke();
X}
X
X/************************************************************************/
X/* cont: line generator. Draws a line from current point to (x, y) */
X/* uses the line mask to decide when to set pixels. */
X/************************************************************************/
X
Xcont(x,y)
Xshort x, y;
X{
X double r1, c1, r2, c2;
X
X r1 = impl.rc; c1 = impl.cc;
X scale((double)x,(double)y);
X r2 = impl.rc; c2 = impl.cc;
X imdraw(r1,c1,r2,c2);
X PSstroke();
X}
X
Ximdraw(r1,c1,r2,c2)
Xdouble r1,c1,r2,c2;
X{
X double rinc, cinc, length, tlen, r, c, fabs();
X int i, state;
X
X /* if the this line is part of a polygon, stack the point for later fill */
X if (impl.fill) {
X fstack[ftop][0] = r2;
X fstack[ftop][1] = c2;
X ftop++;
X if (ftop >= FILLMAX) {
X fprintf(stderr,"plvfs: fill stack overflow\n");
X exit(1);
X }
X }
X
X PSlineto(r2,c2);
X}
X
X/************************************************************************/
X/* line: draw a line */
X/************************************************************************/
X
Xline(x1,y1,x2,y2)
Xshort x1, y1, x2, y2;
X{
X move(x1,y1);
X cont(x2,y2);
X}
X
X/************************************************************************/
X/* polygon: filled polygon */
X/************************************************************************/
X
Xpolygon(n,v)
Xshort n, *v;
X{
X int i, p;
X double x, y;
X
X ftop = n;
X p = 0;
X
X for (i = 0; i < n; i++) {
X x = v[p++]; y = v[p++];
X scale(x,y);
X fstack[i][0] = impl.rc;
X fstack[i][1] = impl.cc;
X }
X
X drawpolygon(ftop,fstack);
X}
X
Xdrawpolygon(top,stack)
Xshort top;
Xdouble *stack;
X{
X short p, i;
X double x,y;
X
X p = impl.fpn;
X
X fprintf(pfp,"gsave\n");
X fprintf(pfp,"pat%d %d %d 300 32 div setpattern\n",
X p,fpat[p].nr,fpat[p].nc / 8);
X
X p = 0;
X x = stack[p++]; y = stack[p++];
X PSmoveto(x,y);
X for (i = 1; i < top; i++) {
X x = stack[p++];
X y = stack[p++];
X PSlineto(x,y);
X }
X
X PSfill();
X fprintf(pfp,"grestore\n");
X}
X
X/************************************************************************/
X/* bspline: order k spline from Newmann & Sproull */
X/************************************************************************/
X
Xbspline(k,n,v)
Xshort k,n,*v;
X{
X double u, du, ufin, x, y, x0,y0;
X short nn;
X
X nn = n - 1;
X ufin = (double)(nn - k + 2);
X du = ufin / (500.0 + (double)nn);
X
X u = 0.0;
X Bpoint(&x,&y,0.0,nn,k,v);
X scale(x,y);
X PSmoveto(impl.rc,impl.cc);
X x0 = impl.rc, y0 = impl.cc;
X
X while (u <= ufin) {
X u = u + du;
X Bpoint(&x,&y,u,n,k,v);
X scale(x,y);
X imdraw(impl.rc,impl.cc,x0,y0);
X x0 = impl.rc, y0 = impl.cc;
X }
X x = v[nn*2];
X y = v[nn*2 + 1];
X scale(x,y);
X imdraw(impl.rc,impl.cc,x0,y0);
X PSstroke();
X}
X
XBpoint(x,y,u,n,k,v)
Xdouble *x,*y,u;
Xint n,k;
Xshort *v;
X{
X int i, m;
X double b, Bnblend();
X
X *x = 0.0; *y = 0.0;
X m = 0;
X knotk = k;
X knotn = n;
X
X for (i = 0; i <= n; i++) {
X b = Bnblend(i,k,u);
X *x = *x + (double)(v[m]) * b;
X *y = *y + (double)(v[m+1]) * b;
X m += 2;
X }
X}
X
XBknot(i)
Xint i;
X{
X if (i < knotk) return(0);
X else if (i > knotn) return(knotn - knotk + 2);
X else return(i - knotk + 1);
X}
X
Xdouble Bnblend(i,k,u)
Xint i,k;
Xdouble u;
X{
X double v, v1, v2, t1, t2, abs();
X
X v1 = 0.0; v2 = 0.0; t1 = 0.0; t2 = 0.0;
X
X if (k == 1) {
X if ((Bknot(i) <= u) && (u < Bknot(i+1))) v = 1.0;
X else v = 0.0;
X }
X else {
X t1 = Bknot(i+k-1) - Bknot(i);
X if (t1 != 0) v1 = (u - Bknot(i)) * Bnblend(i,k-1,u) / t1;
X
X t2 = Bknot(i+k) - Bknot(i+1);
X if (t2 != 0) v2 = (Bknot(i+k) - u) * Bnblend(i+1,k-1,u) / t2;
X
X v = v1 + v2;
X }
X return(v);
X}
X
X/************************************************************************/
X/* chain: polyline */
X/************************************************************************/
X
Xchain(n,v)
Xshort n, *v;
X{
X int i, p;
X short x, y;
X double r1,c1,r2,c2;
X
X p = 0;
X x = v[p++]; y = v[p++];
X move(x,y);
X r1 = impl.rc; c1 = impl.cc;
X
X for (i = 1; i < n; i++) {
X x = v[p++]; y = v[p++];
X scale((double)x,(double)y);
X r2 = impl.rc; c2 = impl.cc;
X imdraw(r1,c1,r2,c2);
X r1 = r2; c1 = c2;
X }
X PSstroke();
X}
X
X/************************************************************************/
X/* moverel: relative move */
X/************************************************************************/
X
Xmoverel(x,y)
Xshort x, y;
X{
X impl.xc += (double)x; impl.yc += (double)y;
X dblmove(impl.xc,impl.yc);
X}
X
Xdblmoverel(x,y)
Xdouble x, y;
X{
X impl.xc += x; impl.yc += y;
X dblmove(impl.xc,impl.yc);
X}
X
X/************************************************************************/
X/* contrel: relative cont */
X/************************************************************************/
X
Xcontrel(x,y)
Xshort x, y;
X{
X double r1, c1, r2, c2;
X
X r1 = impl.rc; c1 = impl.cc;
X impl.xc += (double)x; impl.yc += (double)y;
X scale(impl.xc,impl.yc);
X r2 = impl.rc; c2 = impl.cc;
X imdraw(r1,c1,r2,c2);
X PSstroke();
X}
X
Xdblcontrel(x,y)
Xdouble x, y;
X{
X double r1, c1, r2, c2;
X
X r1 = impl.rc; c1 = impl.cc;
X impl.xc += x; impl.yc += y;
X scale(impl.xc,impl.yc);
X r2 = impl.rc; c2 = impl.cc;
X imdraw(r1,c1,r2,c2);
X}
X
X/************************************************************************/
X/* gray: set the current gray level */
X/************************************************************************/
X
Xgray(g)
Xshort g;
X{
X double og;
X if (impl.fbpp) {
X og = (255.0 - (double)g) / 255.0;
X fprintf(pfp,"%.2f setgray\n",og);
X }
X else if (g) fprintf(pfp,"0 setgray\n");
X else fprintf(pfp,"1 setgray\n");
X}
X
X/************************************************************************/
X/* colour: set the current colour */
X/************************************************************************/
X
Xcolour(r,g,b)
Xshort r,g,b;
X{
X double og;
X
X if (impl.fbpp) {
X og = (765.0 - (double)(r+g+b)) / 765.0;
X fprintf(pfp,"%.2f setgray\n",og);
X }
X else if (r+g+b) fprintf(pfp,"0 setgray\n");
X else fprintf(pfp,"1 setgray\n");
X}
X
X/************************************************************************/
X/* pensize: set the pen size */
X/************************************************************************/
X
Xpensize(p)
Xshort p;
X{
X impl.dot = p;
X PSsetlinewidth(p);
X}
X
X/************************************************************************/
X/* linemod: change the line generator mask */
X/* this mask should be a string of 1s and 0s. The line */
X/* generator (imcont) will set the pixels under a "1". */
X/************************************************************************/
X
Xlinemod(str)
Xchar *str;
X{
X int l,p,s,nz;
X
X nz = 1;
X s = 1;
X l = 0;
X
X fprintf(pfp,"[");
X for (p = 0; str[p] != '\0'; p++) {
X if (s) {
X if (str[p] == '1') l++;
X else {
X fprintf(pfp,"%d ",l);
X l = 1;
X s = 0;
X nz = 0;
X }
X }
X else {
X if (str[p] != '1') l++;
X else {
X fprintf(pfp,"%d ",l);
X l = 1;
X s = 1;
X }
X }
X }
X if (nz) fprintf(pfp,"]");
X else if (s) fprintf(pfp,"%d 0]",l);
X else fprintf(pfp,"%d]",l);
X
X fprintf(pfp," 0 setdash\n",l);
X}
X
X/************************************************************************/
X/* startp: start filled polygon */
X/************************************************************************/
X
Xstartp()
X{
X impl.fill = 1;
X impl.fstat = 1;
X ftop = 0;
X}
X
X/************************************************************************/
X/* endp: end filled polygon */
X/************************************************************************/
X
Xendp()
X{
X drawpolygon(ftop,fstack);
X impl.fill = 0;
X ftop = 0;
X}
X
X/************************************************************************/
X/* arc: draw an arc from x1 y1 to x2 y2, with center at xc xy */
X/************************************************************************/
X
Xarc(xc,yc,x1,y1,x2,y2)
Xshort xc,yc,x1,y1,x2,y2;
X{
X double a1, a2, rad, pi, hypot(), acos();
X double r1, c1, r2, c2, rr, rc;
X
X pi = acos(-1.0);
X
X rad = hypot((double)(x1-xc),(double)(y1-yc));
X
X /* find the angles a1 and a2 */
X
X if (y1 >= yc) a1 = acos((x1-xc)/rad);
X else a1 = pi + acos((xc-x1)/rad);
X
X if (y2 >= yc) a2 = acos((x2-xc)/rad);
X else a2 = pi + acos((xc-x2)/rad);
X
X scale((double)xc,(double)yc);
X r1 = impl.rc; c1 = impl.cc;
X scale((double)xc+rad,(double)yc+rad);
X r2 = impl.rc; c2 = impl.cc;
X
X rr = r2 - r1; rc = c2 - c1;
X
X if (rr < 0) rr *= -1.0;
X if (rc < 0) rc *= -1.0;
X
X fprintf(pfp,"newpath %.2f %.2f %.2f %.2f %.2f %.2f ellipse\n",
X c1,r1,rc,rr,a1,a2);
X PSstroke();
X}
X
X/************************************************************************/
X/* circle: simple incremental circle generator */
X/************************************************************************/
X
Xcircle(x1,y1,r)
Xshort x1,y1,r;
X{
X arc(x1,y1,x1-r,y1,x1+r,y1);
X arc(x1,y1,x1+r,y1,x1-r,y1);
X}
X
X/************************************************************************/
X/* fillpat: set fill pattern */
X/************************************************************************/
X
Xfillpat(n,r,c,str)
Xshort n, r, c;
Xchar *str;
X{
X int pr, pc, p, pat[32][32], nbyte, byte;
X unsigned int bval;
X
X if (c % 8) {
X fprintf(stderr,"fillpat %d %d %c: ncols must be a multiple of 8\n",
X n,r,c);
X return(0);
X }
X
X fpat[n].nr = r;
X fpat[n].nc = c;
X p = 0;
X
X for (pr = 0; pr < r; pr++)
X for (pc = 0; pc < c; pc++) {
X if (str[p++] == '1') fpat[n].grid[pr][pc] = 1;
X else fpat[n].grid[pr][pc] = 0;
X if (str[p] == '\0') p = 0;
X }
X
X fprintf(pfp,"/pat%d <",n);
X
X p = 0;
X nbyte = r * c / 8;
X
X for (byte = 0; byte < nbyte; byte++) {
X bval = 0;
X for (pc = 7; pc >= 0; pc--) {
X if (str[p++] == '1') bval |= 1 << pc;
X if (str[p] == '\0') p = 0;
X }
X if (bval < 16) fprintf(pfp,"0");
X fprintf(pfp,"%x",bval);
X }
X fprintf(pfp,"> def\n",n);
X
X setpat(n);
X}
X
X/************************************************************************/
X/* setpat: set texture */
X/************************************************************************/
X
Xsetpat(p)
Xshort p;
X{
X impl.fpn = p;
X}
X
X/************************************************************************/
X/* area: fill area from seed point - boundary is non-current value */
X/************************************************************************/
X
Xarea(x,y)
Xshort x, y;
X{
X/* AREA NOT IMPLEMENTED */
X}
X
Xcomment(str)
Xchar *str;
X{
X PScomment(str);
X}
X
Xdonelabel()
X{
X PSstroke();
X}
X
XPSerasepage()
X{
X fprintf(pfp,"erasepage\n");
X}
X
XPSmoveto(x,y)
Xdouble x,y;
X{
X fprintf(pfp,"%.2f %.2f moveto\n",x,y);
X}
X
XPSpoint(x,y)
Xdouble x,y;
X{
X fprintf(pfp,"%.2f %.2f point\n",x,y);
X}
X
XPSlineto(x,y)
Xdouble x,y;
X{
X fprintf(pfp,"%.2f %.2f lineto\n",x,y);
X}
X
XPSstroke()
X{
X fprintf(pfp,"stroke\n");
X fprintf(pfp,"%.2f %.2f moveto\n",impl.rc,impl.cc);
X}
X
XPSfill()
X{
X fprintf(pfp,"fill\n");
X fprintf(pfp,"%.2f %.2f moveto\n",impl.rc,impl.cc);
X}
X
XPSsetlinewidth(w)
Xshort w;
X{
X fprintf(pfp,"%d setlinewidth\n",w);
X}
X
XPScomment(str)
Xchar *str;
X{
X fprintf(pfp,"%% %s\n",str);
X}
X
Xprologue()
X{
X fprintf(pfp,"gsave\n");
X fprintf(pfp,"initgraphics\n");
X fprintf(pfp,"0.24 0.24 scale\n");
X fprintf(pfp,"/mtrx matrix def\n");
X fprintf(pfp,"/bitison {\n");
X fprintf(pfp," /ybit exch def\n");
X fprintf(pfp," /xbit exch def\n");
X fprintf(pfp," bstring ybit bwidth mul xbit 8 idiv add get\n");
X fprintf(pfp," 1 7 xbit 8 mod sub bitshift and 0 ne\n");
X fprintf(pfp,"} def\n");
X fprintf(pfp,"/setpattern {\n");
X fprintf(pfp," /freq exch def\n");
X fprintf(pfp," /bwidth exch def\n");
X fprintf(pfp," /bpside exch def\n");
X fprintf(pfp," /bstring exch def\n");
X fprintf(pfp," /onbits 0 def\n");
X fprintf(pfp," /offbits 0 def\n");
X fprintf(pfp," freq 0\n");
X fprintf(pfp," {\n");
X fprintf(pfp," /y exch def\n");
X fprintf(pfp," /x exch def\n");
X fprintf(pfp," /xindex x 1 add 2 div bpside mul cvi def\n");
X fprintf(pfp," /yindex y 1 add 2 div bpside mul cvi def\n");
X fprintf(pfp," xindex yindex bitison\n");
X fprintf(pfp," {/onbits onbits 1 add def 1}\n");
X fprintf(pfp," {/offbits offbits 1 add def 0}\n");
X fprintf(pfp," ifelse\n");
X fprintf(pfp," } setscreen\n");
X fprintf(pfp," {} settransfer\n");
X fprintf(pfp," offbits offbits onbits add div setgray\n");
X fprintf(pfp,"} def\n");
X fprintf(pfp,"/point {\n");
X fprintf(pfp," /x exch def\n");
X fprintf(pfp," /y exch def\n");
X fprintf(pfp," y x moveto\n");
X fprintf(pfp," y 0.01 add x lineto\n");
X fprintf(pfp,"} def\n");
X fprintf(pfp,"/ellipse {\n");
X fprintf(pfp," /a2 exch def\n");
X fprintf(pfp," /a1 exch def\n");
X fprintf(pfp," /rx exch def\n");
X fprintf(pfp," /ry exch def\n");
X fprintf(pfp," /xc exch def\n");
X fprintf(pfp," /yc exch def\n");
X fprintf(pfp," /savematrix mtrx currentmatrix def\n");
X fprintf(pfp," xc yc translate\n");
X fprintf(pfp," rx ry scale\n");
X fprintf(pfp," 0 0 1 a1 a2 arc\n");
X fprintf(pfp," savematrix setmatrix\n");
X fprintf(pfp,"} def\n");
X fprintf(pfp,"1 setlinewidth\n");
X fprintf(pfp,"1 setlinecap\n");
X fprintf(pfp,"1 setlinejoin\n");
X}
X
Xepilogue()
X{
X fprintf(pfp,"stroke\n");
X fprintf(pfp,"showpage\n");
X fprintf(pfp,"grestore\n");
X fprintf(pfp,"end\n");
X}
!FUNKY!STUFF!
echo
echo finished part 4 of 8
More information about the Comp.sources.unix
mailing list