/*
Subroutine: abc_drw.c
This subroutine (adapted from pp2d.f [Choptuik]), draws ABC objects
and particle trajectories. Entering the routine generates the ABC
Simulator display window. <ESC> returns to the command line in abc_com.
Command options from the active display window are described below in
drw_hlp.
*/
#include “abc.h”
#include <GL/glut.h>
int atag=1,htag=1,ltag=0,mtag=0,ntag=1,ptag=0,utag=0;
int itag=0,inum=0;
int xres,yres;
double ipos[99][5];
double xwin=430.0,xmin,ymin,xsmn,ysmn,
ywin=430.0,xmax,ymax,xsmx,ysmx,
dwin=1.1,dscl=1.1,dtrn=0.05,ddis=1.1,drot=5.0,hscl=0.01;
double vrta=0.0,vrtb=0.0,vrtc=0.0,vdis,vsra,vsrb,vsrc,vsds;
void abc_drw(int argc,char **argv)
{
int i;
vdis = 10.0objdim[0][6];
xmin = dscl(objdim[0][1]-0.5objdim[0][4]); xsmn = xmin; vsra = vrta;
ymin = dscl(objdim[0][2]-0.5objdim[0][5]); ysmn = ymin; vsrb = vrtb;
xmax = dscl(objdim[0][1]+0.5objdim[0][4]); xsmx = xmax; vsrc = vrtc;
ymax = dscl(objdim[0][2]+0.5*objdim[0][5]); ysmx = ymax; vsds = vdis;
drwcol[0][0] = 1.0;
if(mtag) for(i=1;i<=3;i++) drwcol[0][i] = 0.0;
else for(i=1;i<=3;i++) drwcol[0][i] = 1.0;
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(0,0);
glutInitWindowSize(xwin,ywin);
glutCreateWindow(“ABC Simulator”);
glutDisplayFunc(drw_dis);
glutIdleFunc(drw_idl);
glutKeyboardFunc(drw_key);
glutMouseFunc(drw_mou);
glutReshapeFunc(drw_res);
glutSpecialFunc(drw_spe);
glEnable(GL_POINT_SMOOTH);
glutMainLoop();
}
void drw_idl(void)
{
return;
}
void drw_key(unsigned char key,int x, int y)
{
double xavg,yavg,xdel,ydel;
int ig;
if(itag) return;
if(key >= ‘0’ && key <= ‘9’)
{
ig = key - ‘0’; if(ig == 0) ig = 10; abc_gen(ig);
drw_res(xres,yres);
return;
}
switch(key)
{
case ‘A’:
vrta += drot; drw_res(xres,yres);
break;
case ‘a’:
vrta -= drot; drw_res(xres,yres);
break;
case ‘B’:
vrtb += drot; drw_res(xres,yres);
break;
case ‘b’:
vrtb -= drot; drw_res(xres,yres);
break;
case ‘C’:
vrtc += drot; drw_res(xres,yres);
break;
case ‘c’:
vrtc -= drot; drw_res(xres,yres);
break;
case ‘D’:
vdis = ddis; drw_res(xres,yres);
break;
case ‘d’:
vdis /= ddis; drw_res(xres,yres);
break;
case ‘S’:
xavg = 0.5(xmin+xmax); yavg = 0.5*(ymin+ymax);
xdel = 0.5*(xmax-xmin); ydel = 0.5*(ymax-ymin);
xmin = xavg - xdel/dscl; xmax = xavg + xdel/dscl;
ymin = yavg - ydel/dscl; ymax = yavg + ydel/dscl;
drw_res(xres,yres);
break;
case ‘s’:
xavg = 0.5*(xmin+xmax); yavg = 0.5*(ymin+ymax);
xdel = 0.5*(xmax-xmin); ydel = 0.5*(ymax-ymin);
xmin = xavg - xdeldscl; xmax = xavg + xdeldscl;
ymin = yavg - ydeldscl; ymax = yavg + ydeldscl;
drw_res(xres,yres);
break;
case ‘W’:
xwin *= dwin; ywin *= dwin;
glutReshapeWindow(xwin,ywin);
glutPostRedisplay();
break;
case ‘w’:
xwin /= dwin; ywin /= dwin;
glutReshapeWindow(xwin,ywin);
glutPostRedisplay();
break;
case ‘r’:
xmin = xsmn; ymin = ysmn; xmax = xsmx; ymax = ysmx; inum = 0;
vrta = vsra; vrtb = vsrb; vrtc = vsrc; vdis = vsds;
drw_res(xres,yres);
break;
case ‘v’:
vrta = 46.0; vrtb = 45.0; vrtc = 90.0;
drw_res(xres,yres);
break;
case ‘x’:
vrta = 180.0; vrtb = -90.0; vrtc = -90.0;
drw_res(xres,yres);
break;
case ‘y’:
vrta = 90.0; vrtb = 90.0; vrtc = 180.0;
drw_res(xres,yres);
break;
case ‘z’:
vrta = 0.0; vrtb = 0.0; vrtc = 0.0;
drw_res(xres,yres);
break;
case ‘i’:
if(inum < 99)
{
if(inum == 0)
{
ipos[inum][1] = xmin; ipos[inum][2] = ymin;
ipos[inum][3] = xmax; ipos[inum][4] = ymax;
}
inum++; itag = 1;
}
break;
case ‘o’:
if(inum > 0)
{
inum–;
xmin = ipos[inum][1]; ymin = ipos[inum][2];
xmax = ipos[inum][3]; ymax = ipos[inum][4];
drw_res(xres,yres);
}
break;
case ‘h’:
htag = !htag; drw_res(xres,yres);
break;
case ‘j’:
atag = !atag; drw_res(xres,yres);
break;
case ‘l’:
ltag = !ltag; drw_res(xres,yres);
break;
case ‘m’:
mtag = !mtag; drw_res(xres,yres);
break;
case ‘n’:
ntag = !ntag; drw_res(xres,yres);
break;
case ‘p’:
ptag = !ptag; drw_res(xres,yres);
break;
case ‘t’:
trknum = 0; hitnum = 0; drw_res(xres,yres);
break;
case ‘u’:
utag = !utag; drw_res(xres,yres);
break;
case 27:
abc_com(); drw_res(xres,yres);
break;
case ‘q’:
fprintf(stderr,"
"); exit(0);
case ‘?’:
drw_hlp();
break;
default:
break;
}
}
void drw_mou(int button,int state,int x,int y)
{
double xmou,ymou,xdel,ydel;
if(!itag) return;
switch(state)
{
case GLUT_DOWN:
ipos[inum][1] = xmin + (x/xwin)(xmax-xmin);
ipos[inum][4] = ymax - (y/ywin)(ymax-ymin);
break;
case GLUT_UP:
ipos[inum][2] = ymax - (y/ywin)(ymax-ymin);
ipos[inum][3] = xmin + (x/xwin)(xmax-xmin);
itag = 0;
xmin = ipos[inum][1]; ymin = ipos[inum][2];
xmax = ipos[inum][3]; ymax = ipos[inum][4];
drw_res(xres,yres);
break;
default:
break;
}
}
void drw_spe(int key, int x, int y )
{
int xdel,ydel,imod=glutGetModifiers();
if(itag) return;
switch(key)
{
case GLUT_KEY_LEFT:
if(imod == GLUT_ACTIVE_SHIFT) vrtb += drot;
else { xdel = xmax - xmin; xmax -= xdeldtrn; xmin -= xdeldtrn; }
drw_res(xres,yres);
break;
case GLUT_KEY_RIGHT:
if(imod == GLUT_ACTIVE_SHIFT) vrtb -= drot;
else { xdel = xmax - xmin; xmax += xdeldtrn; xmin += xdeldtrn; }
drw_res(xres,yres);
break;
case GLUT_KEY_DOWN:
if(imod == GLUT_ACTIVE_SHIFT) vrta += drot;
else { ydel = ymax - ymin; ymax -= ydeldtrn; ymin -= ydeldtrn; }
drw_res(xres,yres);
break;
case GLUT_KEY_UP:
if(imod == GLUT_ACTIVE_SHIFT) vrta -= drot;
else { ydel = ymax - ymin; ymax += ydeldtrn; ymin += ydeldtrn; }
drw_res(xres,yres);
break;
default:
break;
}
}
void drw_dis(void)
{
int i;
double x1,y1,x2,y2,x3,y3,x4,y4;
if(mtag) glClearColor(1.0,1.0,1.0,1.0);
else glClearColor(0.0,0.0,0.0,1.0);
if(mtag) for(i=1;i<=3;i++) drwcol[0][i] = 0.0;
else for(i=1;i<=3;i++) drwcol[0][i] = 1.0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(atag) drw_axe();
for(i=utag;i<maxobj;i++) if(i == 0 || objnum[i] > 0)
{
if(strcmp(objshp[i],“box”) == 0) drw_box(i);
if(strcmp(objshp[i],“BOX”) == 0) drw_box(i);
if(strcmp(objshp[i],“cyl”) == 0) drw_cyl(i);
if(strcmp(objshp[i],“CYL”) == 0) drw_cyl(i);
}
for(i=0;i<trknum;i++) drw_trk(i);
if(htag) for(i=0;i<hitnum;i++) drw_hit(i);
glutSwapBuffers();
}
void drw_res(int nw, int nh)
{
xres = nw;
yres = nh;
glViewport(0,0,xres,yres);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(xmin,xmax,ymin,ymax,-1.0,0.0);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
void drw_axe()
{
double x,y,z,ax[4],ay[4],az[4];
int i,nc;
for(i=1;i<4;i++)
{
x = 0.0; y = 0.0; z = 0.0;
if(i == 1) x = objdim[0][1] + 0.5objdim[0][4];
if(i == 2) y = objdim[0][2] + 0.5objdim[0][5];
if(i == 3) z = objdim[0][3] + 0.5*objdim[0][6];
drw_rot(x,y,z,&ax[i],&ay[i],&az[i]);
}
glPointSize(1.0);
nc = 0; if(ntag) nc = 1;
glColor3d(drwcol[nc][1],drwcol[nc][2],drwcol[nc][3]);
glBegin(GL_LINES);
glVertex2d(0.0,0.0); glVertex2d(ax[1],ay[1]);
glEnd();
nc = 0; if(ntag) nc = 2;
glColor3d(drwcol[nc][1],drwcol[nc][2],drwcol[nc][3]);
glBegin(GL_LINES);
glVertex2d(0.0,0.0); glVertex2d(ax[2],ay[2]);
glEnd();
nc = 0; if(ntag) nc = 3;
glColor3d(drwcol[nc][1],drwcol[nc][2],drwcol[nc][3]);
glBegin(GL_LINES);
glVertex2d(0.0,0.0); glVertex2d(ax[3],ay[3]);
glEnd();
}
void drw_box(int no)
{
double xi,yi,zi,x0,y0,z0,xw,yw,zw,ea,eb,ec,xo,yo,zo,bx[9],by[9],bz[9];
int i,nc=0;
x0 = objdim[no][1]; xw = 0.5objdim[no][4]; ea = objdim[no][7];
y0 = objdim[no][2]; yw = 0.5objdim[no][5]; eb = objdim[no][8];
z0 = objdim[no][3]; zw = 0.5*objdim[no][6]; ec = objdim[no][9];
if(ntag) nc = objcol[no];
for(i=1;i<9;i++)
{
xi = -xw; if(i==2 || i==3 || i==6 || i==7) xi = xw;
yi = -yw; if(i==3 || i==4 || i==7 || i==8) yi = yw;
zi = -zw; if(i > 4) zi = zw;
uti_rot(-1,xi,yi,zi,x0,y0,z0,ea,eb,ec,&xo,&yo,&zo);
drw_rot(xo,yo,zo,&bx[i],&by[i],&bz[i]);
}
glColor3d(drwcol[nc][1],drwcol[nc][2],drwcol[nc][3]);
glPointSize(1.0);
glBegin(GL_LINE_LOOP);
glVertex2d(bx[1],by[1]); glVertex2d(bx[2],by[2]);
glVertex2d(bx[3],by[3]); glVertex2d(bx[4],by[4]);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2d(bx[5],by[5]); glVertex2d(bx[6],by[6]);
glVertex2d(bx[7],by[7]); glVertex2d(bx[8],by[8]);
glEnd();
glBegin(GL_LINES);
glVertex2d(bx[1],by[1]); glVertex2d(bx[5],by[5]);
glVertex2d(bx[2],by[2]); glVertex2d(bx[6],by[6]);
glVertex2d(bx[3],by[3]); glVertex2d(bx[7],by[7]);
glVertex2d(bx[4],by[4]); glVertex2d(bx[8],by[8]);
glEnd();
}
void drw_cyl(int no)
{
double xi,yi,zi,x0,y0,z0,iw,ow,zw,ea,eb,ec,ei,es,xo,yo,zo,z,w;
double cx[17],cy[17];
int i,j,k,ni,nc=0;
x0 = objdim[no][1]; iw = 0.5objdim[no][4]; ea = objdim[no][7];
y0 = objdim[no][2]; ow = 0.5objdim[no][5]; eb = objdim[no][8];
z0 = objdim[no][3]; zw = 0.5objdim[no][6]; ec = objdim[no][9];
if(ntag) nc = objcol[no]; ni = 4maxinc; ei = 2.0pi/ni;
glColor3d(drwcol[nc][1],drwcol[nc][2],drwcol[nc][3]); glPointSize(1.0);
for(j=1;j<=4;j++)
{
z = -zw; if(j == 2 || j == 4) z = +zw;
w = iw; if(j > 2) w = ow; if(w > 0.0)
{
glBegin(GL_LINE_LOOP);
es = 0.0; for(i=1;i<=ni;i++)
{
es = es + ei; xi = wcos(es); yi = w*sin(es); zi = z;
uti_rot(-1,xi,yi,zi,x0,y0,z0,ea,eb,ec,&xo,&yo,&zo);
drw_rot(xo,yo,zo,&xi,&yi,&zi); glVertex2d(xi,yi);
if(i % maxinc == 0)
{
k = i/maxinc;
if(j > 2) k = k + 4;
if(j == 2 || j == 4) k = k + 8;
cx[k] = xi; cy[k] = yi;
}
}
glEnd();
}
}
glBegin(GL_LINES);
for(i=1;i<=8;i++) if(i > 4 || iw > 0)
{
glVertex2d(cx[i],cy[i]); glVertex2d(cx[i+8],cy[i+8]);
}
glEnd();
}
void drw_trk(int no)
{
double xi,yi,zi,xo,yo,zo;
int i,nc=0;
if(ntag) nc = prtcol[trkprt[no]];
glColor3d(drwcol[nc][1],drwcol[nc][2],drwcol[nc][3]);
if(ltag)
{
glPointSize(1.0);
glBegin(GL_LINE_STRIP);
for(i=0;i<trkpnt[no];i++)
{
xi = trkxpo[no][i]; yi = trkypo[no][i]; zi = trkzpo[no][i];
drw_rot(xi,yi,zi,&xo,&yo,&zo);
glVertex2d(xo,yo);
}
glEnd();
}
else
{
glPointSize(2.0);
glBegin(GL_POINTS);
for(i=0;i<trkpnt[no];i++)
{
xi = trkxpo[no][i]; yi = trkypo[no][i]; zi = trkzpo[no][i];
drw_rot(xi,yi,zi,&xo,&yo,&zo);
glVertex2d(xo,yo);
}
glEnd();
}
}
void drw_hit(int no)
{
double xi,yi,zi,xo,yo,zo,x1,y1,x2,y2,dx,dy,dh;
int nc=0;
if(ntag) nc = prtcol[hitprt[no]];
glColor3d(drwcol[nc][1],drwcol[nc][2],drwcol[nc][3]); glPointSize(1.0);
dx = hscl*(xmax-xmin); dy = hscl*(ymax-ymin);
dh = hscldx; if(dy < dx) dh = hscldy;
xi = hitxpo[no]; yi = hitypo[no]; zi = hitzpo[no];
drw_rot(xi,yi,zi,&xo,&yo,&zo);
x1 = xo - dx; y1 = yo - dy;
x2 = xo + dx; y2 = yo + dy;
glBegin(GL_LINES);
glVertex2d(x1,y1); glVertex2d(x2,y2);
glVertex2d(x1,y2); glVertex2d(x2,y1);
glEnd();
}
void drw_rot(xi,yi,zi,xo,yo,zo)
double xi,yi,zi,*xo,yo,zo;
{
double xr,yr,zr;
uti_rot(+1,xi,yi,zi,0.0,0.0,0.0,vrta,vrtb,vrtc,&xr,&yr,&zr);
if(ptag && (vdis-zr) > 0)
{
xr = xr(vdis/(vdis-zr));
yr = yr(vdis/(vdis-zr));
}
*xo = xr; *yo = yr; *zo = zr;
}
void drw_hlp()
{
fprintf(stderr,"
“);
fprintf(stderr,” Commands:");
fprintf(stderr," (type ‘?’ for help, ‘q’ to quit, <ESC> for prompt)
“);
fprintf(stderr,”
“);
fprintf(stderr,” # - generate particle # (‘0’=10)
“);
fprintf(stderr,” i,o - zoom in with mouse (down on UL corner, ");
fprintf(stderr, "up on LR), zoom out
“);
fprintf(stderr,” l,t - toggle tracks (lines/points), ");
fprintf(stderr, "clear tracks/hits
“);
fprintf(stderr,” m,n - toggle background (B/W), color
“);
fprintf(stderr,” u,j,h,p - toggle universe,axes,hits,perspective
“);
fprintf(stderr,” v,x,y,z - view from angle,x-,y-,z-axis
“);
fprintf(stderr,” r - reset view
“);
fprintf(stderr,”
“);
fprintf(stderr,” a/A,b/B,c/C - dec/inc view angle a,b,c
“);
fprintf(stderr,” d/D,s/S,w/W - dec/inc view distance,scale,window
“);
fprintf(stderr,”
“);
fprintf(stderr,” <arrow> - move view left/right/up/down
“);
fprintf(stderr,” <SHIFT><arrow> - rotate x-y view angle
“);
fprintf(stderr,”
");
}