plloop
start event loop
| parameter | type | units | description |
|---|---|---|---|
| -- | void | -- | |
| returns: | void |
Description
plloop, if the plotter driver is X, starts an event loop, testing whether a key or a mouse button was hit. If so, plevent is called, with information about the key that was hit and the current position of the mouse pointer. The user is responsible for delivering the plevent routine. See plevent. If the plotter driver is PostScript (PS or PSL) then plloop is equivalent to calling pldraw and plend. The user is responsible for supplying the pldraw-routine. This facility has been built in for users who want to temporarily convert an X-windows program into a PostScript plotting program without having to make it dynamically switchable .Examples
The following program is a relatively simple example of the use of plloop, yet it is very illustrative for many features of simplot. It plots MIRA-fractals for which the user can change the parameters interactively. The program sets up a loop recognizing several events:- F1
- shows help information about the key recognized
- q
- quits the program
- p
- plots the current fractal to the plotter
- 0-9.-
- these keys enter a number. The current number becomes visible in the top centre of the window
- n
- set the number of iterations to the current number and redraws the fractal
- a
- sets fractal parameter a to the current number and draws the new fractal
- b
- sets fractal parameter b to the current number and draws the new fractal
- mouse
- left button may be pressed and dragged to expand a subrectangle
- mouse
- right button undoes the expansion, returning the fractal to its original dimensions
- mouse
- middle button displays two crosshairs, annotated with the x,y position of their intersection
// plloop example - basic X-windows program plotting fractals
#include <stdio.h>
#include <simplot.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define NONE 0
#define EXPANDING 1
#define MARKING 2
#define BW 16
#define SIZE 150
float number=0.,a=.40002,b=.999;
//float number=0.,a=.399,b=.999;
float ymin=-8,ymax=8,xmin=-8,xmax=8;
float xmn=-8,ymn=-8,xmx=8,ymx=8;
float xl=SIZE,yl=SIZE;
int num=100000,mode=NONE;
float dot=.3;
void pldraw(void) {
int i;
double w,x,y,z;
float c;
if (plget(PLOTTER)==X)
plpage(); // clear the window
plaxes(xmn,ymn,xmx,ymx,xl,yl,"X","Y","MIRA - fractal (F1=help)");
if (plget(PLOTTER)!=X)
plframe(5,3);
plset(RECTFILL,TRUE);
plrect(xmn,ymn,xmx,ymx);
plset(RECTFILL,FALSE);
x=12;
y=0;
c=2*(1-a);
w=a*x+c*x*x/(1+x*x);
if (plget(PLOTTER)==X)
plcolor(Red);
for (i=1;i<num;i++) { // plot the fractal
z=x;
x=b*y+w;
w=a*x+c*x*x/(1+x*x);
y=w-z;
if (x<xmn)
continue;
if (x>xmx)
continue;
if (y<ymn)
continue;
if (y>ymx)
continue;
pldot(x,y,dot);
}
plcolor(Blue);
plmess("MIRA fractal %d iterations a=%g b=%g\n",num,a,b);
plcolor(Black);
}
void expand(float xmi, float ymi, float xma, float yma)
// expand a rectangle opened with the mouse
{ xmn=xmi;
ymn=ymi;
xmx=xma;
ymx=yma;
pldraw();
}
void unexpand(void) {
expand(xmin,ymin,xmax,ymax);
}
void plevent(float xpointer,float ypointer,int key) {
static int numpos=0,help=TRUE;
static char numstring[100]="";
int toplotter=FALSE;
// for non-mouse events look at key down only:
if (!plget(EVENT_BUTTON))
if (key<0)
return;
switch(key) {
case 'a':
a=number;
number=numpos=0;
unexpand();
break;
case 'b':
b=number;
number=numpos=0;
unexpand();
break;
case 'd':
dot=number;
number=numpos=0;
pldraw();
break;
case 'n':
num=(int)number;
number=numpos=0;
pldraw();
break;
case F1: // F1 function key: help
if (!help)
pldraw();
else {
plpage();
plu(xmn,ymx);
plformat(.5,-1, "F1 : help (press again to continue)\n"
"[0-9.-] : build number\n"
"a : set parameter (now %g) a to current number\n"
"b : set parameter (now %g) a to current number\n"
"d : set dotsize in mm\n"
"n : set number of iterations (now %d)\n"
"P : print to plotfile and plotter\n"
"p : print to plotfile only\n"
"q : quit\n"
"Mouse:\n"
"Leftdrag : expand\n"
"Right : unexpand\n"
"Middle : track position\n",a,b,num);
}
help=!help;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5': // build number
case '6':
case '7':
case '8':
case '9':
case '-':
case '.':
numstring[numpos++]=key;
numstring[numpos]=0;
sscanf(numstring,"%g",&number);
plmess("current number: %g",number);
return;
case Delete:
if (numpos)
numstring[--numpos]=0;
sscanf(numstring,"%g",&number);
plmess("current number: %g",number);
return;
case Escape:
number=numpos=0;
plmess("");
break;
case 'P': // plot to plotter
toplotter=TRUE;
case 'p': // plot to file only
plmess("");
plend();
plinit(PS,"plloop",A4,30,30,"","");
pldraw();
plend();
if (toplotter)
system("plot plloop&");
plinit(X,"",SIZE+20,SIZE+20,10,10,"","");
plloop();
break;
case 'q': // Quit
plend();
exit(0);
case MouseLeftDown: // initialize rectangle
plmess("expanding");
mode=EXPANDING;
xmn=xpointer>xmin?xpointer:xmin;
ymn=ypointer>ymin?ypointer:ymin;
xmx=xmn;
ymx=ymn;
plset(PLOTMODE,GXxor);
break;
case MouseLeftUp: // expand part in rect
plset(PLOTMODE,GXcopy);
if ((xmx-xmn)*plget(XU2P)<10||(ymx-ymn)*plget(YU2P)<10)
unexpand();
else
expand(xmn,ymn,xmx,ymx);
mode=NONE;
break;
case MouseMiddleDown:
plhairs(xpointer,ypointer,TRUE,TRUE);
mode=MARKING;
break;
case MouseMiddleUp:
mode=NONE;
plhairs(xpointer,ypointer,FALSE,FALSE); // erase last hairs
plmess("MIRA fractal %d iterations a=%g b=%g\n",num,a,b);
break;
case MouseRightUp: // restore full plot
unexpand();
break;
case MouseDrag: // change rectangle
if (xpointer<xmn)
break;
if (ypointer<ymn)
break;
if (xpointer>xmax)
break;
if (ypointer>ymax)
break;
switch(mode) {
case EXPANDING:
plrect(xmn,ymn,xmx,ymx); // replot previous rect, erasing it
xmx=xpointer;
ymx=ypointer;
plrect(xmn,ymn,xmx,ymx); // plot new rect
break;
case MARKING:
plmess("x=%g y=%g",xpointer,ypointer);
plhairs(xpointer,ypointer,TRUE,TRUE);
break;
}
break;
}
}
int main(int argc,char *argv[]) { // without an argument, just make a PostScript plotfile and quit
// with an argument, run under X
if (argc==1) {
plinit(PS,"plloop",A4,50,50,"","");
plset(PENDIA,1);
plset(HEIGHT,5);
plfcolor(Aquamarine);
pldraw();
plend();
} else {
plinit(X,"",SIZE+50,SIZE+50,25,25,"","");
plset(HEIGHT,5);
plset(PENDIA,.3);
plfcolor(Aquamarine);
plloop();
}
exit(0);
}
