/* Michael Creutz */ /* creutz@wind.phy.bnl.gov */ /* to compile: */ /* cc -O fourier.c -lX11 -lm */ /* version of August, 1995 */ /* January 2000: corrected array bounds on xpoints */ # include # include # include # include # include # include # include # include # include # include #include #include #include struct timeval timeout; /* some colors to use */ #define WHITE 0 #define BLACK 1 #define RED 2 #define BLUE 3 #define GREEN 4 #define YELLOW 5 #define MAGENTA 6 #define CYAN 7 #define ORANGE 8 #define PURPLE 9 #define PINK 10 #define BROWN 11 #define GREY 12 #define TURQUOISE 13 #define GOLD 14 #define NAVY 15 #define TAN 16 #define VIOLET 17 /* NSITES = number of lattice sites */ # define NSITES 256 double phi[NSITES],cpi[NSITES]; /* position space field and momentum */ double fphi[NSITES], fcpi[NSITES]; /* fourier space momentum */ double cn[NSITES],sn[NSITES]; /* for cosine and sin of angles */ double omega[NSITES]; /* frequency for given component */ double comega[NSITES],somega[NSITES];/* cos and sin of dt*omega */ double pi; /* 3.14.... */ int xcenter,ycenter,vx,vy; /* center of drifting blob */ XPoint xpoints[NSITES+7]; /* for drawing polygons */ # define dt (.02*(1-.8*slow)) void drawbutton(),openwindow(),makebuttons(),update(),repaint(), cleanup(),drawit(),drawwave(),drawblob(),fastfourier(), xtof(),ftox(),makedispersion(); /* dimensions for control boxes */ # define BUTTONWIDTH 72 # define BUTTONHEIGHT 18 /* initial button settings */ int paused=0; /* is the system paused? */ int damped=0; /* is the system damped? */ int reversed=0; /* are we going backwards? */ int mass=1; /* does the wave have mass? (0 or 1 only) */ int blob=0; /* display as blob? */ int drift=0; /* let blob drift */ int slow=0; /* run at slow speed */ int equation=0; /* 0 for light, 1 for mesons, 2 for water */ # define WATER 2 char * equtext[3]={"light","mesons","water"}; char stringbuffer[256]; /* generally useful */ /* to simplify typing */ # define line(x1,y1,x2,y2) XDrawLine(display,window,gc1,x1,y1,x2,y2) # define line2(x1,y1,x2,y2) XDrawLine(display,window,gc2,x1,y1,x2,y2) # define color(i) XSetForeground(display,gc1,translate[i]) # define color2(i) XSetForeground(display,gc2,translate[i]) /* various window stuff */ Display *display; int screen; static char *progname; Window window,quitbutton,pausebutton,vacuumbutton,rightbutton,dampbutton, reversebutton,blobbutton,driftbutton,slowbutton,packetbutton, equbutton,makebutton(); XColor xcolor,colorcell; Colormap cmap; GC gc1,gc2; int windowwidth,windowheight,playwidth,playheight; XFontStruct *font=NULL; int font_height,font_width; XSizeHints size_hints; int darkcolor,lightcolor,black,white; long translate[256]; /* for converting colors */ double norm=1/(1.*NSITES); int main ( int argc, char **argv ) { int i,j,k; double phipeg,w,theta,theta0; unsigned int width, height; XEvent report; progname=argv[0]; pi=4*atan(1.0); for (i=0;iplayheight) update(); /* outside of playfield */ else /* perturb field */ {if (blob) /* do some trig */ {phipeg=(i-xcenter)*(i-xcenter) +(j-ycenter)*(j-ycenter); phipeg=4*sqrt(phipeg)/(1.*playheight)-.60; if (j!=ycenter) theta0=atan((xcenter-i)/(1.0*(ycenter-j))); else theta0=pi/2.0; if (j>ycenter) /* put theta0 between 0 and 2 pi */ theta0+=pi; if (theta0<0.) theta0+=2*pi; } else /* not displayed as a blob */ {theta0=2*pi*i/(1.*playwidth); phipeg=(j-playheight/2)/(0.5*playheight); } /* now construct the perturbed field */ for (k=0;k=playheight) iy=playheight-1; else if (iy<0) iy=0; xpoints[i].x=(i*playwidth)/(NSITES-1); xpoints[i].y=iy; } xpoints[NSITES].x=playwidth; xpoints[NSITES].y=playheight-1; xpoints[NSITES+1].x=0; xpoints[NSITES+1].y=playheight-1; XFillPolygon(display,window,gc1,xpoints,NSITES+2,Nonconvex,CoordModeOrigin); xpoints[NSITES].y=0; xpoints[NSITES+1].y=0; XFillPolygon(display,window,gc2,xpoints,NSITES+2,Nonconvex,CoordModeOrigin); return; } void drawblob() {int i,ix,iy; double r; color(CYAN); color2(MAGENTA); xcenter+=vx; ycenter+=vy; for (i=0;i(playheight-1)) iy=playheight-1, vy=-abs(vy); if (iy< 0 ) iy=0 , vy= abs(vy); if (ix>playwidth ) ix=playwidth , vx=-abs(vx); if (ix<0 ) ix=0 , vx= abs(vx); xpoints[i].x=ix; xpoints[i].y=iy; } /* draw inside, allowing for boundary if imposed */ XFillPolygon(display,window,gc2,xpoints,NSITES,Nonconvex, CoordModeOrigin); /* draw outside of region */ xpoints[NSITES].x=xpoints[0].x; xpoints[NSITES].y=xpoints[0].y; xpoints[NSITES+1].x=xcenter; xpoints[NSITES+1].y=0; xpoints[NSITES+2].x=playwidth; xpoints[NSITES+2].y=0; xpoints[NSITES+3].x=playwidth; xpoints[NSITES+3].y=playheight-1; xpoints[NSITES+4].x=0; xpoints[NSITES+4].y=playheight-1; xpoints[NSITES+5].x=0; xpoints[NSITES+5].y=0; xpoints[NSITES+6].x=xcenter; xpoints[NSITES+6].y=0; XFillPolygon(display,window,gc1,xpoints,NSITES+7,Nonconvex, CoordModeOrigin); return; } void repaint() /* this fixes the window up whenever it is uncovered */ {int i; color(BROWN); XFillRectangle(display,window,gc1,0,playheight, playwidth,windowheight-playheight); drawbutton(pausebutton,0,0,BUTTONWIDTH,BUTTONHEIGHT,"pause",1-2*paused); drawbutton(dampbutton,0,0,BUTTONWIDTH,BUTTONHEIGHT,"damp",1-2*damped); drawbutton(quitbutton,0,0,BUTTONWIDTH,BUTTONHEIGHT,"quit",1); drawbutton(vacuumbutton,0,0,BUTTONWIDTH,BUTTONHEIGHT,"vacuum",1); drawbutton(reversebutton,0,0,BUTTONWIDTH,BUTTONHEIGHT,"reverse",1-2*reversed); drawbutton(blobbutton,0,0,BUTTONWIDTH,BUTTONHEIGHT,"blob",1-2*blob); drawbutton(rightbutton,0,0,BUTTONWIDTH,BUTTONHEIGHT,"right",1); drawbutton(driftbutton,0,0,BUTTONWIDTH,BUTTONHEIGHT,"drift",1-2*drift); drawbutton(slowbutton,0,0,BUTTONWIDTH,BUTTONHEIGHT,"slow",1-2*slow); drawbutton(packetbutton,0,0,BUTTONWIDTH,BUTTONHEIGHT,"packet",1); for (i=0;i<3;i++) drawbutton(equbutton,i*BUTTONWIDTH,0,BUTTONWIDTH,BUTTONHEIGHT, equtext[i],1-2*(equation==i)); color(BLACK); line(0,playheight,windowwidth,playheight); drawit(); return; } void openwindow(argc,argv) /* a lot of this is taken from basicwin in the Xlib Programming Manual */ int argc; char **argv; {char *window_name="Wave tank"; char *icon_name="Wave"; long event_mask; Pixmap icon_pixmap; char *display_name=NULL; int i; # define icon_bitmap_width 16 # define icon_bitmap_height 16 static char icon_bitmap_bits[] = { 0x1f, 0xf8, 0x1f, 0x88, 0x1f, 0x88, 0x1f, 0x88, 0x1f, 0x88, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; /* open up the display */ if ((display=XOpenDisplay(display_name))==NULL) {fprintf(stderr,"%s: cannot connect to X server %s\n", progname,XDisplayName(display_name)); exit(-1); } screen=DefaultScreen(display); cmap=DefaultColormap(display,screen); darkcolor=black=BlackPixel(display,screen); lightcolor=white=WhitePixel(display,screen); translate[WHITE]=white; translate[BLACK]=black; translate[2]=lightcolor; translate[3]=darkcolor; for(i=4;i<256;i++) translate[i]=translate[i%4]; if (DefaultDepth(display,screen)>1) { if (XAllocNamedColor(display,cmap,"salmon",&colorcell,&xcolor)) darkcolor=colorcell.pixel; if (XAllocNamedColor(display,cmap,"wheat",&colorcell,&xcolor)) lightcolor=colorcell.pixel; if (XAllocNamedColor(display,cmap,"red",&colorcell,&xcolor)) translate[RED]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"blue",&colorcell,&xcolor)) translate[BLUE]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"green",&colorcell,&xcolor)) translate[GREEN]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"cyan",&colorcell,&xcolor)) translate[CYAN]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"orange",&colorcell,&xcolor)) translate[ORANGE]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"purple",&colorcell,&xcolor)) translate[PURPLE]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"yellow",&colorcell,&xcolor)) translate[YELLOW]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"pink",&colorcell,&xcolor)) translate[PINK]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"brown",&colorcell,&xcolor)) translate[BROWN]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"grey",&colorcell,&xcolor)) translate[GREY]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"turquoise",&colorcell,&xcolor)) translate[TURQUOISE]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"gold",&colorcell,&xcolor)) translate[GOLD]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"magenta",&colorcell,&xcolor)) translate[MAGENTA]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"navy",&colorcell,&xcolor)) translate[NAVY]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"tan",&colorcell,&xcolor)) translate[TAN]=colorcell.pixel; if (XAllocNamedColor(display,cmap,"violet",&colorcell,&xcolor)) translate[VIOLET]=colorcell.pixel; } /* feel free to type in more colors, I got bored */ for(i=18;i<256;i++) translate[i]=translate[i%18]; /* make the main window */ windowwidth=6*BUTTONWIDTH; windowheight=600; playwidth=windowwidth; playheight=windowheight-3*BUTTONHEIGHT-1; window=XCreateSimpleWindow(display,RootWindow(display,screen), 0,0,windowwidth,windowheight,4,translate[14],lightcolor); /* make the icon */ icon_pixmap=XCreateBitmapFromData(display,window, icon_bitmap_bits,icon_bitmap_width,icon_bitmap_height); size_hints.flags=PPosition | PSize | PMinSize; size_hints.min_width=windowwidth; size_hints.min_height=100; #ifdef X11R3 size_hints.x=x; size_hints.y=y; size_hints.width=windowwidth; size_hints.height=windowheight; XSetStandardProperties(display,window,window_name,icon_name, icon_pixmap,argv,argc,&size_hints); #else {XWMHints wm_hints; XClassHint class_hints; XTextProperty windowName, iconName; if (XStringListToTextProperty(&window_name,1,&windowName)==0) {fprintf(stderr,"%s: structure allocation for windowName failed.\n" ,progname); exit(-1); } if (XStringListToTextProperty(&icon_name,1,&iconName)==0) {fprintf(stderr,"%s: structure allocation for iconName failed.\n" ,progname); exit(-1); } wm_hints.initial_state=NormalState; wm_hints.input=True; wm_hints.icon_pixmap=icon_pixmap; wm_hints.flags=StateHint|IconPixmapHint|InputHint; class_hints.res_name=progname; class_hints.res_class="Basicwin"; XSetWMProperties(display,window,&windowName,&iconName, argv,argc,&size_hints,&wm_hints,&class_hints); } #endif /* pick the events to look for */ event_mask=ExposureMask|ButtonPressMask|StructureNotifyMask; XSelectInput(display,window,event_mask); /* pick font: 9x15 is supposed to almost always be there */ if ((font=XLoadQueryFont(display,"9x15"))==NULL) if ((font=XLoadQueryFont(display,"fixed"))==NULL) {fprintf(stderr,"%s: Sorry, having font problems.\n",progname); exit(-1); } font_height=font->ascent+font->descent; font_width=font->max_bounds.width; /* make graphics context: */ gc1=XCreateGC(display,window,0,NULL); XSetFont(display,gc1,font->fid); XSetForeground(display,gc1,black); XSetBackground(display,gc1,lightcolor); gc2=XCreateGC(display,window,0,NULL); XSetFont(display,gc2,font->fid); XSetForeground(display,gc2,black); XSetBackground(display,gc2,lightcolor); /* show the window */ XMapWindow(display,window); return; } void makebuttons() { /* first destroy any old buttons */ XDestroySubwindows(display,window); /* now make the new buttons */ quitbutton=makebutton(0,windowheight-BUTTONHEIGHT,BUTTONWIDTH,BUTTONHEIGHT); vacuumbutton=makebutton(3*BUTTONWIDTH,windowheight-BUTTONHEIGHT, BUTTONWIDTH,BUTTONHEIGHT); pausebutton=makebutton(BUTTONWIDTH,windowheight-BUTTONHEIGHT, BUTTONWIDTH,BUTTONHEIGHT); dampbutton=makebutton(2*BUTTONWIDTH,windowheight-BUTTONHEIGHT, BUTTONWIDTH,BUTTONHEIGHT); reversebutton=makebutton(windowwidth-2*BUTTONWIDTH,windowheight-3*BUTTONHEIGHT ,BUTTONWIDTH,BUTTONHEIGHT); blobbutton=makebutton(windowwidth-BUTTONWIDTH,windowheight-3*BUTTONHEIGHT, BUTTONWIDTH,BUTTONHEIGHT); rightbutton=makebutton(windowwidth-2*BUTTONWIDTH,windowheight-2*BUTTONHEIGHT, BUTTONWIDTH,BUTTONHEIGHT); driftbutton=makebutton(windowwidth-BUTTONWIDTH,windowheight-2*BUTTONHEIGHT, BUTTONWIDTH,BUTTONHEIGHT); slowbutton=makebutton(windowwidth-BUTTONWIDTH,windowheight-BUTTONHEIGHT, BUTTONWIDTH,BUTTONHEIGHT); equbutton=makebutton(0,windowheight-3*BUTTONHEIGHT, 3*BUTTONWIDTH,BUTTONHEIGHT); packetbutton=makebutton(windowwidth-2*BUTTONWIDTH,windowheight-BUTTONHEIGHT, BUTTONWIDTH,BUTTONHEIGHT); return; } void cleanup() {XUnloadFont(display,font->fid); XFreeGC(display,gc1); XCloseDisplay(display); exit(1); } Window makebutton(xoffset,yoffset,xsize,ysize) int xoffset,yoffset,xsize,ysize; /* Puts button of specified dimensions on window. Nothing is drawn. */ {Window buttonwindow; long event_mask; buttonwindow=XCreateSimpleWindow(display,window,xoffset,yoffset, xsize,ysize,0,black,lightcolor); event_mask=ButtonPressMask|ExposureMask; /* look for mouse-button presses */ XSelectInput(display,buttonwindow,event_mask); XMapWindow(display,buttonwindow); return buttonwindow; } void drawbutton(buttonwindow,xoffset,yoffset,xsize,ysize,text,state) Window buttonwindow; int xoffset,yoffset,xsize,ysize,state; char * text; /* Draw a button in buttonwindow of specified dimensions with text centered. Color of button determined by sign of "state." size of border determined by magnitude. */ {int textlength,i,j; int cdark,clight,cup,cdown; int cleft,cright,cbutton,ctext; cup=lightcolor; cdown=darkcolor; cdark=black; clight=white; if (state<0) {cbutton=cdown; ctext=clight; cleft=cdark; cright=clight; } else {cbutton=cup; ctext=cdark; cleft=clight; cright=cdark; } j=abs(state); XSetForeground(display,gc1,cbutton); XFillRectangle(display,buttonwindow,gc1,xoffset+j,yoffset+j, xsize-2*j,ysize-2*j); XSetForeground(display,gc1,cleft); XFillRectangle(display,buttonwindow,gc1,xoffset,yoffset,xsize,j); XFillRectangle(display,buttonwindow,gc1,xoffset,yoffset,j,ysize); XSetForeground(display,gc1,cright); for (i=0;i>1; /* half the vector length */ /* recursively call fastfourier */ fastfourier(rex ,imx ,ref ,imf ,nd2,2*d1,d2,direction); fastfourier(rex+d1,imx+d1,ref+nd2*d2,imf+nd2*d2,nd2,2*d1,d2,direction); /* combine the results */ Ndn=NSITES/n; for (j=0;j