Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site ubc-vision.UUCP Path: utzoo!utcsri!ubc-vision!majka From: majka@ubc-vision.UUCP (Marc Majka) Newsgroups: net.sources Subject: Super Plot (4 of 8) Message-ID: <121@ubc-vision.UUCP> Date: Sun, 27-Apr-86 18:49:45 EDT Article-I.D.: ubc-visi.121 Posted: Sun Apr 27 18:49:45 1986 Date-Received: Mon, 28-Apr-86 04:02:01 EDT Organization: UBC Computational Vision Lab, Vancouver, B.C., Canada Lines: 865 - - - 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 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