00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifdef _windows
00012 #include "display_win.cpp"
00013 #else
00014
00015 #include "display.h"
00016 #ifdef TMCC
00017 extern "C"
00018 #endif
00019
00020 unsigned long colorconvert_16[3][6]={{0xF8,8,0,0xF800,11,0x1F},
00021 {0xF8,3,0,0x7C0, 6,0x1F},
00022 {0xF8,0,0,0x1F, 0,0x1F}};
00023 unsigned long colorconvert_32[3][6]={{0xFF,16,0,0xFF0000,16,0xFF},
00024 {0xFF, 8,0,0xFF00, 8,0xFF},
00025 {0xFF, 0,0,0xFF, 0,0xFF}};
00026
00027 int SYWindow::cmp(const void *p1, const void *p2)
00028 {
00029
00030 if (((struct SYWindow::ZInd *)p1)->Z < ((struct SYWindow::ZInd *)p2)->Z)
00031 return -1;
00032 else if (((struct SYWindow::ZInd *)p1)->Z == ((struct SYWindow::ZInd *)p2)->Z)
00033 return 0;
00034 else
00035 return 1;
00036 }
00037
00038 #ifndef NO_THREAD
00039 #ifdef TMCC
00040 extern "C"
00041 #endif
00042 void * SYWindow::thread_routine(void *p)
00043 {
00044 ((SYWindow *)p)->Routine();
00045 return NULL;
00046 }
00047 void SYWindow::Run()
00048 {
00049 int r;
00050 pthread_t thread;
00051 r=pthread_create(&thread, NULL, thread_routine, this);
00052 #ifdef _GENERAL_H
00053
00054 if(r!=0) FATAL("Fail to create thread: ["<<strerror(errno)<<"]");
00055 #else
00056 if(r!=0) fprintf(stderr,"Fail to create thread\n");
00057 #endif
00058 }
00059 #endif
00060
00061 void SYWindow::Draw3DLine(YLine line)
00062 {
00063 double x1,y1,x2,y2; unsigned attr;
00064 double xs1, ys1, zs1, xs2, ys2, zs2, Z, r;
00065 unsigned long col=cblack;
00066
00067 attr = line.attr;
00068 xs1 = line.x0;
00069 ys1 = line.y0;
00070 zs1 = line.z0;
00071 Z=A31*xs1+A32*ys1+A33*zs1;
00072
00073 #define PBCSHIFT(a,shift,origin) if(enable_pbc){a-=origin;a/=2;a+=shift;a-=rint(a);a*=2;a+=origin;}
00074
00075 PBCSHIFT(xs1,pbcshift[0],0);
00076 PBCSHIFT(ys1,-pbcshift[1],0);
00077 PBCSHIFT(zs1,pbcshift[2],0);
00078
00079 x1=CX(A11*xs1+A12*ys1+A13*zs1,Z);
00080 y1=CY(A21*xs1+A22*ys1+A23*zs1,Z);
00081 xs2 = line.x1;
00082 ys2 = line.y1;
00083 zs2 = line.z1;
00084
00085 PBCSHIFT(xs2,pbcshift[0],xs1);
00086 PBCSHIFT(ys2,-pbcshift[1],ys1);
00087 PBCSHIFT(zs2,pbcshift[2],zs1);
00088
00089 Z=A31*xs2+A32*ys2+A33*zs2;
00090 x2=CX(A11*xs2+A12*ys2+A13*zs2,Z);
00091 y2=CY(A21*xs2+A22*ys2+A23*zs2,Z);
00092
00093
00094 if((((x1<0)||(x1>(int)width))||((y1<0)||(y1>(int)height)))
00095 &&(((x2<0)||(x2>(int)width))||((y2<0)||(y2>(int)height))))
00096 return;
00097
00098 if(x1!=x2 || y1!=y2)
00099 {
00100 if(col!=line.c)
00101 XSetForeground(theDisplay, gc, col=line.c);
00102 if(attr==0)
00103 {
00104 r=CR(line.r,0);
00105 if(r<1) r=1;
00106 if(r>maxlinewidth) r=maxlinewidth;
00107
00108 XSetLineAttributes(theDisplay, gc, (int)r,
00109 LineSolid, CapRound, JoinRound);
00110 XDrawLine(theDisplay, pixmap, gc, (int)x1,(int)y1,(int)x2,(int)y2);
00111 }
00112 else
00113 {
00114 XPoint points[5]; double dy,dx,dr,r;
00115 dy=y2-y1;dx=x2-x1;dr=sqrt(dy*dy+dx*dx);dy/=dr;dx/=dr;
00116 r=CR(line.r,0);
00117 if(r<1) r=1;
00118 if(r>maxlinewidth) r=maxlinewidth;
00119
00120 points[0].x=(int)(x1-dy*r/2);points[0].y=(int)(y1+dx*r/2);
00121 points[1].x=(int)(x1+dy*r/2);points[1].y=(int)(y1-dx*r/2);
00122 points[2].x=(int)(x2+dy*r/2);points[2].y=(int)(y2-dx*r/2);
00123 points[3].x=(int)(x2-dy*r/2);points[3].y=(int)(y2+dx*r/2);
00124 points[4].x=points[0].x;points[4]=points[0];
00125
00126
00127
00128
00129 XSetLineAttributes(theDisplay, gc, (int)r,
00130 LineSolid, CapRound, JoinRound);
00131 XDrawLine(theDisplay, pixmap, gc, (int)x1,(int)y1,(int)x2,(int)y2);
00132 XSetLineAttributes(theDisplay, gc, 1,
00133 LineSolid, CapRound, JoinRound);
00134 XSetForeground(theDisplay, gc, cblack);
00135 XDrawLines(theDisplay, pixmap, gc, points+1, 2,
00136 CoordModeOrigin);
00137 XDrawLines(theDisplay, pixmap, gc, points+3, 2,
00138 CoordModeOrigin);
00139 }
00140 }
00141 }
00142
00143 void SYWindow::Draw3DPixel(YPoint point)
00144 {
00145 int x,y; double r; unsigned attr;
00146 double xs, ys, zs, Z;
00147 unsigned long col=cblack;
00148
00149 xs = point.x;
00150 ys = point.y;
00151 zs = point.z;
00152
00153 PBCSHIFT(xs,pbcshift[0],0);
00154 PBCSHIFT(ys,-pbcshift[1],0);
00155 PBCSHIFT(zs,pbcshift[2],0);
00156
00157 attr = point.attr;
00158 Z=A31*xs+A32*ys+A33*zs;
00159 x=(int)CX(A11*xs+A12*ys+A13*zs,Z);
00160 y=(int)CY(A21*xs+A22*ys+A23*zs,Z);
00161 r=CR(point.r,Z);
00162
00163 if(r>maxpointradius) r=maxpointradius;
00164
00165 if(((x<-r)||(x>(int)width+r))||((y<-r)||(y>(int)height+r))) return;
00166 XSetLineAttributes(theDisplay, gc, 1,
00167 LineSolid, CapRound, JoinRound);
00168 if(col!=point.c)
00169 XSetForeground(theDisplay, gc, col=point.c);
00170
00171
00172 if(r<0.5) XDrawPoint(theDisplay, pixmap, gc, x, y);
00173 else if(r<=1)
00174 {
00175 XDrawPoint(theDisplay, pixmap, gc, x+1, y);
00176 XDrawPoint(theDisplay, pixmap, gc, x, y);
00177 XDrawPoint(theDisplay, pixmap, gc, x, y+1);
00178 XDrawPoint(theDisplay, pixmap, gc, x+1, y+1);
00179 }
00180 else if(r<=1.5)
00181 {
00182
00183 XDrawPoint(theDisplay, pixmap, gc, x+1, y);
00184 XDrawPoint(theDisplay, pixmap, gc, x-1, y);
00185 XDrawPoint(theDisplay, pixmap, gc, x, y+1);
00186 XDrawPoint(theDisplay, pixmap, gc, x+1, y+1);
00187 XDrawPoint(theDisplay, pixmap, gc, x-1, y+1);
00188 XDrawPoint(theDisplay, pixmap, gc, x, y-1);
00189 XDrawPoint(theDisplay, pixmap, gc, x+1, y-1);
00190 XDrawPoint(theDisplay, pixmap, gc, x-1, y-1);
00191 }
00192 else
00193 {
00194 if((attr==0)||(attr==2))
00195 {
00196 XSetForeground(theDisplay, gc, point.c);
00197 XFillArc(theDisplay, pixmap, gc, (int)(x-r),(int)(y-r),
00198 (int)(r*2),(int)(r*2),0,23040);
00199 XSetForeground(theDisplay, gc, cblack);
00200 XDrawArc(theDisplay, pixmap, gc, (int)(x-r),(int)(y-r),
00201 (int)(r*2),(int)(r*2),0,23040);
00202 }
00203 else if(attr==1)
00204 {
00205 XDrawArc(theDisplay, pixmap, gc, (int)(x-r),(int)(y-r),
00206 (int)(r*2),(int)(r*2),0,23040);
00207 }
00208 else
00209 {
00210 XSetForeground(theDisplay, gc, point.c);
00211 XFillArc(theDisplay, pixmap, gc, (int)(x-r),(int)(y-r),
00212 (int)(r*2),(int)(r*2),0,23040);
00213 }
00214 }
00215 }
00216
00217 void SYWindow::paint()
00218 {
00219 int i;
00220
00221 double xs, ys, zs;
00222
00223 if (sort)
00224 {
00225 for(i=0;i<nL;i++)
00226 {
00227 xs=(Lines[i].x0+Lines[i].x1)/2;
00228 ys=(Lines[i].y0+Lines[i].y1)/2;
00229 zs=(Lines[i].z0+Lines[i].z1)/2;
00230
00231 PBCSHIFT(xs,pbcshift[0],0);
00232 PBCSHIFT(ys,-pbcshift[1],0);
00233 PBCSHIFT(zs,pbcshift[2],0);
00234
00235 Z_ind[i].Z=A31*xs+A32*ys+A33*zs;
00236 Z_ind[i].index=i;
00237 }
00238 for(i=0;i<nP;i++)
00239 {
00240 xs = Points[i].x;
00241 ys = Points[i].y;
00242 zs = Points[i].z;
00243
00244 PBCSHIFT(xs,pbcshift[0],0);
00245 PBCSHIFT(ys,-pbcshift[1],0);
00246 PBCSHIFT(zs,pbcshift[2],0);
00247
00248 Z_ind[i+nL].Z=A31*xs+A32*ys+A33*zs;
00249 Z_ind[i+nL].index=i+nL;
00250 }
00251
00252 qsort(Z_ind, nL+nP, sizeof(struct ZInd), &cmp);
00253
00254 for(i=0;i<nL+nP;i++)
00255 {
00256 int n=Z_ind[i].index;
00257 if(n<nL) Draw3DLine(Lines[n]);
00258 else Draw3DPixel(Points[n-nL]);
00259 }
00260
00261
00262 }
00263 else
00264 {
00265 for(i=0;i<nL;i++)
00266 {
00267 Draw3DLine(Lines[i]);
00268 }
00269 for(i=0;i<nP;i++)
00270 {
00271 Draw3DPixel(Points[i]);
00272 }
00273 }
00274 }
00275 #if 0
00276 void SYWindow::paint()
00277 {
00278 int i;
00279 double xs, ys, zs, Z;
00280 unsigned long col=cblack;
00281
00282 if(!alive) return;
00283
00284 {
00285 int x1, y1, x2, y2;
00286 XSetLineAttributes(theDisplay, gc, 2, LineSolid, CapButt, JoinMiter);
00287 for(i=0;i<nL;i++)
00288 {
00289 xs = Lines[i].x0;
00290 ys = Lines[i].y0;
00291 zs = Lines[i].z0;
00292 Z=A31*xs+A32*ys+A33*zs;
00293 x1=CX(A11*xs+A12*ys+A13*zs,Z);
00294 y1=CY(A21*xs+A22*ys+A23*zs,Z);
00295 xs = Lines[i].x1;
00296 ys = Lines[i].y1;
00297 zs = Lines[i].z1;
00298 Z=A31*xs+A32*ys+A33*zs;
00299 x2=CX(A11*xs+A12*ys+A13*zs,Z);
00300 y2=CY(A21*xs+A22*ys+A23*zs,Z);
00301
00302
00303 if((((x1<0)||(x1>(int)width))||((y1<0)||(y1>(int)height)))
00304 &&(((x2<0)||(x2>(int)width))||((y2<0)||(y2>(int)height))))
00305 continue;
00306
00307 if(x1!=x2 || y1!=y2)
00308 {
00309 if(col!=Lines[i].c)
00310 XSetForeground(theDisplay, gc, col=Lines[i].c);
00311 XDrawLine(theDisplay, pixmap, gc, x1,y1,x2,y2);
00312 }
00313 }
00314 }
00315
00316 for(i=0;i<nP;i++)
00317 {
00318 int x, y, r; unsigned attr;
00319 xs = Points[i].x;
00320 ys = Points[i].y;
00321 zs = Points[i].z;
00322 attr = Points[i].attr;
00323 Z=A31*xs+A32*ys+A33*zs;
00324 x=CX(A11*xs+A12*ys+A13*zs,Z);
00325 y=CY(A21*xs+A22*ys+A23*zs,Z);
00326 r=CR(Points[i].r);
00327 if(((x<-r)||(x>(int)width+r))||((y<-r)||(y>(int)height+r))) continue;
00328 if(col!=Points[i].c)
00329 XSetForeground(theDisplay, gc, col=Points[i].c);
00330
00331
00332 if(r<=1) XDrawPoint(theDisplay, pixmap, gc, x, y);
00333 else if(r<=2)
00334 {
00335 XDrawPoint(theDisplay, pixmap, gc, x+1, y);
00336 XDrawPoint(theDisplay, pixmap, gc, x, y);
00337 XDrawPoint(theDisplay, pixmap, gc, x, y+1);
00338 XDrawPoint(theDisplay, pixmap, gc, x+1, y+1);
00339 }
00340 else if(r<=3)
00341 {
00342
00343 XDrawPoint(theDisplay, pixmap, gc, x+1, y);
00344 XDrawPoint(theDisplay, pixmap, gc, x-1, y);
00345 XDrawPoint(theDisplay, pixmap, gc, x, y+1);
00346 XDrawPoint(theDisplay, pixmap, gc, x+1, y+1);
00347 XDrawPoint(theDisplay, pixmap, gc, x-1, y+1);
00348 XDrawPoint(theDisplay, pixmap, gc, x, y-1);
00349 XDrawPoint(theDisplay, pixmap, gc, x+1, y-1);
00350 XDrawPoint(theDisplay, pixmap, gc, x-1, y-1);
00351 }
00352 else
00353 if(attr==0)
00354 XFillArc(theDisplay, pixmap, gc, x-r,y-r,r*2,r*2,0,23040);
00355 else
00356 XDrawArc(theDisplay, pixmap, gc, x-r,y-r,r*2,r*2,0,23040);
00357 }
00358 }
00359 #endif
00360
00361 int SYWindow::identify(int px, int py)
00362 {
00363 int i;
00364 int hit;
00365 double xs, ys, zs, Z;
00366 hit=-1;
00367 for(i=0;i<nP;i++)
00368 {
00369 int x, y, r;
00370 if(Points[i].dscrpt[0]!=0)
00371 {
00372 xs = Points[i].x;
00373 ys = Points[i].y;
00374 zs = Points[i].z;
00375
00376 PBCSHIFT(xs,pbcshift[0],0);
00377 PBCSHIFT(ys,-pbcshift[1],0);
00378 PBCSHIFT(zs,pbcshift[2],0);
00379
00380 Z=A31*xs+A32*ys+A33*zs;
00381 x=(int)CX(A11*xs+A12*ys+A13*zs,Z);
00382 y=(int)CY(A21*xs+A22*ys+A23*zs,Z);
00383 r=(int)CR(Points[i].r,Z);
00384 if((px<x+r)&&(px>x-r)&&(py<y+r)&&(py>y-r))
00385 {
00386 hit=i;
00387 #ifdef _GENERAL_H
00388 INFO("point("<<px<<","<<py<<"): "<<Points[i].dscrpt);
00389 #else
00390 fprintf(stdout,"point (%d,%d): %s\n",px,py,Points[i].dscrpt);
00391 #endif
00392 }
00393 }
00394 }
00395 return hit;
00396 }
00397
00398 void SYWindow::update()
00399 {
00400 if(!alive) return;
00401 Lock();
00402
00403 XSetForeground(theDisplay, gc, bgcolor);
00404
00405 XFillRectangle(theDisplay, pixmap, gc, 0, 0,
00406 width,height);
00407 paint();
00408
00409 XCopyArea(theDisplay,pixmap,theWindow,gc,0,0,width,height,0,0);
00410 Unlock();
00411 }
00412
00413
00414 void SYWindow::newGraph()
00415 {
00416 unsigned int Rg, w, h;
00417 unsigned int border_width;
00418 int xself, yself;
00419
00420 XGetGeometry(theDisplay, theWindow,
00421 &Root,&xself,&yself,&w,&h,
00422 &border_width,&depth);
00423
00424 Rg=w< h?w:h;
00425 if(!alive)
00426 {
00427 alive=true;
00428 goto init;
00429 }
00430 if(width!=w || height!=h)
00431 {
00432 XFreeGC(theDisplay, gc);
00433 XFreePixmap(theDisplay, pixmap);
00434 init:
00435 R=(Rg+1)/2-5;
00436 #ifndef M_SQRT3 //sqrt(3)
00437 #define M_SQRT3 1.73205080756887729353
00438 #endif
00439 B=(int)(R/M_SQRT3);
00440 double rx0=((double)X0)/width,ry0=((double)Y0)/height;
00441 X0=(int)(rx0*w);
00442 Y0=(int)(ry0*h);
00443 width=w; height=h;
00444 pixmap = XCreatePixmap(theDisplay, Root, width,height,depth);
00445 gc = XCreateGC(theDisplay, pixmap, 0, 0);
00446 }
00447 dirty=true;
00448 }
00449
00450 void SYWindow::Evolve()
00451 {
00452 XEvent ev; KeySym ks;
00453 if(!alive) return;
00454 XSync(theDisplay, false);
00455 if(dirty)
00456 {
00457 dirty=false;
00458 update();
00459 }
00460 #ifndef NO_XPM
00461 if(autowritegif)
00462 {
00463 writegif();
00464 UnlockWritegif();
00465 }
00466 #endif
00467 while(XPending(theDisplay))
00468 {
00469 XNextEvent(theDisplay, &ev);
00470 switch(ev.type)
00471 {
00472 case ButtonPress:
00473 Xp=ev.xbutton.x;
00474 Yp=ev.xbutton.y;
00475 identify(Xp,Yp);
00476 break;
00477 case Expose:
00478 newGraph();
00479 break;
00480 case KeyPress:
00481 ks=XKeycodeToKeysym(theDisplay,ev.xkey.keycode,0);
00482 switch (ks)
00483 {
00484 case XK_Escape:
00485 FreeResource(); return;
00486 #ifdef _GENERAL_H
00487 case XK_p: TogglePause();INFO("Pause="<<pause);return;
00488 #else
00489 case XK_p: TogglePause();
00490 fprintf(stdout,"Pause=%d",(int)pause);return;
00491 #endif
00492 #ifndef NO_XPM
00493
00494 #endif
00495 case XK_F9: importgif(); return;
00496 case XK_F10: writeps(); return;
00497 case XK_Up:
00498 switch(msrsp){
00499 case(SCALING):Scale/=1.1;dirty=true;break;
00500 case(TRANSLATION):Y0-=5;dirty=true;break;
00501 case(ASPECTRATIO):Aspr*=1.1;dirty=true;break;
00502 } break;
00503 case XK_Down:
00504 switch(msrsp){
00505 case(SCALING):Scale*=1.1;dirty=true;break;
00506 case(TRANSLATION):Y0+=5;dirty=true;break;
00507 case(ASPECTRATIO):Aspr/=1.1;dirty=true;break;
00508 } break;
00509 case XK_Left:
00510 switch(msrsp){
00511 case(SCALING):Scale/=1.1;dirty=true;break;
00512 case(TRANSLATION):X0-=5;dirty=true;break;
00513 case(ASPECTRATIO):Scale/=1.1;Aspr*=1.1;dirty=true;break;
00514 } break;
00515 case XK_Right:
00516 switch(msrsp){
00517 case(SCALING):Scale*=1.1;dirty=true;break;
00518 case(TRANSLATION):X0+=5;dirty=true;break;
00519 case(ASPECTRATIO):Scale*=1.1;Aspr/=1.1;dirty=true;break;
00520 } break;
00521 case XK_Home:
00522 X0=X00;Y0=Y00;Scale=Scale0;Aspr=Aspr0;
00523 dirty=true;break;
00524 case XK_a:msrsp=ASPECTRATIO;dirty=true;break;
00525 case XK_s:msrsp=SCALING;dirty=true;break;
00526 case XK_t:msrsp=TRANSLATION;dirty=true;break;
00527 default: ExtKeyHandler(ks); break;
00528 }
00529 default: break;
00530 }
00531 }
00532 }
00533
00534 void SYWindow::DrawPoint(double x, double y, double z, double r,
00535 unsigned long c, unsigned long attr)
00536 {
00537 if(nP<MaxPoints-1)
00538 {
00539 Points[nP].x=x;
00540 Points[nP].y=y;
00541 Points[nP].z=z;
00542 Points[nP].r=r;
00543 Points[nP].c=c;
00544 Points[nP].attr=attr;
00545 Points[nP].dscrpt[0]=0;
00546 nP++;
00547 }
00548 else if(nP==MaxPoints-1)
00549 {
00550 #ifdef _GENERAL_H
00551 WARNING("SYWindow: Too many points (more than "
00552 << (int)MaxPoints
00553 << "), ignoring");
00554 #else
00555 fprintf(stderr,"SYWindow: Too many points (more than %d"
00556 "), ignoring\n\n", (int)MaxPoints );
00557 #endif
00558 Points[nP].x=x;
00559 Points[nP].y=y;
00560 Points[nP].z=z;
00561 Points[nP].r=r;
00562 Points[nP].c=c;
00563 Points[nP].attr=attr;
00564 Points[nP].dscrpt[0]=0;
00565 nP++;
00566 }
00567 }
00568
00569 void SYWindow::DrawPoint(double x, double y, double z, double r,
00570 unsigned long c, char *ds, unsigned long attr)
00571 {
00572 if(nP<MaxPoints-1)
00573 {
00574 Points[nP].x=x;
00575 Points[nP].y=y;
00576 Points[nP].z=z;
00577 Points[nP].r=r;
00578 Points[nP].c=c;
00579 Points[nP].attr=attr;
00580 strncpy(Points[nP].dscrpt,ds,DSCLEN-1);
00581 nP++;
00582 }
00583 else if (nP==MaxPoints-1)
00584 {
00585 #ifdef _GENERAL_H
00586 WARNING("SYWindow: Too many points (more than "
00587 << (int)MaxPoints
00588 << "), ignoring");
00589 #else
00590 fprintf(stderr,"SYWindow: Too many points (more than %d"
00591 "), ignoring", (int)MaxPoints );
00592 #endif
00593 Points[nP].x=x;
00594 Points[nP].y=y;
00595 Points[nP].z=z;
00596 Points[nP].r=r;
00597 Points[nP].c=c;
00598 Points[nP].attr=attr;
00599 strncpy(Points[nP].dscrpt,ds,DSCLEN-1);
00600 nP++;
00601 }
00602
00603 }
00604
00605 void SYWindow::DrawLine(double x0, double y0, double z0,
00606 double x1, double y1, double z1, unsigned long c,
00607 double r, unsigned long attr)
00608 {
00609 if(nL<MaxLines-1)
00610 {
00611 Lines[nL].x0=x0;
00612 Lines[nL].y0=y0;
00613 Lines[nL].z0=z0;
00614 Lines[nL].x1=x1;
00615 Lines[nL].y1=y1;
00616 Lines[nL].z1=z1;
00617 Lines[nL].c=c;
00618 Lines[nL].r=r;
00619 Lines[nL].attr=attr;
00620 nL++;
00621 }
00622 else if(nL==MaxLines-1)
00623 {
00624 #ifdef _GENERAL_H
00625 WARNING("SYWindow: Too many lines (more than "
00626 << (int)MaxLines
00627 << "), ignoring");
00628 #else
00629 fprintf(stderr,"SYWindow: Too many lines (more than %d"
00630 "), ignoring\n\n", (int)MaxLines );
00631 #endif
00632 Lines[nL].x0=x0;
00633 Lines[nL].y0=y0;
00634 Lines[nL].z0=z0;
00635 Lines[nL].x1=x1;
00636 Lines[nL].y1=y1;
00637 Lines[nL].z1=z1;
00638 Lines[nL].c=c;
00639 Lines[nL].r=r;
00640 Lines[nL].attr=attr;
00641 nL++;
00642 }
00643 }
00644
00645 SYWindow::SYWindow(int width_hint, int height_hint,
00646 const char *winname, bool s, bool so, bool fm)
00647 {
00648 XSizeHints myhint;
00649 unsigned long mask;
00650 Cursor arrow;
00651 int i,j;
00652
00653
00654 initRot();copyRot();
00655 theDisplay = XOpenDisplay(getenv("DISPLAY"));
00656 theScreen = DefaultScreen(theDisplay);
00657
00658 cblack = BlackPixel(theDisplay,theScreen);
00659 cwhite = WhitePixel(theDisplay,theScreen);
00660 bgcolor=cblack;
00661 myhint.x = 100;
00662 myhint.y = 100;
00663 myhint.width = width_hint;
00664 myhint.height = height_hint;
00665 myhint.flags = PPosition | PSize;
00666
00667 width=width_hint;
00668 height=height_hint;
00669
00670 ksfeedback=0;
00671
00672 Root = RootWindow(theDisplay,theScreen);
00673 cmap = DefaultColormap(theDisplay, theScreen);
00674
00675
00676
00677
00678 PixDepth = 0;
00679
00680 if( XMatchVisualInfo(theDisplay,theScreen,32,TrueColor,&visinfo) ||
00681 XMatchVisualInfo(theDisplay,theScreen,32,DirectColor,&visinfo) )
00682 {
00683 PixDepth = 32;
00684 }else if( XMatchVisualInfo(theDisplay,theScreen,24,TrueColor,&visinfo) ||
00685 XMatchVisualInfo(theDisplay,theScreen,24,DirectColor,&visinfo) )
00686 { PixDepth = 24;
00687 }
00688 else if( XMatchVisualInfo(theDisplay,theScreen,16,TrueColor,&visinfo) ||
00689 XMatchVisualInfo(theDisplay,theScreen,32,DirectColor,&visinfo) )
00690 { PixDepth = 16;
00691 }
00692 else if( XMatchVisualInfo(theDisplay,theScreen,8,PseudoColor,&visinfo) ||
00693 XMatchVisualInfo(theDisplay,theScreen,8,GrayScale,&visinfo) )
00694 { PixDepth = 8;
00695 }
00696
00697 #ifdef _GENERAL_H
00698 INFO("PixDepth="<<PixDepth);
00699 #else
00700 printf("PixDepth=%d",PixDepth);
00701 #endif
00702 if(PixDepth==16)
00703 {
00704 for(i=0;i<3;i++)
00705 for(j=0;j<6;j++)
00706 CCT[i][j]=colorconvert_16[i][j];
00707 }
00708 else
00709 {
00710 for(i=0;i<3;i++)
00711 for(j=0;j<6;j++)
00712 CCT[i][j]=colorconvert_32[i][j];
00713 }
00714
00715 if((PixDepth!=0)&1)
00716 {
00717 vis=visinfo.visual;
00718 cblack=AllocShortRGBColor(0,0,0);
00719 cwhite=AllocShortRGBColor(255,255,255);
00720 #ifdef _GENERAL_H
00721 INFO_Printf("visual=%x\n",vis);
00722 #else
00723 printf("visual=%x\n",vis);
00724 #endif
00725 if( vis != DefaultVisual(theDisplay,theScreen) )
00726 { cmap = XCreateColormap(theDisplay,Root,vis,AllocNone);
00727 }
00728 arrow = XCreateFontCursor(theDisplay,XC_top_left_arrow);
00729
00730 #ifdef _GENERAL_H
00731 INFO("XCreateWindow");
00732 #else
00733 printf("XCreateWindow");
00734 #endif
00735 mask = CWEventMask;
00736 attr.event_mask = ExposureMask | KeyPressMask | StructureNotifyMask
00737 | EnterWindowMask | LeaveWindowMask | PropertyChangeMask;
00738 attr.background_pixel = cblack; mask |= CWBackPixel;
00739 attr.border_pixel = cwhite; mask |= CWBorderPixel;
00740 attr.colormap = cmap; mask |= CWColormap;
00741 attr.cursor = arrow; mask |= CWCursor;
00742 theWindow = XCreateWindow(theDisplay,
00743 Root,0,0,
00744 myhint.width, myhint.height,
00745 2, PixDepth, InputOutput,
00746 vis, mask, &attr);
00747 }
00748 else
00749 {
00750 #ifdef _GENERAL_H
00751 INFO("XCreateSimpleWindow");
00752 #else
00753 printf("XCreateSimpleWindow");
00754 #endif
00755 theWindow = XCreateSimpleWindow(theDisplay,
00756 Root,
00757 myhint.x, myhint.y,
00758 myhint.width, myhint.height,
00759 5, cwhite, cblack);
00760 }
00761
00762 XSetStandardProperties(theDisplay, theWindow, winname, winname,
00763 None, NULL, 0, &myhint);
00764
00765 XSelectInput(theDisplay, theWindow,
00766 ButtonPressMask|ButtonReleaseMask|Button1MotionMask|
00767 KeyPressMask|ExposureMask);
00768
00769 XMapRaised(theDisplay, theWindow);
00770
00771 alive=false;
00772 pause=false;
00773
00774 autowritegif=false;
00775
00776 framecolor = cwhite;
00777 newGraph();
00778
00779
00780 nL=nP=0;
00781
00782
00783
00784
00785
00786 InitSem();
00787 Unlock();
00788
00789
00790
00791
00792 InitSem2();
00793
00794
00795 square = s;
00796 sort = so;
00797 drawframe = fm;
00798 X0=Y0=X00=Y00=0;Scale=Scale0=1;Aspr=Aspr0=1;
00799
00800 D=D0=10000;
00801
00802 gifcount=0;pscount=0;
00803
00804
00805 lastDrag = (unsigned long) (-1);
00806
00807 rinterval=0;
00808 msrsp=ROTATION;
00809
00810 scalepoints = 1;
00811 enable_pbc = 0;
00812 pbcshift[0]=pbcshift[1]=pbcshift[2]=0 ;
00813 maxpointradius = 100;
00814 maxlinewidth = 100;
00815 }
00816
00817 SYWindow::~SYWindow()
00818 {
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829 FreeResource();
00830 }
00831
00832 void SYWindow::reversergb()
00833 {
00834 int j;
00835 unsigned long L;
00836
00837 for(j=0;j<6;j++)
00838 {
00839 L=CCT[0][j];
00840 CCT[0][j]=CCT[2][j];
00841 CCT[2][j]=L;
00842 }
00843 }
00844
00845 unsigned long SYWindow::AllocRGBColor(unsigned r, unsigned g, unsigned b)
00846 {
00847 XColor c;
00848 c.red=r, c.green=g, c.blue=b;
00849
00850 #ifdef _GENERAL_H
00851 if(XAllocColor(theDisplay, cmap, &c)==0)
00852 WARNING("Error allocating color ("<<r<<", "<<g<<", "<<b<<")");
00853 #else
00854 if(XAllocColor(theDisplay, cmap, &c)==0)
00855 fprintf(stderr,"Error allocating color (%d,%d,%d)\n",r,g,b);
00856 #endif
00857
00858
00859
00860
00861
00862
00863
00864 return c.pixel;
00865 }
00866
00867 unsigned long SYWindow::AllocShortRGBColor(unsigned r, unsigned g, unsigned b)
00868 {
00869
00870 return RGBany(r,g,b);
00871 }
00872
00873 unsigned long SYWindow::AllocNamedColor(char *name)
00874 {
00875 XColor c,c1;
00876
00877
00878 #ifdef _GENERAL_H
00879 if(XAllocNamedColor(theDisplay, cmap, name,&c1,&c)==0)
00880 WARNING("Error allocating color ("<<name<<")");
00881 #else
00882 if(XAllocNamedColor(theDisplay, cmap, name,&c1,&c)==0)
00883 fprintf(stderr,"Error allocating color ( %s )\n",name);
00884 #endif
00885
00886
00887
00888
00889
00890
00891
00892
00893 return c.pixel;
00894 }
00895
00896 void SYWindow::testcolor()
00897 {
00898 unsigned long c;
00899 int r, g, b;
00900 unsigned int ur,ug,ub;
00901 #ifndef INFO_Printf
00902 #define INFO_Printf printf
00903 #endif
00904 r=255; g=0; b=0; ur=0xffff; ug=0; ub=0;
00905 c=AllocRGBColor(ur,ug,ub); INFO_Printf(" (%x %x %x)-%x\n",ur,ug,ub,c);
00906 c=AllocShortRGBColor(r,g,b); INFO_Printf(" (%d %d %d)-%x\n",r,g,b,c);
00907 r=0; g=255; b=0; ur=0; ug=0xffff; ub=0;
00908 c=AllocRGBColor(ur,ug,ub); INFO_Printf(" (%x %x %x)-%x\n",ur,ug,ub,c);
00909 c=AllocShortRGBColor(r,g,b); INFO_Printf(" (%d %d %d)-%x\n",r,g,b,c);
00910 r=0; g=0; b=255; ur=0; ug=0; ub=0xffff;
00911 c=AllocRGBColor(ur,ug,ub); INFO_Printf(" (%x %x %x)-%x\n",ur,ug,ub,c);
00912 c=AllocShortRGBColor(r,g,b); INFO_Printf(" (%d %d %d)-%x\n",r,g,b,c);
00913 r=1; g=0; b=0; ur=0x1000; ug=0; ub=0;
00914 c=AllocRGBColor(ur,ug,ub); INFO_Printf(" (%x %x %x)-%x\n",ur,ug,ub,c);
00915 c=AllocShortRGBColor(r,g,b); INFO_Printf(" (%d %d %d)-%x\n",r,g,b,c);
00916 r=0; g=1; b=0; ur=0; ug=0x1000; ub=0;
00917 c=AllocRGBColor(ur,ug,ub); INFO_Printf(" (%x %x %x)-%x\n",ur,ug,ub,c);
00918 c=AllocShortRGBColor(r,g,b); INFO_Printf(" (%d %d %d)-%x\n",r,g,b,c);
00919 r=0; g=0; b=1; ur=0; ug=0; ub=0x1000;
00920 c=AllocRGBColor(ur,ug,ub); INFO_Printf(" (%x %x %x)-%x\n",ur,ug,ub,c);
00921 c=AllocShortRGBColor(r,g,b); INFO_Printf(" (%d %d %d)-%x\n",r,g,b,c);
00922 r=127; g=0; b=0; ur=0x7fff; ug=0; ub=0;
00923 c=AllocRGBColor(ur,ug,ub); INFO_Printf(" (%x %x %x)-%x\n",ur,ug,ub,c);
00924 c=AllocShortRGBColor(r,g,b); INFO_Printf(" (%d %d %d)-%x\n",r,g,b,c);
00925 r=0; g=127; b=0; ur=0; ug=0x7fff; ub=0;
00926 c=AllocRGBColor(ur,ug,ub); INFO_Printf(" (%x %x %x)-%x\n",ur,ug,ub,c);
00927 c=AllocShortRGBColor(r,g,b); INFO_Printf(" (%d %d %d)-%x\n",r,g,b,c);
00928 r=0; g=0; b=127; ur=0; ug=0; ub=0x7fff;
00929 c=AllocRGBColor(ur,ug,ub); INFO_Printf(" (%x %x %x)-%x\n",ur,ug,ub,c);
00930 c=AllocShortRGBColor(r,g,b); INFO_Printf(" (%d %d %d)-%x\n",r,g,b,c);
00931 r=255; g=255; b=255; ur=0xffff; ug=0xffff; ub=0xffff;
00932 c=AllocRGBColor(ur,ug,ub); INFO_Printf(" (%x %x %x)-%x\n",ur,ug,ub,c);
00933 c=AllocShortRGBColor(r,g,b); INFO_Printf(" (%d %d %d)-%x\n",r,g,b,c);
00934 }
00935
00936 #ifndef NO_XPM
00937 void SYWindow::writegif()
00938 {
00939 const char fname[]="Ysnap";
00940 char extname[100],tmp[100];
00941 char f1[100], c1[100];
00942 Lock();
00943 sprintf(tmp,"%04d",gifcount);
00944 strcpy(extname,fname);
00945 strcat(extname,tmp);
00946 sprintf(f1,"%s.xpm",extname);
00947 #ifdef _GENERAL_H
00948 INFO("writegif -> "<<extname<<".gif");
00949 #else
00950 fprintf(stdout,"writegif -> %s.gif\n",extname);
00951 #endif
00952 sprintf(c1,"xpmtoppm %s.xpm | ppmtogif > %s.gif",extname,extname);
00953 writeXpm(f1);
00954 system(c1);
00955 sprintf(c1,"rm -f %s",f1);
00956 system(c1);
00957 gifcount++;
00958 Unlock();
00959 }
00960 #endif
00961 void SYWindow::importgif()
00962 {
00963 const char fname[]="Ysnap";
00964 char extname[100],tmp[100];
00965 char f1[100], c1[100];
00966 Lock();
00967 sprintf(tmp,"%04d",gifcount);
00968 strcpy(extname,fname);
00969 strcat(extname,tmp);
00970 sprintf(f1,"%s.xpm",extname);
00971 #ifdef _GENERAL_H
00972 INFO_Printf("import -window 0x%x %s.gif &\n",theWindow,extname);
00973 #else
00974 printf("import -window 0x%x %s.gif &\n",theWindow,extname);
00975 #endif
00976 sprintf(c1,"import -window 0x%x %s.gif &",(unsigned)theWindow,extname);
00977 system(c1);
00978 gifcount++;
00979 Unlock();
00980 }
00981 void SYWindow::Draw3DLinetoPS(FILE *file,YLine line)
00982 {
00983 double xs1,ys1,zs1,xs2,ys2,zs2,Z,r;unsigned attr;
00984 double red,green,blue;
00985 double x1, y1, x2, y2;
00986 attr = line.attr;
00987 xs1 = line.x0;
00988 ys1 = line.y0;
00989 zs1 = line.z0;
00990
00991 PBCSHIFT(xs1,pbcshift[0],0);
00992 PBCSHIFT(ys1,-pbcshift[1],0);
00993 PBCSHIFT(zs1,pbcshift[2],0);
00994
00995 Z=A31*xs1+A32*ys1+A33*zs1;
00996 x1=CX(A11*xs1+A12*ys1+A13*zs1,Z);
00997 y1=CY(A21*xs1+A22*ys1+A23*zs1,Z);
00998 xs2 = line.x1;
00999 ys2 = line.y1;
01000 zs2 = line.z1;
01001
01002 PBCSHIFT(xs2,pbcshift[0],xs1);
01003 PBCSHIFT(ys2,-pbcshift[1],ys1);
01004 PBCSHIFT(zs2,pbcshift[2],zs1);
01005
01006 Z=A31*xs2+A32*ys2+A33*zs2;
01007 x2=CX(A11*xs2+A12*ys2+A13*zs2,Z);
01008 y2=CY(A21*xs2+A22*ys2+A23*zs2,Z);
01009 r=CR(line.r,0);
01010 if(r>maxlinewidth) r=maxlinewidth;
01011 if(r<0.5) r=0.5;
01012
01013
01014
01015 if((((x1<0)||(x1>(int)width))||((y1<0)||(y1>(int)height)))
01016 &&(((x2<0)||(x2>(int)width))||((y2<0)||(y2>(int)height))))
01017 return;
01018
01019
01020
01021
01022 red=REDany(line.c);
01023 green=GREENany(line.c);
01024 blue=BLUEany(line.c);
01025
01026 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb"
01027 " %5.2f %5.2f %5.2f %5.2f m l s\n",
01028 r,red,green,blue,
01029 x1,height-y1,x2,height-y2);
01030 if(attr!=0)
01031 {
01032 double dy,dx,dr;
01033 dy=y2-y1;dx=x2-x1;dr=sqrt(dy*dy+dx*dx);dy/=dr;dx/=dr;
01034 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb"
01035 " %5.2f %5.2f %5.2f %5.2f m l s\n",
01036 0.5,0.,0.,0.,
01037 x1+dy*r/2,height-(y1-dx*r/2),
01038 x2+dy*r/2,height-(y2-dx*r/2));
01039 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb"
01040 " %5.2f %5.2f %5.2f %5.2f m l s\n",
01041 0.5,0.,0.,0.,
01042 x1-dy*r/2,height-(y1+dx*r/2),
01043 x2-dy*r/2,height-(y2+dx*r/2));
01044 }
01045 }
01046
01047 void SYWindow::Draw3DPixeltoPS(FILE *file,YPoint point)
01048 {
01049 double x,y,r;
01050
01051 #ifndef _ALLCIRCLE
01052 unsigned attr;
01053 #endif
01054 double xs, ys, zs, Z;
01055 double red,green,blue;
01056 xs = point.x;
01057 ys = point.y;
01058 zs = point.z;
01059
01060 PBCSHIFT(xs,pbcshift[0],0);
01061 PBCSHIFT(ys,-pbcshift[1],0);
01062 PBCSHIFT(zs,pbcshift[2],0);
01063
01064 #ifndef _ALLCIRCLE
01065 attr = point.attr;
01066 #endif
01067 Z=A31*xs+A32*ys+A33*zs;
01068 x=CX(A11*xs+A12*ys+A13*zs,Z);
01069 y=CY(A21*xs+A22*ys+A23*zs,Z);
01070 r=CR(point.r,Z);
01071 if(((x<-r)||(x>(int)width+r))||((y<-r)||(y>(int)height+r))) return;
01072
01073
01074
01075 red=REDany(point.c);
01076 green=GREENany(point.c);
01077 blue=BLUEany(point.c);
01078
01079 if(r>maxpointradius) r=maxpointradius;
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089 if(attr==0)
01090 {
01091 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb %f %f %f ",
01092 0.5,
01093 1.,1.,1.,
01094 x,height-y,r);
01095 fprintf(file,"disc\n");
01096 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb %f %f %f ",
01097 0.5,
01098 0.,0.,0.,x,height-y,r);
01099 fprintf(file,"circle\n");
01100 }
01101 else if(attr==2)
01102 {
01103 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb %f %f %f ",
01104 0.5,
01105 red,green,blue,
01106 x,height-y,r);
01107 fprintf(file,"disc\n");
01108 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb %f %f %f ",
01109 0.5,
01110 0.,0.,0.,x,height-y,r);
01111 fprintf(file,"circle\n");
01112 }
01113 else
01114 {
01115 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb %f %f %f ",
01116 0.5,
01117 red,green,blue,
01118 x,height-y,r);
01119 fprintf(file,"circle\n");
01120 }
01121 }
01122
01123 void SYWindow::writeps()
01124 {
01125 int i;
01126
01127 const char fname[]="Yshot";
01128 char extname[100],tmp[100];
01129 char f1[100];
01130 FILE *file;
01131
01132 char head1[500]="%!PS-Adobe-3.0 EPSF-3.0\n"
01133 "%%Pages: (atend)\n";
01134 char head2[500]="%%BoundingBox:";
01135 char head3[5000]=
01136 "%%EndComments\n"
01137 "/l {lineto} def\n"
01138 "/m {moveto} def\n"
01139 "/t {translate} def\n"
01140 "/slw {setlinewidth} def\n"
01141 "/srgb {setrgbcolor} def\n"
01142 "/np {newpath} def\n"
01143 "/s {stroke} def\n"
01144 "/disc { 0 360 arc fill } def\n"
01145 "/circle { 0 360 arc s } def\n";
01146
01147 char tail[500]="showpage\n";
01148
01149 sprintf(tmp,"%04d",pscount);
01150 strcpy(extname,fname);
01151 strcat(extname,tmp);
01152 sprintf(f1,"%s.ps",extname);
01153 file=fopen(f1,"w");
01154 pscount++;
01155
01156 fprintf(file,"%s",head1);
01157 #ifdef _GENERAL_H
01158 INFO("writeps -> "<<f1);
01159 INFO("write to file");
01160 #else
01161 fprintf(stdout,"writeps -> %s\nwrite to file\n",f1);
01162 #endif
01163 fprintf(file,"%s %d %d %d %d\n",head2,0,0,width,height);
01164 fprintf(file,"%s",head3);
01165
01166 if (sort)
01167 {
01168 for(i=0;i<nL+nP;i++)
01169 {
01170 int n=Z_ind[i].index;
01171 if(n<nL) Draw3DLinetoPS(file,Lines[n]);
01172 else Draw3DPixeltoPS(file,Points[n-nL]);
01173 }
01174 }
01175 else
01176 {
01177 for(i=0;i<nL;i++)
01178 {
01179 Draw3DLinetoPS(file,Lines[i]);
01180 }
01181 for(i=0;i<nP;i++)
01182 {
01183 Draw3DPixeltoPS(file,Points[i]);
01184 }
01185 }
01186
01187 fprintf(file,"%s",tail);
01188 fclose(file);
01189 }
01190
01191 void YWindow::help()
01192 {
01193 const char helpstr[]=
01194 "yview:\n"
01195 "Mouse drag to rotate\n"
01196 "Hot Keys:\n"
01197 "F1 : display this message\n"
01198 "Up : rotate up\n"
01199 "Down : rotate down\n"
01200 "Left : rotate left\n"
01201 "Right : rotate right\n"
01202 "PgUp : rotate counterclockwise\n"
01203 "PgDn : rotate clockwise\n"
01204 "Home : back to initial viewpoint\n"
01205 "Space : stop rotate\n"
01206
01207
01208
01209
01210
01211
01212
01213
01214 "p : toggle pause\n"
01215 "t : translation\n"
01216 "s : scaling\n"
01217 "d : move projection infinity point\n"
01218 "r : rotation\n"
01219 "f : toggle pbc enableness\n"
01220 "m : toggle drawframe\n"
01221 "g : pbc glide\n"
01222 "x : pbc shift in x\n"
01223 "y : pbc shift in y\n"
01224 "z : pbc shift in z\n"
01225 "w : print window specification\n"
01226 "F9 : output gif\n"
01227 "F10 : output postscript\n";
01228 #ifdef _GENERAL_H
01229 INFO("YWindow: "<<helpstr);
01230 #else
01231 fprintf(stdout,"YWindow: %s\n",helpstr);
01232 #endif
01233 }
01234
01235 void YWindow::printWinSpec()
01236 {
01237 char tmp[1000];
01238 sprintf(tmp,"YWindow: Window Specification\n"
01239 "width=%d\theight=%d\n"
01240 "X0=%d\tY0=%d\n"
01241 "Scale=%f\tD=%f\n"
01242 "rotation matrix=[%10f %10f %10f\n"
01243 " %10f %10f %10f\n"
01244 " %10f %10f %10f]\n\n"
01245 ,width,height,X0,Y0,Scale,D
01246 ,A11,A12,A13,A21,A22,A23,A31,A32,A33
01247 );
01248 #ifdef _GENERAL_H
01249 INFO(tmp);
01250 #else
01251 fprintf(stdout,"%s\n",tmp);
01252 #endif
01253 }
01254
01255 void YWindow::setWinSpec(int x0,int y0,double s,double d,double a[3][3])
01256 {
01257 X0=x0;Y0=y0;Scale=s;D=d;
01258 A11=a[0][0];A12=a[0][1];A13=a[0][2];
01259 A21=a[1][0];A22=a[1][1];A23=a[1][2];
01260 A31=a[2][0];A32=a[2][1];A33=a[2][2];
01261 }
01262
01263 void YWindow::update()
01264 {
01265 Lock();
01266 XSetForeground(theDisplay, gc, bgcolor);
01267 XFillRectangle(theDisplay, pixmap, gc, 0, 0,
01268 width,height);
01269 paint();
01270 if(drawframe)drawBoxFrame();
01271 XCopyArea(theDisplay,pixmap,theWindow,gc,0,0,width,height,0,0);
01272 Unlock();
01273 }
01274
01275 void YWindow::drawBoxFrame()
01276 {
01277 unsigned char FLAG;
01278 #define _DoDraw(_1,_2,_3, _4,_5,_6) \
01279 _XDrawLine(_1 A11 _2 A12 _3 A13,\
01280 _1 A21 _2 A22 _3 A23,\
01281 _1 A31 _2 A32 _3 A33,\
01282 _4 A11 _5 A12 _6 A13,\
01283 _4 A21 _5 A22 _6 A23,\
01284 _4 A31 _5 A32 _6 A33)
01285
01286 #define _XDrawLine(a,b,Z0,c,d,Z1) XDrawLine(theDisplay,pixmap,gc,\
01287 (int)CX(a,Z0),(int)CY(b,Z0),(int)CX(c,Z1),(int)CY(d,Z1))
01288
01289 #define _XDash XSetLineAttributes(theDisplay, gc, 1, LineOnOffDash, CapButt, JoinMiter)
01290 #define _XSold XSetLineAttributes(theDisplay, gc, 1, LineSolid, CapButt, JoinMiter)
01291
01292 #define _XSetLine(a,b) {if((a)&& !(b)) _XDash; else if(!(a)&&(b)) _XSold;}
01293
01294 XSetForeground(theDisplay, gc, framecolor);
01295 _XDash;
01296
01297 FLAG = 1<< ( ((A31<0)?4:0)+((A32<0)?2:0)+((A33<0)?1:0));
01298
01299 _XSetLine(FLAG&0xA0,!(FLAG&0xA0));
01300 _DoDraw(+,-,+, +,+,+);
01301
01302
01303 _XSetLine(FLAG&0x22,FLAG&0xA0);
01304 _DoDraw(-,-,+, +,-,+);
01305
01306
01307 _XSetLine(FLAG&0x0A,FLAG&0x22);
01308 _DoDraw(-,+,+, -,-,+);
01309
01310
01311 _XSetLine(FLAG&0x88,FLAG&0x0A);
01312 _DoDraw(+,+,+, -,+,+);
01313
01314
01315
01316 _XSetLine(FLAG&0x50,FLAG&0x88);
01317 _DoDraw(+,-,-, +,+,-);
01318
01319
01320 _XSetLine(FLAG&0x11,FLAG&0x50);
01321 _DoDraw(-,-,-, +,-,-);
01322
01323
01324 _XSetLine(FLAG&0x05,FLAG&0x11);
01325 _DoDraw(-,+,-, -,-,-);
01326
01327
01328 _XSetLine(FLAG&0x44,FLAG&0x05);
01329 _DoDraw(+,+,-, -,+,-);
01330
01331
01332
01333 _XSetLine(FLAG&0xC0,FLAG&0x44);
01334 _DoDraw(+,+,+, +,+,-);
01335
01336
01337 _XSetLine(FLAG&0x30,FLAG&0xC0);
01338 _DoDraw(+,-,+, +,-,-);
01339
01340
01341 _XSetLine(FLAG&0x03,FLAG&0x30);
01342 _DoDraw(-,-,+, -,-,-);
01343
01344
01345 _XSetLine(FLAG&0x0C,FLAG&0x03);
01346 _DoDraw(-,+,+, -,+,-);
01347
01348
01349 _XSold;
01350
01351 XDrawArc(theDisplay, pixmap, gc, width/2+(int)(X0-R*Scale),height/2+(int)(Y0-R*Scale),
01352 (int)(2*R*Scale),(int)(2*R*Scale),0,23040);
01353 }
01354
01355
01356
01357 void YWindow::applyRotate()
01358 {
01359 double d1,d2,d3;
01360 d1=B11*A11+B12*A21+B13*A31;
01361 d2=B21*A11+B22*A21+B23*A31;
01362 d3=B31*A11+B32*A21+B33*A31;
01363 A11=d1; A21=d2; A31=d3;
01364 d1=B11*A12+B12*A22+B13*A32;
01365 d2=B21*A12+B22*A22+B23*A32;
01366 d3=B31*A12+B32*A22+B33*A32;
01367 A12=d1; A22=d2; A32=d3;
01368 d1=B11*A13+B12*A23+B13*A33;
01369 d2=B21*A13+B22*A23+B23*A33;
01370 d3=B31*A13+B32*A23+B33*A33;
01371 A13=d1; A23=d2; A33=d3;
01372 dirty=true;
01373 }
01374
01375 void YWindow::horizontalRot(double arc)
01376 {
01377 double d1,d3;
01378 double c, s;
01379 c=cos(arc);
01380 s=sin(arc);
01381 d1=c*A11+s*A31;
01382 d3=-s*A11+c*A31;
01383 A11=d1;A31=d3;
01384 d1=c*A12+s*A32;
01385 d3=-s*A12+c*A32;
01386 A12=d1;A32=d3;
01387 d1=c*A13+s*A33;
01388 d3=-s*A13+c*A33;
01389 A13=d1;A33=d3;
01390 dirty=true;
01391 }
01392
01393 void YWindow::verticalRot(double arc)
01394 {
01395 double d2,d3;
01396 double c,s;
01397 s=sin(arc);
01398 c=cos(arc);
01399 d2=c*A21+s*A31;
01400 d3=-s*A21+c*A31;
01401 A21=d2;A31=d3;
01402 d2=c*A22+s*A32;
01403 d3=-s*A22+c*A32;
01404 A22=d2;A32=d3;
01405 d2=c*A23+s*A33;
01406 d3=-s*A23+c*A33;
01407 A23=d2;A33=d3;
01408 dirty=true;
01409 }
01410
01411 void YWindow::spinRot(double arc)
01412 {
01413 double d1,d2;
01414 double c,s;
01415 s=sin(arc);
01416 c=cos(arc);
01417 d1=c*A11+s*A21;
01418 d2=-s*A11+c*A21;
01419 A11=d1;A21=d2;
01420 d1=c*A12+s*A22;
01421 d2=-s*A12+c*A22;
01422 A12=d1;A22=d2;
01423 d1=c*A13+s*A23;
01424 d2=-s*A13+c*A23;
01425 A13=d1;A23=d2;
01426 dirty=true;
01427 }
01428
01429 void YWindow::zoom(double z)
01430 {
01431
01432 Scale*=z;
01433
01434 }
01435
01436 void YWindow::project(double z)
01437 {
01438
01439 D*=z;
01440
01441 }
01442
01443 void YWindow::scaleTo(XEvent ev)
01444 {
01445 Scale*=exp((ev.xmotion.x-Xp+ev.xmotion.y-Yp)*0.001);
01446 if(Scale<5e-2) Scale=5e-2;
01447 if(Scale>1e2) Scale=1e2;
01448
01449 dirty=true;
01450 Xp=ev.xmotion.x;
01451 Yp=ev.xmotion.y;
01452 }
01453
01454 void YWindow::translateTo(XEvent ev)
01455 {
01456 X0+=ev.xmotion.x-Xp;Y0+=ev.xmotion.y-Yp;
01457
01458 dirty=true;
01459 Xp=ev.xmotion.x;
01460 Yp=ev.xmotion.y;
01461 }
01462
01463 void YWindow::pbcshiftTo(XEvent ev, int dir)
01464 {
01465 pbcshift[dir]+=(0.0+ev.xmotion.x-Xp+ev.xmotion.y-Yp)/(2.0*B*Scale);
01466
01467 dirty=true;
01468 Xp=ev.xmotion.x;
01469 Yp=ev.xmotion.y;
01470 }
01471
01472 void YWindow::pbcglideTo(XEvent ev)
01473 {
01474 pbcglide((ev.xmotion.x-Xp)/(2.0*B),(ev.xmotion.y-Yp)/(2.0*B));
01475
01476 dirty=true;
01477 Xp=ev.xmotion.x;
01478 Yp=ev.xmotion.y;
01479 }
01480
01481 void YWindow::pbcglide(double dx, double dy)
01482 {
01483 double Ainv11,Ainv12,Ainv13,Ainv21,Ainv22,Ainv23,Ainv31,Ainv32,Ainv33;
01484
01485 Ainv11=A22*A33-A23*A32;
01486 Ainv22=A33*A11-A31*A13;
01487 Ainv33=A11*A22-A12*A21;
01488 Ainv12=A23*A31-A21*A33;
01489 Ainv23=A31*A12-A32*A11;
01490 Ainv31=A12*A23-A13*A22;
01491 Ainv13=A21*A32-A31*A22;
01492 Ainv21=A32*A13-A12*A33;
01493 Ainv32=A13*A21-A23*A11;
01494
01495 pbcshift[0]+=Ainv11*dx+Ainv12*dy;
01496 pbcshift[1]+=Ainv21*dx+Ainv22*dy;
01497 pbcshift[2]+=Ainv31*dx+Ainv32*dy;
01498 }
01499
01500 void YWindow::projectTo(XEvent ev)
01501 {
01502 D*=exp(-(ev.xmotion.x-Xp+ev.xmotion.y-Yp)*0.001);
01503 if(D<0.2) D=0.2;
01504 if(D>1e2) D=1e2;
01505
01506 dirty=true;
01507 Xp=ev.xmotion.x;
01508 Yp=ev.xmotion.y;
01509 }
01510
01511 void YWindow::rotateTo(XEvent ev)
01512 {
01513
01514 double a1,a2,a3,b1,b2,b3,c1,c2,c3,d1,d2,d3,e1,e2,e3;
01515 double r,rp,xx,yy,xp,yp;
01516 #define _toler 1.0e-6
01517 xx=((double)ev.xmotion.x-width/2-X0)/R;
01518 yy=-((double)ev.xmotion.y-height/2-Y0)/R;
01519 xp=((double)Xp-width/2-X0)/R;
01520 yp=-((double)Yp-height/2-Y0)/R;
01521
01522 if((xp-xx)*(xp-xx)+(yp-yy)*(yp-yy)<_toler) return;
01523
01524
01525 rp=sqrt(xp*xp+yp*yp);
01526 r=sqrt(xx*xx+yy*yy);
01527 if(r>=1 || rp>=1)
01528 {
01529 d1=xp/rp;
01530 e1=yp/rp;
01531 d2=xx/r;
01532 e2=yy/r;
01533
01534 d3=cos((r-rp)*M_PI);
01535 e3=sin((r-rp)*M_PI);
01536
01537 B11=d3*d1*d2+e1*e2;
01538 B12=d3*e1*d2-d1*e2;
01539 B13=e3*d2;
01540 B21=d3*d1*e2-e1*d2;
01541 B22=d3*e1*e2+d1*d2;
01542 B23=e3*e2;
01543 B31=-e3*d1;
01544 B32=-e3*e1;
01545 B33=d3;
01546 }
01547 else
01548 {
01549 a1=xp;a2=yp;a3=sqrt(1-a1*a1-a2*a2);
01550 b1=xx;b2=yy;b3=sqrt(1-b1*b1-b2*b2);
01551 c1=a2*b3-a3*b2;
01552 c2=a3*b1-a1*b3;
01553 c3=a1*b2-a2*b1;
01554 r=sqrt(c1*c1+c2*c2+c3*c3);
01555 c1/=r;c2/=r;c3/=r;
01556
01557 d1=a2*c3-a3*c2;
01558 d2=a3*c1-a1*c3;
01559 d3=a1*c2-a2*c1;
01560 e1=b2*c3-b3*c2;
01561 e2=b3*c1-b1*c3;
01562 e3=b1*c2-b2*c1;
01563
01564 B11=b1*a1+e1*d1+c1*c1;
01565 B12=b1*a2+e1*d2+c1*c2;
01566 B13=b1*a3+e1*d3+c1*c3;
01567 B21=b2*a1+e2*d1+c2*c1;
01568 B22=b2*a2+e2*d2+c2*c2;
01569 B23=b2*a3+e2*d3+c2*c3;
01570 B31=b3*a1+e3*d1+c3*c1;
01571 B32=b3*a2+e3*d2+c3*c2;
01572 B33=b3*a3+e3*d3+c3*c3;
01573
01574 }
01575
01576
01577
01578
01579 Xp=ev.xmotion.x;
01580 Yp=ev.xmotion.y;
01581
01582 applyRotate();
01583 }
01584
01585 void YWindow::Evolve()
01586 {
01587 XEvent ev;KeySym ks;
01588 long t;
01589
01590 if(!alive) return;
01591 XSync(theDisplay, false);
01592 if(enableRot) applyRotate();
01593 if(dirty)
01594 {
01595 dirty=false;
01596 update();
01597 }
01598 #ifndef NO_XPM
01599 if(autowritegif)
01600 {
01601 writegif();
01602 UnlockWritegif();
01603 }
01604 #endif
01605 while(XPending(theDisplay))
01606 {
01607 XNextEvent(theDisplay, &ev);
01608 switch(ev.type)
01609 {
01610 case ButtonPress:
01611 enableRot=false;
01612 Xp=ev.xbutton.x;
01613 Yp=ev.xbutton.y;
01614 identify(Xp,Yp);
01615
01616
01617 break;
01618 case ButtonRelease:
01619 t=(long)ev.xbutton.time-(long)lastDrag;
01620 if(msrsp==ROTATION) enableRot = (t<100);
01621
01622 break;
01623 case MotionNotify:
01624 if(lastDrag+rInterval*3/4 <= ev.xmotion.time)
01625 {
01626 lastDrag=ev.xmotion.time;
01627 switch(msrsp){
01628 case(ROTATION):
01629 rotateTo(ev);break;
01630 case(TRANSLATION):
01631 translateTo(ev);break;
01632 case(SCALING):
01633 scaleTo(ev);break;
01634 case(PROJECTION):
01635 projectTo(ev);break;
01636 case(PBCX):
01637 pbcshiftTo(ev,0);break;
01638 case(PBCY):
01639 pbcshiftTo(ev,1);break;
01640 case(PBCZ):
01641 pbcshiftTo(ev,2);break;
01642 case(PBCGLIDE):
01643 pbcglideTo(ev);break;
01644 default:break;
01645 }
01646 }
01647
01648
01649 break;
01650 case Expose:
01651 newGraph();
01652 break;
01653 case KeyPress:
01654 ks=XKeycodeToKeysym(theDisplay,ev.xkey.keycode,0);
01655 switch (ks)
01656 {
01657 case XK_F1: help();break;
01658 case XK_Escape:
01659 FreeResource(); return;
01660 case XK_space: enableRot=false;break;
01661 case XK_Page_Up: spinRot(DEG(-5));break;
01662 case XK_Page_Down: spinRot(DEG(5));break;
01663 case XK_Up:
01664 switch(msrsp){
01665 case(PROJECTION):D*=1.1;dirty=true;break;
01666 case(SCALING):Scale/=1.1;dirty=true;break;
01667 case(TRANSLATION):Y0-=5;dirty=true;break;
01668 case(ROTATION):verticalRot(DEG(5));break;
01669 case(ASPECTRATIO):Aspr*=1.1;dirty=true;break;
01670 case(PBCX):pbcshift[0]=0.01;dirty=true;break;
01671 case(PBCY):pbcshift[1]-=0.01;dirty=true;break;
01672 case(PBCZ):pbcshift[2]-=0.01;dirty=true;break;
01673 case(PBCGLIDE):pbcglide(0,-0.01);dirty=true;break;
01674 } break;
01675 case XK_Down:
01676 switch(msrsp){
01677 case(PROJECTION):D/=1.1;dirty=true;break;
01678 case(SCALING):Scale*=1.1;dirty=true;break;
01679 case(TRANSLATION):Y0+=5;dirty=true;break;
01680 case(ROTATION):verticalRot(DEG(-5));break;
01681 case(ASPECTRATIO):Aspr/=1.1;dirty=true;break;
01682 case(PBCX):pbcshift[0]-=0.01;dirty=true;break;
01683 case(PBCY):pbcshift[1]+=0.01;dirty=true;break;
01684 case(PBCZ):pbcshift[2]+=0.01;dirty=true;break;
01685 case(PBCGLIDE):pbcglide(0,+0.01);dirty=true;break;
01686 } break;
01687 case XK_Left:
01688 switch(msrsp){
01689 case(PROJECTION):D*=1.1;dirty=true;break;
01690 case(SCALING):Scale/=1.1;dirty=true;break;
01691 case(TRANSLATION):X0-=5;dirty=true;break;
01692 case(ROTATION):horizontalRot(DEG(-5));break;
01693 case(PBCX):pbcshift[0]-=0.01;dirty=true;break;
01694 case(PBCY):pbcshift[1]+=0.01;dirty=true;break;
01695 case(PBCZ):pbcshift[2]+=0.01;dirty=true;break;
01696 case(PBCGLIDE):pbcglide(-0.01,0);dirty=true;break;
01697 } break;
01698 case XK_Right:
01699 switch(msrsp){
01700 case(PROJECTION):D/=1.1;dirty=true;break;
01701 case(SCALING):Scale*=1.1;dirty=true;break;
01702 case(TRANSLATION):X0+=5;dirty=true;break;
01703 case(ROTATION):horizontalRot(DEG(5));break;
01704 case(PBCX):pbcshift[0]+=0.01;dirty=true;break;
01705 case(PBCY):pbcshift[1]-=0.01;dirty=true;break;
01706 case(PBCZ):pbcshift[2]-=0.01;dirty=true;break;
01707 case(PBCGLIDE):pbcglide(+0.01,0);dirty=true;break;
01708 } break;
01709 case XK_Home:
01710 copyRot();X0=X00;Y0=Y00;D=D0;Scale=Scale0;Aspr=Aspr0;
01711 pbcshift[0]=pbcshift[1]=pbcshift[2]=0;
01712 dirty=true;break;
01713 #ifdef _GENERAL_H
01714 case XK_p: TogglePause();INFO("Pause="<<pause);return;
01715 #else
01716 case XK_p: TogglePause();
01717 fprintf(stdout,"Pause=%d\n",(int)pause);return;
01718 #endif
01719 case XK_a:msrsp=ASPECTRATIO;dirty=true;break;
01720 case XK_d:msrsp=PROJECTION;dirty=true;break;
01721 case XK_s:msrsp=SCALING;dirty=true;break;
01722 case XK_t:msrsp=TRANSLATION;dirty=true;break;
01723 case XK_r:msrsp=ROTATION;dirty=true;break;
01724 case XK_f:enable_pbc=!enable_pbc;
01725 if(enable_pbc)msrsp=PBCX;else msrsp=ROTATION;
01726 dirty=true; break;
01727 case XK_g:enable_pbc=1; msrsp=PBCGLIDE; dirty=true; break;
01728 case XK_x:enable_pbc=1; msrsp=PBCX; dirty=true; break;
01729 case XK_y:enable_pbc=1; msrsp=PBCY; dirty=true; break;
01730 case XK_z:enable_pbc=1; msrsp=PBCZ; dirty=true; break;
01731 case XK_w: printWinSpec(); break;
01732 case XK_m: drawframe=!drawframe; dirty=true; break;
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748 #ifndef NO_XPM
01749
01750
01751
01752 #endif
01753 case XK_F9:
01754 importgif();
01755 break;
01756 case XK_F10:
01757 writeps();
01758 break;
01759 default: ExtKeyHandler(ks); break;
01760 }
01761 default: break;
01762 }
01763 }
01764 }
01765
01766
01767
01768 #ifdef _TEST
01769
01770 int main(int argc, char *argv[])
01771 {
01772 int i, j, k;
01773 int ni=6,nj=6,nk=6;
01774 double x,y,z,x1,y1,z1,r,br,dx,dy,dz,dr;
01775 unsigned c;
01776 char s[100];
01777 YWindow *win;
01778
01779
01780
01781 win=new YWindow(400,400,"Test Window Display",true);
01782
01783
01784
01785 #define yw (*win)
01786
01787 yw.Lock();
01788 yw.Clear();
01789 ni=nj=nk=6;
01790
01791
01792 yw.bgcolor=yw.AllocShortRGBColor(100,100,100);
01793 for(i=0;i<ni;i++)for(j=0;j<nj;j++)for(k=0;k<nk;k++)
01794 {
01795 sprintf(s,"Ball:%d,%d,%d",i,j,k);
01796 x=-1+1./ni+2.*i/ni;y=-1+1./nj+2.*j/nj;z=-1+1./nk+2.*k/nk;r=.5/ni;br=r/4;
01797 c=yw.AllocShortRGBColor(i*0x33, j*0x33, k*0x33);
01798 yw.DrawPoint(x,y,z,r,c,s);
01799 if(i>0)
01800 {
01801 x1=x-2./ni;y1=y;z1=z;
01802 dx=x1-x;dy=y1-y;dz=z1-z;dr=sqrt(dx*dx+dy*dy+dz*dz);dx/=dr;dy/=dr;dz/=dr;
01803 yw.DrawLine(x+dx*r,y+dy*r,z+dz*r,x1-dx*r,y1-dy*r,z1-dz*r,c,br,1);
01804
01805 }
01806 if(j>0)
01807 {
01808 x1=x;y1=y-2./nj;z1=z;
01809 dx=x1-x;dy=y1-y;dz=z1-z;dr=sqrt(dx*dx+dy*dy+dz*dz);dx/=dr;dy/=dr;dz/=dr;
01810 yw.DrawLine(x+dx*r,y+dy*r,z+dz*r,x1-dx*r,y1-dy*r,z1-dz*r,c,br,1);
01811
01812 }
01813 if(k>0)
01814 {
01815 x1=x;y1=y;z1=z-2./nk;
01816 dx=x1-x;dy=y1-y;dz=z1-z;dr=sqrt(dx*dx+dy*dy+dz*dz);dx/=dr;dy/=dr;dz/=dr;
01817 yw.DrawLine(x+dx*r,y+dy*r,z+dz*r,x1-dx*r,y1-dy*r,z1-dz*r,c,br,1);
01818
01819 }
01820 }
01821
01822 yw.Unlock();
01823 yw.Refresh();
01824 #ifdef NO_THREAD
01825 yw.Routine();
01826 #else
01827 yw.Run();
01828 i=99;
01829 #ifndef NO_GENERAL
01830 _IO << "I can live for <<"<<i<<" seconds.\n" ;
01831 #else
01832 printf("I can live for %d seconds.\n",i);
01833 #endif
01834 for(j=0;j<i;j++)
01835 {
01836 sleep(1);
01837 #ifndef NO_GENERAL
01838 _IO << i-j << ' ';
01839 #else
01840 printf("%d \n",i-j);
01841 #endif
01842 }
01843 #ifndef NO_GENERAL
01844 _IO << "Bye.\n";
01845 #else
01846 printf("Bye.\n");
01847 #endif
01848 #endif
01849 return 0;
01850 }
01851
01852 #endif //_TEST
01853
01854 #endif //ifdef _windows