#include #include #include #include #include #include #include #define Interval 100 #define WinWidth 600 #define WinHeight 320 #define TrendHeight 100 #define TrendUnit 4 #define TrendSize (WinWidth/TrendUnit) #define PointSize 13 #define PointColor "red" #define AxisColor "white" #define GridColor "grey" #define FontName "*-courier-medium-r-normal--20-*-*" XtAppContext app_con; Widget app_sh, draw, trend, StartButton, StopButton, StepButton; Boolean Running = False; String fallback_resources[] = { "*FontList: *-helvetica-bold-r-*-140-75-*", "*background: grey90", "*.field.background: black", "*.field.foreground: yellow", "*.trend.background: NavyBlue", "*.command.marginWidth: 0", "*.command.marginHeight: 0", "*.command.spacing: 0", "*.alpha.titleString: alpha", "*.alpha.minimum: 2000", "*.alpha.maximum: 4000", "*.alpha.decimalPoints: 3", "*.ivalue.titleString: initial value", "*.ivalue.maximum: 1000", "*.ivalue.decimalPoints: 3", "*.Quit.accelerator: Altq", "*.Quit.acceleratorText: Alt+Q", NULL }; Display *dpy = NULL; GC gc; Window win,TrendWin; Pixmap pmap; XFontStruct *fst; Pixel fg, bg, pointPixel, axisPixel, gridPixel; int Nit = 0; double Alpha = 3.6, A0 = 0.2, An, Am; XPoint TrendP[TrendSize+1]; int TrendPCnt = 0; #define WinX(x) ((int)((x)*WinWidth*.9+WinWidth*.05)) #define WinY(y) (WinHeight-1-(int)((y)*WinWidth*.45+WinWidth*.05)) #define TrendY(y) (TrendHeight-1-(int)((y)*TrendHeight)) void setup_draw_info() { int i; XColor scol, ecol; dpy = XtDisplay(app_sh); gc = DefaultGC(dpy,0); win = XtWindow(draw); TrendWin = XtWindow(trend); pmap = XCreatePixmap(dpy,win,PointSize,PointSize,DefaultDepth(dpy,0)); XtVaGetValues(draw,XmNforeground,&fg,XmNbackground,&bg,NULL); XAllocNamedColor(dpy,DefaultColormap(dpy,0),PointColor,&scol,&ecol); pointPixel = scol.pixel; XAllocNamedColor(dpy,DefaultColormap(dpy,0),AxisColor,&scol,&ecol); axisPixel = scol.pixel; XAllocNamedColor(dpy,DefaultColormap(dpy,0),GridColor,&scol,&ecol); gridPixel = scol.pixel; fst = XLoadQueryFont(dpy,FontName); if (fst) XSetFont(dpy,gc,fst->fid); XSetLineAttributes(dpy,gc,2,LineSolid,CapRound,JoinRound); for (i = 0; i <= TrendSize; i ++) TrendP[i].x = i * TrendUnit; } void one_step() { Am = An; An = (1. - An) * An * Alpha; Nit ++; } void draw_one_step(a1,a2) double a1, a2; { XPoint p[3]; p[0].x = WinX(a1); p[0].y = WinY(a1); p[1].x = p[0].x; p[1].y = WinY(a2); p[2].x = WinX(a2); p[2].y = p[1].y; XDrawLines(dpy,win,gc,p,3,CoordModeOrigin); } int OldPX = -9999, OldPY; void erase_point() { if (OldPX > -PointSize) XCopyArea(dpy,pmap,win,gc, 0,0,PointSize,PointSize,OldPX,OldPY); } void plot_point() { int x, y; x = WinX(An) - PointSize/2; y = WinY(An) - PointSize/2; if (x > -PointSize && x < WinWidth && y > -PointSize && y < WinHeight) { XCopyArea(dpy,win,pmap,gc,x,y,PointSize,PointSize,0,0); XFillArc(dpy,win,gc,x,y,PointSize,PointSize,0,64*360); OldPX = x; OldPY = y; } else OldPX = -9999; } void redisplay() { int z, i; double a; XPoint p[2]; XSetForeground(dpy,gc,gridPixel); for (i = 1; i < 11; i ++) { z = WinX(i*.1); XDrawLine(dpy,win,gc,z,0,z,WinHeight-1); z = WinY(i*.1); XDrawLine(dpy,win,gc,0,z,WinWidth-1,z); } XDrawLine(dpy,win,gc,WinX(-.1),WinY(-.1),WinX(1.1),WinY(1.1)); for (a = -.1; a <= 1.1; a += 0.05) { p[0] = p[1]; p[1].x = WinX(a); p[1].y = WinY((1. - a) * a * Alpha); if (a > -1.) XDrawLines(dpy,win,gc,p,2,CoordModeOrigin); } XSetForeground(dpy,gc,axisPixel); z = WinY(0); XDrawLine(dpy,win,gc,0,z,WinWidth-1,z); z = WinX(0); XDrawLine(dpy,win,gc,z,0,z,WinHeight-1); XSetForeground(dpy,gc,fg); i = Nit; Nit = 0; An = Am = A0; while (Nit < i-1) { one_step(); draw_one_step(Am,An); } XSetForeground(dpy,gc,pointPixel); if (i > Nit) { one_step(); draw_one_step(Am,An); } plot_point(); } void reset() { XClearWindow(dpy,win); XClearWindow(dpy,TrendWin); Nit = 0; An = Am = A0; TrendPCnt = 0; TrendP[0].y = TrendY(A0); redisplay(); } void work_one_step(cl,id) XtPointer cl; XtIntervalId *id; { int ndp; erase_point(); if (Am != An) { XSetForeground(dpy,gc,fg); draw_one_step(Am,An); } XSetForeground(dpy,gc,pointPixel); one_step(); plot_point(); draw_one_step(Am,An); if (TrendPCnt >= TrendSize) { int i; for (i = 0; i < TrendSize; i ++) TrendP[i].y = TrendP[i+1].y; XCopyArea(dpy,TrendWin,TrendWin,gc,TrendUnit,0, WinWidth-TrendUnit,TrendHeight,0,0); XClearArea(dpy,TrendWin,WinWidth-TrendUnit,0, TrendUnit,TrendHeight,False); ndp = 3; } else { TrendPCnt ++; ndp = 2; } TrendP[TrendPCnt].y = TrendY(An); XSetForeground(dpy,gc,axisPixel); XDrawLines(dpy,TrendWin,gc,TrendP+TrendPCnt-ndp+1,ndp, CoordModeOrigin); if (Running) XtAppAddTimeOut(app_con,Interval,work_one_step,NULL); } void RedrawCB(w,cl,cd) Widget w; XtPointer cl,cd; { XmDrawingAreaCallbackStruct *d = (XmDrawingAreaCallbackStruct *)cd; XExposeEvent *e = &(d->event->xexpose); redisplay(); } void ResetCB(w,cl,cd) Widget w; XtPointer cl,cd; { reset(); } void QuitCB(w,cl,cd) Widget w; XtPointer cl,cd; { exit(0);} void StartCB(w,cl,cd) Widget w; XtPointer cl,cd; { Running = True; XtAppAddTimeOut(app_con,Interval,work_one_step,NULL); XtVaSetValues(StartButton,XmNsensitive,False,NULL); XtVaSetValues(StopButton,XmNsensitive,True,NULL); XtVaSetValues(StepButton,XmNsensitive,False,NULL); } void StopCB(w,cl,cd) Widget w; XtPointer cl,cd; { Running = False; XtVaSetValues(StopButton,XmNsensitive,False,NULL); XtVaSetValues(StartButton,XmNsensitive,True,NULL); XtVaSetValues(StepButton,XmNsensitive,True,NULL); } void StepCB(w,cl,cd) Widget w; XtPointer cl,cd; { Running = False; XtAppAddTimeOut(app_con,4,work_one_step,NULL); } void ValueCB(w,cl,cd) Widget w; XtPointer cl,cd; { XmScaleCallbackStruct *cs = (XmScaleCallbackStruct *)cd; *((double *)cl) = cs->value * 0.001; reset(); } void RedrawTrendCB(w,cl,cd) Widget w; XtPointer cl,cd; { if (TrendPCnt <= 0) return; XSetForeground(dpy,gc,axisPixel); XDrawLines(dpy,TrendWin,gc,TrendP,TrendPCnt+1,CoordModeOrigin); } main(argc,argv) int argc; char *argv[]; { Widget main_win, menu_bar, menu, button, command, scale; Arg args[8]; int n; app_sh = XtAppInitialize(&app_con,"Logistic map",NULL,0, &argc,argv,fallback_resources,NULL,0); XtSetArg(args[0],XmNshowSeparator,True); XtManageChild(main_win=XmCreateMainWindow(app_sh,"main",args,1)); XtManageChild(menu_bar=XmCreateMenuBar(main_win,"bar",NULL,0)); menu = XmCreatePulldownMenu(menu_bar,"FileMenu",NULL,0); XtManageChild(button=XmCreatePushButton(menu,"Reset",NULL,0)); XtAddCallback(button,XmNactivateCallback,ResetCB,NULL); XtManageChild(button=XmCreatePushButton(menu,"Quit",NULL,0)); XtAddCallback(button,XmNactivateCallback,QuitCB,NULL); XtSetArg(args[0],XmNsubMenuId,menu); XtManageChild(XmCreateCascadeButton(menu_bar,"File",args,1)); StepButton = XmCreateCascadeButton(menu_bar,"Step",NULL,0); XtManageChild(StepButton); XtAddCallback(StepButton,XmNactivateCallback,StepCB,NULL); StartButton = XmCreateCascadeButton(menu_bar,"Start",NULL,0); XtManageChild(StartButton); XtAddCallback(StartButton,XmNactivateCallback,StartCB,NULL); XtSetArg(args[0],XmNsensitive,False); StopButton = XmCreateCascadeButton(menu_bar,"Stop",args,1); XtManageChild(StopButton); XtAddCallback(StopButton,XmNactivateCallback,StopCB,NULL); XtSetArg(args[0],XmNorientation,XmVERTICAL); XtManageChild(command=XmCreateRowColumn(main_win,"command",args,1)); XtSetArg(args[0],XmNorientation,XmHORIZONTAL); XtSetArg(args[1],XmNshowValue,True); XtSetArg(args[2],XmNvalue,(int)(Alpha*1000)); XtManageChild(scale=XmCreateScale(command,"alpha",args,3)); XtAddCallback(scale,XmNvalueChangedCallback, ValueCB,(XtPointer)(&Alpha)); XtSetArg(args[2],XmNvalue,(int)(A0*1000)); XtManageChild(scale=XmCreateScale(command,"ivalue",args,3)); XtAddCallback(scale,XmNvalueChangedCallback, ValueCB,(XtPointer)(&A0)); XtSetArg(args[0],XmNwidth,WinWidth); XtSetArg(args[1],XmNheight,WinHeight); XtManageChild(draw=XmCreateDrawingArea(main_win,"field",args,2)); XtSetArg(args[1],XmNheight,TrendHeight); XtManageChild(trend=XmCreateDrawingArea(main_win,"trend",args,2)); /* XtVaSetValues(main_win,XmNcommandWindow,command, XmNmessageWindow,trend,XmNworkWindow,draw,NULL); */ XtVaSetValues(main_win,XmNcommandWindow,draw, XmNworkWindow,trend, XmNmessageWindow,command,NULL); XtRealizeWidget(app_sh); setup_draw_info(draw); reset(); XtAddCallback(draw,XmNexposeCallback,RedrawCB,NULL); XtAddCallback(trend,XmNexposeCallback,RedrawTrendCB,NULL); XtAppMainLoop(app_con); }