Add graph, plot
This commit is contained in:
parent
6e18e03e63
commit
4314729dde
44 changed files with 2307 additions and 0 deletions
8
src/cmd/plot/libplot/box.c
Normal file
8
src/cmd/plot/libplot/box.c
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include "mplot.h"
|
||||
void box(double x0, double y0, double x1, double y1){
|
||||
move(x0, y0);
|
||||
vec(x0, y1);
|
||||
vec(x1, y1);
|
||||
vec(x1, y0);
|
||||
vec(x0, y0);
|
||||
}
|
||||
5
src/cmd/plot/libplot/cfill.c
Normal file
5
src/cmd/plot/libplot/cfill.c
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include "mplot.h"
|
||||
void cfill(char *s){
|
||||
int k=bcolor(s);
|
||||
if(k>=0) e1->backgr=k;
|
||||
}
|
||||
12
src/cmd/plot/libplot/circ.c
Normal file
12
src/cmd/plot/libplot/circ.c
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include "mplot.h"
|
||||
void circ(double xc, double yc, double r){
|
||||
Point p;
|
||||
int rad;
|
||||
p.x=SCX(xc);
|
||||
p.y=SCY(yc);
|
||||
if (r < 0)
|
||||
rad=SCR(-r);
|
||||
else
|
||||
rad=SCR(r);
|
||||
ellipse(screen, p, rad, rad, 0, getcolor(e1->foregr), ZP);
|
||||
}
|
||||
4
src/cmd/plot/libplot/closepl.c
Normal file
4
src/cmd/plot/libplot/closepl.c
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#include "mplot.h"
|
||||
void closepl(void){
|
||||
m_finish();
|
||||
}
|
||||
4
src/cmd/plot/libplot/color.c
Normal file
4
src/cmd/plot/libplot/color.c
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#include "mplot.h"
|
||||
void color(char *s){
|
||||
e1->foregr=bcolor(s);
|
||||
}
|
||||
12
src/cmd/plot/libplot/disk.c
Normal file
12
src/cmd/plot/libplot/disk.c
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include "mplot.h"
|
||||
void plotdisc(double xc, double yc, double r){
|
||||
Point p;
|
||||
int rad;
|
||||
p.x=SCX(xc);
|
||||
p.y=SCY(yc);
|
||||
if (r < 0)
|
||||
rad=SCR(-r);
|
||||
else
|
||||
rad=SCR(r);
|
||||
fillellipse(screen, p, rad, rad, getcolor(e1->foregr), ZP);
|
||||
}
|
||||
4
src/cmd/plot/libplot/doublebuffer.c
Normal file
4
src/cmd/plot/libplot/doublebuffer.c
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#include "mplot.h"
|
||||
void doublebuffer(void){
|
||||
m_dblbuf();
|
||||
}
|
||||
6
src/cmd/plot/libplot/dpoint.c
Normal file
6
src/cmd/plot/libplot/dpoint.c
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include "mplot.h"
|
||||
void dpoint(double x, double y){
|
||||
draw(screen, Rect(SCX(x), SCY(y), SCX(x)+1, SCY(y)+1), getcolor(e1->foregr),
|
||||
nil, ZP);
|
||||
move(x, y);
|
||||
}
|
||||
5
src/cmd/plot/libplot/erase.c
Normal file
5
src/cmd/plot/libplot/erase.c
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include "mplot.h"
|
||||
void erase(void){
|
||||
m_swapbuf();
|
||||
m_clrwin(clipminx, clipminy, clipmaxx, clipmaxy, e1->backgr);
|
||||
}
|
||||
167
src/cmd/plot/libplot/fill.c
Normal file
167
src/cmd/plot/libplot/fill.c
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* fill -- polygon tiler
|
||||
* Updating the edgelist from scanline to scanline could be quicker if no
|
||||
* edges cross: we can just merge the incoming edges. If the scan-line
|
||||
* filling routine were a parameter, we could do textured
|
||||
* polygons, polyblt, and other such stuff.
|
||||
*/
|
||||
#include "mplot.h"
|
||||
typedef enum{
|
||||
Odd=1,
|
||||
Nonzero=~0
|
||||
}Windrule;
|
||||
typedef struct edge Edge;
|
||||
struct edge{
|
||||
Point p; /* point of crossing current scan-line */
|
||||
int maxy; /* scan line at which to discard edge */
|
||||
int dx; /* x increment if x fraction<1 */
|
||||
int dx1; /* x increment if x fraction>=1 */
|
||||
int x; /* x fraction, scaled by den */
|
||||
int num; /* x fraction increment for unit y change, scaled by den */
|
||||
int den; /* x fraction increment for unit x change, scaled by num */
|
||||
int dwind; /* increment of winding number on passing this edge */
|
||||
Edge *next; /* next edge on current scanline */
|
||||
Edge *prev; /* previous edge on current scanline */
|
||||
};
|
||||
static void insert(Edge *ep, Edge **yp){
|
||||
while(*yp && (*yp)->p.x<ep->p.x) yp=&(*yp)->next;
|
||||
ep->next=*yp;
|
||||
*yp=ep;
|
||||
if(ep->next){
|
||||
ep->prev=ep->next->prev;
|
||||
ep->next->prev=ep;
|
||||
if(ep->prev)
|
||||
ep->prev->next=ep;
|
||||
}
|
||||
else
|
||||
ep->prev=0;
|
||||
}
|
||||
static void polygon(int cnt[], double *pts[], Windrule w, int v){
|
||||
Edge *edges, *ep, *nextep, **ylist, **eylist, **yp;
|
||||
Point p, q, p0, p1, p10;
|
||||
int i, dy, nbig, y, left, right, wind, nwind, nvert;
|
||||
int *cntp;
|
||||
double **ptsp, *xp;
|
||||
nvert=0;
|
||||
for(cntp=cnt;*cntp;cntp++) nvert+=*cntp;
|
||||
edges=(Edge *)malloc(nvert*sizeof(Edge));
|
||||
if(edges==0){
|
||||
NoSpace:
|
||||
fprintf(stderr, "polygon: no space\n");
|
||||
exits("malloc failed");
|
||||
}
|
||||
ylist=(Edge **)malloc(Dy(screen->r)*sizeof(Edge *));
|
||||
if(ylist==0) goto NoSpace;
|
||||
eylist=ylist+Dy(screen->r);
|
||||
for(yp=ylist;yp!=eylist;yp++) *yp=0;
|
||||
ep=edges;
|
||||
for(cntp=cnt,ptsp=pts;*cntp;cntp++,ptsp++){
|
||||
p.x=SCX((*ptsp)[*cntp*2-2]);
|
||||
p.y=SCY((*ptsp)[*cntp*2-1]);
|
||||
nvert=*cntp;
|
||||
for(xp=*ptsp,i=0;i!=nvert;xp+=2,i++){
|
||||
q=p;
|
||||
p.x=SCX(xp[0]);
|
||||
p.y=SCY(xp[1]);
|
||||
if(p.y==q.y) continue;
|
||||
if(p.y<q.y){
|
||||
p0=p;
|
||||
p1=q;
|
||||
ep->dwind=1;
|
||||
}
|
||||
else{
|
||||
p0=q;
|
||||
p1=p;
|
||||
ep->dwind=-1;
|
||||
}
|
||||
if(p1.y<=screen->r.min.y) continue;
|
||||
if(p0.y>=screen->r.max.y) continue;
|
||||
ep->p=p0;
|
||||
if(p1.y>screen->r.max.y)
|
||||
ep->maxy=screen->r.max.y;
|
||||
else
|
||||
ep->maxy=p1.y;
|
||||
p10=subpt(p1, p0);
|
||||
if(p10.x>=0){
|
||||
ep->dx=p10.x/p10.y;
|
||||
ep->dx1=ep->dx+1;
|
||||
}
|
||||
else{
|
||||
p10.x=-p10.x;
|
||||
ep->dx=-(p10.x/p10.y); /* this nonsense rounds toward zero */
|
||||
ep->dx1=ep->dx-1;
|
||||
}
|
||||
ep->x=0;
|
||||
ep->num=p10.x%p10.y;
|
||||
ep->den=p10.y;
|
||||
if(ep->p.y<screen->r.min.y){
|
||||
dy=screen->r.min.y-ep->p.y;
|
||||
ep->x+=dy*ep->num;
|
||||
nbig=ep->x/ep->den;
|
||||
ep->p.x+=ep->dx1*nbig+ep->dx*(dy-nbig);
|
||||
ep->x%=ep->den;
|
||||
ep->p.y=screen->r.min.y;
|
||||
}
|
||||
insert(ep, ylist+(ep->p.y-screen->r.min.y));
|
||||
ep++;
|
||||
}
|
||||
}
|
||||
left = 0;
|
||||
for(yp=ylist,y=screen->r.min.y;yp!=eylist;yp++,y++){
|
||||
wind=0;
|
||||
for(ep=*yp;ep;ep=nextep){
|
||||
nwind=wind+ep->dwind;
|
||||
if(nwind&w){ /* inside */
|
||||
if(!(wind&w)){
|
||||
left=ep->p.x;
|
||||
if(left<screen->r.min.x) left=screen->r.min.x;
|
||||
}
|
||||
}
|
||||
else if(wind&w){
|
||||
right=ep->p.x;
|
||||
if(right>=screen->r.max.x) right=screen->r.max.x;
|
||||
#define BART_BUG_FIXED /* what goes on here?? -rob */
|
||||
#ifdef BART_BUG_FIXED
|
||||
if(right>left)
|
||||
line(screen, Pt(left, y), Pt(right, y), Endsquare, Endsquare, 0, getcolor(v), ZP);
|
||||
#else
|
||||
if(right>left){
|
||||
switch(v){
|
||||
default:
|
||||
segment(&screen, Pt(left, y), Pt(right, y),
|
||||
~0, D&~S);
|
||||
segment(&screen, Pt(left, y), Pt(right, y),
|
||||
v, f);
|
||||
break;
|
||||
case 0:
|
||||
segment(&screen, Pt(left, y), Pt(right, y),
|
||||
~0, D&~S);
|
||||
break;
|
||||
case 3:
|
||||
segment(&screen, Pt(left, y), Pt(right, y),
|
||||
v, f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
wind=nwind;
|
||||
nextep=ep->next;
|
||||
if(++ep->p.y!=ep->maxy){
|
||||
ep->x+=ep->num;
|
||||
if(ep->x>=ep->den){
|
||||
ep->x-=ep->den;
|
||||
ep->p.x+=ep->dx1;
|
||||
}
|
||||
else
|
||||
ep->p.x+=ep->dx;
|
||||
insert(ep, yp+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
free((char *)edges);
|
||||
free((char *)ylist);
|
||||
}
|
||||
void fill(int num[], double *ff[]){
|
||||
polygon(num, ff, Odd, e1->foregr);
|
||||
}
|
||||
16
src/cmd/plot/libplot/frame.c
Normal file
16
src/cmd/plot/libplot/frame.c
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#include "mplot.h"
|
||||
void frame(double xs, double ys, double xf, double yf){
|
||||
register double osidex, osidey;
|
||||
osidex = e1->sidex;
|
||||
osidey = e1->sidey;
|
||||
e1->left = e0->left + xs * e0->sidex;
|
||||
e1->bottom = e0->bottom + ys * e0->sidey;
|
||||
e1->sidex = (xf-xs)*e0->sidex;
|
||||
e1->sidey = (yf-ys)*e0->sidey;
|
||||
e1->scalex *= (e1->sidex / osidex);
|
||||
e1->scaley *= (e1->sidey / osidey);
|
||||
e1->quantum=e0->quantum/sqrt(e1->scalex*e1->scalex +
|
||||
e1->scaley*e1->scaley);
|
||||
if(e1->quantum < .01)
|
||||
e1->quantum = .01;
|
||||
}
|
||||
4
src/cmd/plot/libplot/grade.c
Normal file
4
src/cmd/plot/libplot/grade.c
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#include "mplot.h"
|
||||
void grade(double x){
|
||||
e1->grade = x;
|
||||
}
|
||||
5
src/cmd/plot/libplot/line.c
Normal file
5
src/cmd/plot/libplot/line.c
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include "mplot.h"
|
||||
void plotline(double x0, double y0, double x1, double y1){
|
||||
move(x0, y0);
|
||||
vec(x1, y1);
|
||||
}
|
||||
141
src/cmd/plot/libplot/machdep.c
Normal file
141
src/cmd/plot/libplot/machdep.c
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#include "mplot.h"
|
||||
Image *offscreen;
|
||||
/*
|
||||
* Clear the window from x0, y0 to x1, y1 (inclusive) to color c
|
||||
*/
|
||||
void m_clrwin(int x0, int y0, int x1, int y1, int c){
|
||||
draw(offscreen, Rect(x0, y0, x1+1, y1+1), getcolor(c), nil, ZP);
|
||||
}
|
||||
/*
|
||||
* Draw text between pointers p and q with first character centered at x, y.
|
||||
* Use color c. Centered if cen is non-zero, right-justified if right is non-zero.
|
||||
* Returns the y coordinate for any following line of text.
|
||||
*/
|
||||
int m_text(int x, int y, char *p, char *q, int c, int cen, int right){
|
||||
Point tsize;
|
||||
USED(c);
|
||||
tsize=stringsize(font, p);
|
||||
if(cen) x -= tsize.x/2;
|
||||
else if(right) x -= tsize.x;
|
||||
stringn(offscreen, Pt(x, y-tsize.y/2), getcolor(c), ZP, font, p, q-p);
|
||||
return y+tsize.y;
|
||||
}
|
||||
/*
|
||||
* Draw the vector from x0, y0 to x1, y1 in color c.
|
||||
* Clipped by caller
|
||||
*/
|
||||
void m_vector(int x0, int y0, int x1, int y1, int c){
|
||||
line(offscreen, Pt(x0, y0), Pt(x1, y1), Endsquare, Endsquare, 0, getcolor(c), ZP);
|
||||
}
|
||||
char *scanint(char *s, int *n){
|
||||
while(*s<'0' || '9'<*s){
|
||||
if(*s=='\0'){
|
||||
fprint(2, "plot: bad -Wxmin,ymin,xmax,ymax\n");
|
||||
exits("bad arg");
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*n=0;
|
||||
while('0'<=*s && *s<='9'){
|
||||
*n=*n*10+*s-'0';
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
char *rdenv(char *name){
|
||||
char *v;
|
||||
int fd, size;
|
||||
fd=open(name, OREAD);
|
||||
if(fd<0) return 0;
|
||||
size=seek(fd, 0, 2);
|
||||
v=malloc(size+1);
|
||||
if(v==0){
|
||||
fprint(2, "Can't malloc: %r\n");
|
||||
exits("no mem");
|
||||
}
|
||||
seek(fd, 0, 0);
|
||||
read(fd, v, size);
|
||||
v[size]=0;
|
||||
close(fd);
|
||||
return v;
|
||||
}
|
||||
/*
|
||||
* Startup initialization
|
||||
*/
|
||||
void m_initialize(char *s){
|
||||
static int first=1;
|
||||
int dx, dy;
|
||||
USED(s);
|
||||
if(first){
|
||||
initdraw(0,0,"plot");
|
||||
einit(Emouse);
|
||||
clipminx=mapminx=screen->r.min.x+4;
|
||||
clipminy=mapminy=screen->r.min.y+4;
|
||||
clipmaxx=mapmaxx=screen->r.max.x-5;
|
||||
clipmaxy=mapmaxy=screen->r.max.y-5;
|
||||
dx=clipmaxx-clipminx;
|
||||
dy=clipmaxy-clipminy;
|
||||
if(dx>dy){
|
||||
mapminx+=(dx-dy)/2;
|
||||
mapmaxx=mapminx+dy;
|
||||
}
|
||||
else{
|
||||
mapminy+=(dy-dx)/2;
|
||||
mapmaxy=mapminy+dx;
|
||||
}
|
||||
first=0;
|
||||
offscreen = screen;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Clean up when finished
|
||||
*/
|
||||
void m_finish(void){
|
||||
m_swapbuf();
|
||||
}
|
||||
void m_swapbuf(void){
|
||||
if(offscreen!=screen)
|
||||
draw(screen, offscreen->r, offscreen, nil, offscreen->r.min);
|
||||
flushimage(display, 1);
|
||||
}
|
||||
void m_dblbuf(void){
|
||||
if(offscreen==screen){
|
||||
offscreen=allocimage(display, insetrect(screen->r, 4), screen->chan, 0, -1);
|
||||
if(offscreen==0){
|
||||
fprintf(stderr, "Can't double buffer\n");
|
||||
offscreen=screen;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Assume colormap entry because
|
||||
* Use cache to avoid repeated allocation.
|
||||
*/
|
||||
struct{
|
||||
int v;
|
||||
Image *i;
|
||||
}icache[32];
|
||||
|
||||
Image*
|
||||
getcolor(int v)
|
||||
{
|
||||
Image *i;
|
||||
int j;
|
||||
|
||||
for(j=0; j<nelem(icache); j++)
|
||||
if(icache[j].v==v && icache[j].i!=nil)
|
||||
return icache[j].i;
|
||||
|
||||
i = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, v);
|
||||
if(i == nil){
|
||||
fprint(2, "plot: can't allocate image for color: %r\n");
|
||||
exits("allocimage");
|
||||
}
|
||||
for(j=0; j<nelem(icache); j++)
|
||||
if(icache[j].i == nil){
|
||||
icache[j].v = v;
|
||||
icache[j].i = i;
|
||||
break;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
42
src/cmd/plot/libplot/mkfile
Normal file
42
src/cmd/plot/libplot/mkfile
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
PLAN9=../../../..
|
||||
<$PLAN9/src/mkhdr
|
||||
|
||||
LIB=../libplot.a
|
||||
OFILES=box.$O\
|
||||
cfill.$O\
|
||||
circ.$O\
|
||||
closepl.$O\
|
||||
color.$O\
|
||||
disk.$O\
|
||||
doublebuffer.$O\
|
||||
dpoint.$O\
|
||||
erase.$O\
|
||||
fill.$O\
|
||||
frame.$O\
|
||||
grade.$O\
|
||||
line.$O\
|
||||
machdep.$O\
|
||||
move.$O\
|
||||
openpl.$O\
|
||||
parabola.$O\
|
||||
pen.$O\
|
||||
poly.$O\
|
||||
ppause.$O\
|
||||
pprompt.$O\
|
||||
range.$O\
|
||||
rarc.$O\
|
||||
restore.$O\
|
||||
rmove.$O\
|
||||
rvec.$O\
|
||||
save.$O\
|
||||
sbox.$O\
|
||||
spline.$O\
|
||||
subr.$O\
|
||||
text.$O\
|
||||
vec.$O\
|
||||
whoami.$O\
|
||||
|
||||
HFILES=mplot.h\
|
||||
|
||||
<$PLAN9/src/mklib
|
||||
|
||||
5
src/cmd/plot/libplot/move.c
Normal file
5
src/cmd/plot/libplot/move.c
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include "mplot.h"
|
||||
void move(double xx, double yy){
|
||||
e1->copyx = xx;
|
||||
e1->copyy = yy;
|
||||
}
|
||||
47
src/cmd/plot/libplot/mplot.h
Normal file
47
src/cmd/plot/libplot/mplot.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <stdio.h>
|
||||
#include <draw.h>
|
||||
#include <event.h>
|
||||
#define SCX(A) ((((A) - e1->xmin)*e1->scalex + e1->left)+.5)
|
||||
#define SCY(A) ((((A) - e1->ymin)*e1->scaley + e1->bottom)+.5)
|
||||
#define SCR(A) ((A)*e1->scalex+.5)
|
||||
#define unorm(y) (double)(e1->sidey - y)
|
||||
#define BIGINT 0x3FFFFFFF /* a large, but valid, int */
|
||||
extern struct penvir {
|
||||
double left, bottom;
|
||||
double xmin, ymin;
|
||||
double scalex, scaley;
|
||||
double sidex, sidey;
|
||||
double copyx, copyy;
|
||||
double quantum;
|
||||
double grade;
|
||||
int pgap;
|
||||
double pslant;
|
||||
int pmode, foregr, backgr;
|
||||
} *e0, *e1, *esave;
|
||||
#define RADIAN 57.3 /* radians per degree */
|
||||
struct seg {
|
||||
int x, y, X, Y;
|
||||
char stat;
|
||||
};
|
||||
|
||||
/*
|
||||
* display parameters
|
||||
*/
|
||||
int clipminx, clipminy, clipmaxx, clipmaxy; /* clipping rectangle */
|
||||
int mapminx, mapminy, mapmaxx, mapmaxy; /* centered square */
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
#include "../plot.h"
|
||||
void m_clrwin(int, int, int, int, int);
|
||||
void m_finish(void);
|
||||
void m_initialize(char *);
|
||||
int m_text(int, int, char *, char *, int, int, int);
|
||||
void m_vector(int, int, int, int, int);
|
||||
void m_swapbuf(void);
|
||||
void m_dblbuf(void);
|
||||
int bcolor(char *);
|
||||
void sscpy(struct penvir *, struct penvir *);
|
||||
Image *getcolor(int);
|
||||
12
src/cmd/plot/libplot/openpl.c
Normal file
12
src/cmd/plot/libplot/openpl.c
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include "mplot.h"
|
||||
void openpl(char *s){
|
||||
m_initialize(s);
|
||||
e0->left=mapminx;
|
||||
e0->bottom=mapmaxy;
|
||||
e0->sidex=mapmaxx-mapminx;
|
||||
e0->sidey=mapminy-mapmaxy;
|
||||
e0->scalex=e0->sidex;
|
||||
e0->scaley=e0->sidey;
|
||||
sscpy(e0, e1);
|
||||
move(0., 0.);
|
||||
}
|
||||
32
src/cmd/plot/libplot/parabola.c
Normal file
32
src/cmd/plot/libplot/parabola.c
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#include "mplot.h"
|
||||
void parabola(double x0, double y0, double x1, double y1, double xb, double yb){
|
||||
register double x, y, t;
|
||||
double c0x, c0y, c1x, c1y;
|
||||
double dt, d2, d1;
|
||||
d1 = sqrt((xb - x0) * (xb - x0) + (yb - y0) * (yb - y0));
|
||||
d2 = sqrt((xb - x1) * (xb - x1) + (yb - y1) * (yb - y1));
|
||||
if (d1 <= e1->quantum || d2 <= e1->quantum) {
|
||||
plotline(x0, y0, x1, y1);
|
||||
return;
|
||||
}
|
||||
c0x = x0 + x1 - 2. * xb;
|
||||
c1x = 2. * (xb - x0);
|
||||
c0y = y0 + y1 - 2. * yb;
|
||||
c1y = 2. * (yb - y0);
|
||||
move(x0, y0);
|
||||
dt = e1->quantum / d1;
|
||||
dt /= e1->grade;
|
||||
for (t = dt; t < 0.5; t += dt) {
|
||||
x = (c0x * t + c1x) * t + x0;
|
||||
y = (c0y * t + c1y) * t + y0;
|
||||
vec(x, y);
|
||||
}
|
||||
dt = e1->quantum / d2;
|
||||
dt /= e1->grade;
|
||||
for (; t < 1.0; t += dt) {
|
||||
x = (c0x * t + c1x) * t + x0;
|
||||
y = (c0y * t + c1y) * t + y0;
|
||||
vec(x, y);
|
||||
}
|
||||
vec(x1, y1);
|
||||
}
|
||||
6
src/cmd/plot/libplot/pen.c
Normal file
6
src/cmd/plot/libplot/pen.c
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include "mplot.h"
|
||||
void pen(char *s){
|
||||
/* BUG: NO OP */
|
||||
USED(s);
|
||||
/* was this error: color(s); */
|
||||
}
|
||||
17
src/cmd/plot/libplot/poly.c
Normal file
17
src/cmd/plot/libplot/poly.c
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#include "mplot.h"
|
||||
void plotpoly(int num[], double *ff[]){
|
||||
double *xp, *yp, **fp;
|
||||
int i, *n;
|
||||
n = num;
|
||||
fp = ff;
|
||||
while((i = *n++)){
|
||||
xp = *fp++;
|
||||
yp = xp+1;
|
||||
move(*xp, *yp);
|
||||
while(--i){
|
||||
xp += 2;
|
||||
yp += 2;
|
||||
vec(*xp, *yp);
|
||||
}
|
||||
}
|
||||
}
|
||||
7
src/cmd/plot/libplot/ppause.c
Normal file
7
src/cmd/plot/libplot/ppause.c
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#include "mplot.h"
|
||||
void ppause(void){
|
||||
char aa[4];
|
||||
fflush(stdout);
|
||||
read(0, aa, 4);
|
||||
erase();
|
||||
}
|
||||
5
src/cmd/plot/libplot/pprompt.c
Normal file
5
src/cmd/plot/libplot/pprompt.c
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include "mplot.h"
|
||||
void
|
||||
pprompt(void){
|
||||
fprintf(stderr, ":");
|
||||
}
|
||||
11
src/cmd/plot/libplot/range.c
Normal file
11
src/cmd/plot/libplot/range.c
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include "mplot.h"
|
||||
void range(double x0, double y0, double x1, double y1){
|
||||
e1->xmin = x0;
|
||||
e1->ymin = y0;
|
||||
e1->scalex = e1->sidex / (x1 - x0 );
|
||||
e1->scaley = e1->sidey / (y1 - y0 );
|
||||
e1->quantum=e0->quantum/sqrt(e1->scalex*e1->scalex +
|
||||
e1->scaley*e1->scaley);
|
||||
if(e1->quantum < .01)
|
||||
e1->quantum = .01;
|
||||
}
|
||||
44
src/cmd/plot/libplot/rarc.c
Normal file
44
src/cmd/plot/libplot/rarc.c
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#include "mplot.h"
|
||||
/* arc plotting routine */
|
||||
/* from x1,y1 to x2,y2 */
|
||||
/* with center xc,yc and radius rr */
|
||||
/* integrates difference equation */
|
||||
/* negative rr draws counterclockwise */
|
||||
#define PI4 0.7854
|
||||
void rarc(double x1, double y1, double x2, double y2, double xc, double yc, double rr){
|
||||
register double dx, dy, a, b;
|
||||
double ph, dph, rd, xnext;
|
||||
register int n;
|
||||
dx = x1 - xc;
|
||||
dy = y1 - yc;
|
||||
rd = sqrt(dx * dx + dy * dy);
|
||||
if (rd / e1->quantum < 1.0) {
|
||||
move(xc, yc);
|
||||
vec(xc, yc);
|
||||
return;
|
||||
}
|
||||
dph = acos(1.0 - (e1->quantum / rd));
|
||||
if (dph > PI4)
|
||||
dph = PI4;
|
||||
ph=atan2((y2-yc),(x2 - xc)) - atan2(dy, dx);
|
||||
if (ph < 0)
|
||||
ph += 6.2832;
|
||||
if (rr < 0)
|
||||
ph = 6.2832 - ph;
|
||||
if (ph < dph)
|
||||
plotline(x1, y1, x2, y2);
|
||||
else {
|
||||
n = ph / dph;
|
||||
a = cos(dph);
|
||||
b = sin(dph);
|
||||
if (rr < 0)
|
||||
b = -b;
|
||||
move(x1, y1);
|
||||
while ((n--) >= 0) {
|
||||
xnext = dx * a - dy * b;
|
||||
dy = dx * b + dy * a;
|
||||
dx = xnext;
|
||||
vec(dx + xc, dy + yc);
|
||||
}
|
||||
}
|
||||
}
|
||||
5
src/cmd/plot/libplot/restore.c
Normal file
5
src/cmd/plot/libplot/restore.c
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include "mplot.h"
|
||||
void restore(void){
|
||||
e1--;
|
||||
move(e1->copyx, e1->copyy);
|
||||
}
|
||||
6
src/cmd/plot/libplot/rmove.c
Normal file
6
src/cmd/plot/libplot/rmove.c
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include "mplot.h"
|
||||
void rmove(double xx, double yy){
|
||||
e1->copyx += xx;
|
||||
e1->copyy += yy;
|
||||
move(e1->copyx, e1->copyy);
|
||||
}
|
||||
6
src/cmd/plot/libplot/rvec.c
Normal file
6
src/cmd/plot/libplot/rvec.c
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include "mplot.h"
|
||||
void rvec(double xx, double yy){
|
||||
e1->copyx += xx;
|
||||
e1->copyy += yy;
|
||||
vec(e1->copyx, e1->copyy);
|
||||
}
|
||||
5
src/cmd/plot/libplot/save.c
Normal file
5
src/cmd/plot/libplot/save.c
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include "mplot.h"
|
||||
void save(void){
|
||||
sscpy(e1, e1 + 1);
|
||||
e1++;
|
||||
}
|
||||
13
src/cmd/plot/libplot/sbox.c
Normal file
13
src/cmd/plot/libplot/sbox.c
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#include "mplot.h"
|
||||
void sbox(double xx0, double yy0, double xx1, double yy1){
|
||||
int x0=SCX(xx0), y0=SCY(yy0), x1=SCX(xx1), y1=SCY(yy1);
|
||||
int t;
|
||||
if(x1<x0){ t=x0; x0=x1; x1=t; }
|
||||
if(y1<y0){ t=y0; y0=y1; y1=t; }
|
||||
if(x0<clipminx) x0=clipminx;
|
||||
if(y0<clipminy) y0=clipminy;
|
||||
if(x1>clipmaxx) x1=clipmaxx;
|
||||
if(y1>clipmaxy) y1=clipmaxy;
|
||||
if(x1<x0 || y1<y0) return;
|
||||
m_clrwin(x0, y0, x1, y1, e1->backgr);
|
||||
}
|
||||
51
src/cmd/plot/libplot/spline.c
Normal file
51
src/cmd/plot/libplot/spline.c
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Produce spline (uniform knots, second order)
|
||||
from guiding points
|
||||
*/
|
||||
#include "mplot.h"
|
||||
void splin(int mode, int num[], double *ff[]){
|
||||
int i, *np, n;
|
||||
double xa, ya, xc, yc, *xp, *yp, *xp0, *yp0, *xpe, *ype;
|
||||
double **fp;
|
||||
np = num;
|
||||
fp = ff;
|
||||
while((n = *np++)){
|
||||
xp = *fp++;
|
||||
yp = xp + 1;
|
||||
xp0 = xp;
|
||||
yp0 = yp;
|
||||
xpe = xp0 + 2 * (n - 1);
|
||||
ype = yp0 + 2 * (n - 1);
|
||||
if (n < 3) {
|
||||
plotline(*xp, *yp, *(xp + 2), *(yp + 2));
|
||||
continue;
|
||||
}
|
||||
if (mode == 4) { /*closed curve*/
|
||||
xa = 0.5 * (*xpe + *(xpe - 2));
|
||||
xc = 0.5 * (*xpe + *xp0);
|
||||
ya = 0.5 * (*ype + *(ype - 2));
|
||||
yc = 0.5 * (*ype + *yp0);
|
||||
parabola(xa, ya, xc, yc, *xpe, *ype);
|
||||
xa = 0.5 * (*xpe + *xp0);
|
||||
xc = 0.5 * (*(xp0 + 2) + *xp0);
|
||||
ya = 0.5 * (*ype + *yp0);
|
||||
yc = 0.5 * (*(yp0 + 2) + *yp0);
|
||||
parabola(xa, ya, xc, yc, *xp0, *yp0);
|
||||
}
|
||||
else { /*open curve with multiple endpoints*/
|
||||
if (mode % 2) /*odd mode makes first point double*/
|
||||
plotline(*xp0,*yp0,0.5*(*xp0+*(xp0+2)),0.5*(*yp0+*(yp0+2)));
|
||||
}
|
||||
xp += 2;
|
||||
yp += 2;
|
||||
for (i = 1; i < (n - 1); i++, xp += 2, yp += 2) {
|
||||
xa = 0.5 * (*(xp - 2) + *xp);
|
||||
xc = 0.5 * ( *xp + *(xp + 2));
|
||||
ya = 0.5 * (*(yp - 2) + *yp);
|
||||
yc = 0.5 * ( *yp + *(yp + 2));
|
||||
parabola(xa, ya, xc, yc, *xp, *yp);
|
||||
}
|
||||
if(mode >= 2 && mode != 4)
|
||||
plotline(0.5*(*(xpe-2)+*xpe),0.5*(*(ype-2)+*ype),*xpe,*ype);
|
||||
}
|
||||
}
|
||||
79
src/cmd/plot/libplot/subr.c
Normal file
79
src/cmd/plot/libplot/subr.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
#include "mplot.h"
|
||||
#define pSMALL 0.5
|
||||
struct penvir E[9] = {
|
||||
{ 0., 1024., 0., 0., 1., -1.,1024., -1024., 0., 0., pSMALL, 1., 1, 0.,1, DBlack, DWhite},
|
||||
{ 0., 1024., 0., 0., 1., -1.,1024., -1024., 0., 0., pSMALL, 1., 1, 0.,1, DBlack, DWhite},
|
||||
{ 0., 1024., 0., 0., 1., -1.,1024., -1024., 0., 0., pSMALL, 1., 1, 0.,1, DBlack, DWhite},
|
||||
{ 0., 1024., 0., 0., 1., -1.,1024., -1024., 0., 0., pSMALL, 1., 1, 0.,1, DBlack, DWhite},
|
||||
{ 0., 1024., 0., 0., 1., -1.,1024., -1024., 0., 0., pSMALL, 1., 1, 0.,1, DBlack, DWhite},
|
||||
{ 0., 1024., 0., 0., 1., -1.,1024., -1024., 0., 0., pSMALL, 1., 1, 0.,1, DBlack, DWhite},
|
||||
{ 0., 1024., 0., 0., 1., -1.,1024., -1024., 0., 0., pSMALL, 1., 1, 0.,1, DBlack, DWhite},
|
||||
{ 0., 1024., 0., 0., 1., -1.,1024., -1024., 0., 0., pSMALL, 1., 1, 0.,1, DBlack, DWhite}
|
||||
};
|
||||
struct penvir *e0 = E, *e1 = &E[1], *esave;
|
||||
bcolor(char *s){
|
||||
int c;
|
||||
while (*s != NULL) {
|
||||
switch (*s) {
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
c=0;
|
||||
while('0'<=*s && *s<='9')
|
||||
c=c*10+*s++-'0';
|
||||
if(c < 0)
|
||||
return DBlack;
|
||||
return cmap2rgba(c);
|
||||
case 'k': case 'z': /* zero was old name for kblack */
|
||||
return(DBlack);
|
||||
case 'r':
|
||||
print("RED");
|
||||
return(DRed);
|
||||
case 'g':
|
||||
return(DGreen);
|
||||
case 'b':
|
||||
return(DBlue);
|
||||
case 'm':
|
||||
return(DMagenta);
|
||||
case 'y':
|
||||
return(DYellow);
|
||||
case 'c':
|
||||
return(DCyan);
|
||||
case 'w':
|
||||
return(DWhite);
|
||||
case 'R':
|
||||
return(atoi(s + 1));
|
||||
case 'G':
|
||||
e1->pgap = atof(s + 1);
|
||||
return(-1);
|
||||
case 'A':
|
||||
e1->pslant = (180. - atof(s + 1)) / RADIAN;
|
||||
return(-1);
|
||||
}
|
||||
while (*++s != NULL)
|
||||
if (*s == '/') {
|
||||
s++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return DBlack;
|
||||
}
|
||||
void sscpy(struct penvir *a, struct penvir *b){ /* copy 'a' onto 'b' */
|
||||
b->left = a->left;
|
||||
b->bottom = a->bottom;
|
||||
b->xmin = a->xmin;
|
||||
b->ymin = a->ymin;
|
||||
b->scalex = a->scalex;
|
||||
b->scaley = a->scaley;
|
||||
b->sidex = a->sidex;
|
||||
b->sidey = a->sidey;
|
||||
b->copyx = a->copyx;
|
||||
b->copyy = a->copyy;
|
||||
b->quantum = a->quantum;
|
||||
b->grade = a->grade;
|
||||
b->pmode = a->pmode;
|
||||
b->foregr = a->foregr;
|
||||
b->backgr = a->backgr;
|
||||
}
|
||||
void idle(void){}
|
||||
|
||||
void ptype(char *s){USED(s);}
|
||||
39
src/cmd/plot/libplot/text.c
Normal file
39
src/cmd/plot/libplot/text.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
t string Place the string so that its first character is
|
||||
centered on the current point (default). If
|
||||
string begins with `\C' (`\R'), it is centered
|
||||
(right-adjusted) on the current point. A
|
||||
backslash at the beginning of the string may be
|
||||
escaped with another backslash.
|
||||
*/
|
||||
#include "mplot.h"
|
||||
void text(char *s){
|
||||
register int kx, ky;
|
||||
int centered, right, more;
|
||||
char *ss;
|
||||
ss=s;
|
||||
for(;;){
|
||||
centered=right=more=0;
|
||||
if(*ss=='\\'){
|
||||
ss++;
|
||||
switch(*ss){
|
||||
case 'C': centered++; ss++; break;
|
||||
case 'R': right++; ss++; break;
|
||||
case 'L': ss++; break;
|
||||
case 'n': --ss; break;
|
||||
}
|
||||
}
|
||||
for(s=ss;*ss!='\0';ss++)
|
||||
if(ss[0]=='\\' && ss[1]=='n'){
|
||||
more++;
|
||||
break;
|
||||
}
|
||||
kx = SCX(e1->copyx);
|
||||
ky = SCY(e1->copyy);
|
||||
ky=m_text(kx, ky, s, ss, e1->foregr, centered, right);
|
||||
if(!more)break;
|
||||
e1->copyy = ( (double)(ky) - e1->bottom)/e1->scaley + e1->ymin + .5;
|
||||
move(e1->copyx, e1->copyy);
|
||||
ss+=2;
|
||||
}
|
||||
}
|
||||
26
src/cmd/plot/libplot/vec.c
Normal file
26
src/cmd/plot/libplot/vec.c
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#include "mplot.h"
|
||||
#define code(x, y) ((x<clipminx?1:x>clipmaxx?2:0)|(y<clipminy?4:y>clipmaxy?8:0))
|
||||
void vec(double xx, double yy){
|
||||
int x0, y0, x1, y1, c0, c1, c, tx, ty;
|
||||
double t;
|
||||
t=SCX(e1->copyx); if(fabs(t)>BIGINT) return; x0=t;
|
||||
t=SCY(e1->copyy); if(fabs(t)>BIGINT) return; y0=t;
|
||||
t=SCX(xx); if(fabs(t)>BIGINT) return; x1=t;
|
||||
t=SCY(yy); if(fabs(t)>BIGINT) return; y1=t;
|
||||
e1->copyx=xx;
|
||||
e1->copyy=yy;
|
||||
/* clipping -- what a concept */
|
||||
c0=code(x0, y0);
|
||||
c1=code(x1, y1);
|
||||
while(c0|c1){
|
||||
if(c0&c1) return;
|
||||
c=c0?c0:c1;
|
||||
if(c&1) ty=y0+(y1-y0)*(clipminx-x0)/(x1-x0), tx=clipminx;
|
||||
else if(c&2) ty=y0+(y1-y0)*(clipmaxx-x0)/(x1-x0), tx=clipmaxx;
|
||||
else if(c&4) tx=x0+(x1-x0)*(clipminy-y0)/(y1-y0), ty=clipminy;
|
||||
else tx=x0+(x1-x0)*(clipmaxy-y0)/(y1-y0), ty=clipmaxy;
|
||||
if(c==c0) x0=tx, y0=ty, c0=code(x0, y0);
|
||||
else x1=tx, y1=ty, c1=code(x1, y1);
|
||||
}
|
||||
m_vector(x0, y0, x1, y1, e1->foregr);
|
||||
}
|
||||
4
src/cmd/plot/libplot/whoami.c
Normal file
4
src/cmd/plot/libplot/whoami.c
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#include "mplot.h"
|
||||
char *whoami(void){
|
||||
return("ramtek");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue