00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "display_win.h"
00012
00013 #ifdef TMCC
00014 extern "C"
00015 #endif
00016
00017 static int num_win = 0;
00018 static int win_table[100][2];
00019
00020 #ifndef NO_THREAD
00021
00022 #ifdef TMCC
00023 extern "C"
00024 #endif
00025
00026 #define PBCSHIFT(a,shift,origin) \
00027 if(enable_pbc){a-=origin;a/=2;a+=shift;a-=rint(a);a*=2;a+=origin;}
00028
00029 void * SYWindow::thread_routine(void *p)
00030 {
00031 int win;
00032
00033 static float diffuse[] = {0.6, 0.6, 0.6, 1.0};
00034
00035
00036
00037 static float ambient[] = {0.4, 0.4, 0.4, 1.0};
00038
00039 static float position[] = {0.0, 0.0, 1.0, 0.0};
00040
00041
00042
00043
00044
00045
00046
00047
00048 glutInitWindowPosition (100, 100);
00049
00050
00051
00052 glutInitWindowSize ((int)((SYWindow *)p)->width, (int)((SYWindow *)p)->height);
00053
00054
00055
00056 win = glutCreateWindow ("md++");
00057 glutDisplayFunc (display);
00058
00059
00060
00061 glutReshapeFunc (&event_WinReshape);
00062
00063
00064 glutKeyboardFunc (event_KeyboardProc);
00065
00066
00067 glutSpecialFunc (&event_SpecialProc);
00068
00069
00070 glutIdleFunc (event_IdleProc);
00071
00072
00073 glutMouseFunc (&event_Butp);
00074
00075
00076 glutMotionFunc (&event_Motion);
00077
00078 win_table[num_win][0] = glutGetWindow();
00079 win_table[num_win][1] = (int)p;
00080 num_win++;
00081
00082
00083 glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse);
00084 glLightfv (GL_LIGHT0, GL_POSITION, position);
00085 glLightfv (GL_LIGHT0, GL_AMBIENT, ambient);
00086 glEnable (GL_LIGHT0);
00087 glEnable (GL_LIGHTING);
00088
00089
00090 glEnable (GL_DEPTH_TEST);
00091
00092
00093 glEnable (GL_NORMALIZE);
00094
00095
00096 glEnable (GL_COLOR_MATERIAL);
00097
00098 viewport_Set (win, (int)((SYWindow *)p)->width, (int)((SYWindow *)p)->height);
00099
00100
00101 glutMainLoop();
00102
00103 return NULL;
00104 }
00105
00106
00107 void SYWindow::Run()
00108 {
00109 int r;
00110
00111 pthread_t thread;
00112
00113 r = pthread_create (&thread, NULL, thread_routine, this);
00114
00115 #ifdef _GENERAL_H
00116 if(r!=0) FATAL("Fail to create thread: ["<<strerror(errno)<<"]");
00117 #else
00118 if(r!=0) fprintf(stderr,"Fail to create thread\n");
00119 #endif
00120 }
00121 #endif
00122
00123
00124
00125
00126
00127
00128
00129
00130 void SYWindow::Draw3DLine(YLine line)
00131 {
00132 unsigned c, attr;
00133 double xs1, ys1, zs1, xs2, ys2, zs2;
00134 float rc, gc, bc;
00135
00136
00137
00138
00139
00140
00141
00142
00143 c = line.c;
00144 attr = line.attr;
00145 xs1 = line.x0;
00146 ys1 = line.y0;
00147 zs1 = line.z0;
00148
00149 PBCSHIFT(xs1, pbcshift[0], 0);
00150 PBCSHIFT(ys1,-pbcshift[1], 0);
00151 PBCSHIFT(zs1, pbcshift[2], 0);
00152
00153 xs2 = line.x1;
00154 ys2 = line.y1;
00155 zs2 = line.z1;
00156
00157 PBCSHIFT(xs2, pbcshift[0], xs1);
00158 PBCSHIFT(ys2,-pbcshift[1], ys1);
00159 PBCSHIFT(zs2, pbcshift[2], zs1);
00160
00161
00162
00163
00164 rc = ((c & 0xff0000) >> 16) / 255.0;
00165 gc = ((c & 0x00ff00) >> 8) / 255.0;
00166 bc = ((c & 0x0000ff)) / 255.0;
00167
00168 glBegin (GL_LINES);
00169 glColor3f (rc, gc, bc);
00170 glVertex3d (xs1, ys1, zs1);
00171 glVertex3d (xs2, ys2, zs2);
00172 glEnd();
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182 void SYWindow::Draw3DPixel (YPoint point)
00183 {
00184 double x, y, r, xs, ys, zs;
00185 unsigned c, attr, attr_real;
00186 int dlist;
00187 float rc, gc, bc;
00188
00189
00190
00191
00192
00193
00194
00195
00196 xs = point.x;
00197 ys = point.y;
00198 zs = point.z;
00199 r = point.r;
00200 c = point.c;
00201 attr=point.attr;
00202
00203 PBCSHIFT(xs,pbcshift[0],0);
00204 PBCSHIFT(ys,-pbcshift[1],0);
00205 PBCSHIFT(zs,pbcshift[2],0);
00206
00207 if (r > maxpointradius) r=maxpointradius;
00208
00209 if (((x<-r)||(x>(int)width+r))||((y<-r)||(y>(int)height+r))) return;
00210
00211 if(sphere_render==0)
00212 attr_real = attr;
00213 else
00214 attr_real = sphere_render;
00215
00216 if (attr_real == 1)
00217 dlist = SceneDlist.disc_dlist;
00218 else
00219 dlist = SceneDlist.surf_dlist;
00220
00221
00222
00223 glPushMatrix();
00224 glTranslated (xs, ys, zs);
00225 glScaled (r, r, r);
00226
00227 glRotatef (-SceneXform.rot[2], 0.0, 0.0, 1.0);
00228 glRotatef (-SceneXform.rot[1], 0.0, 1.0, 0.0);
00229 glRotatef (-SceneXform.rot[0], 1.0, 0.0, 0.0);
00230
00231 rc = ((c & 0xff0000) >> 16) / 255.0;
00232 gc = ((c & 0x00ff00) >> 8) / 255.0;
00233 bc = ((c & 0x0000ff)) / 255.0;
00234
00235 glColor3f (rc, gc, bc);
00236
00237 glCallList (dlist);
00238
00239 glPopMatrix();
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249 void SYWindow::paint()
00250 {
00251
00252 int i, j, k, dlist, res, num_stack, ncp;
00253 float r, x, y, t, dt, cpts[100][2];
00254 float rc, gc, bc;
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 rc = ((bgcolor & 0xff0000) >> 16) / 255.0;
00269 gc = ((bgcolor & 0x00ff00) >> 8) / 255.0;
00270 bc = ((bgcolor & 0x0000ff)) / 255.0;
00271 glClearColor (rc,gc,bc,1.0);
00272
00273 glLoadIdentity ();
00274 glPushMatrix ();
00275
00276
00277
00278 glTranslatef (SceneXform.trans[0]+SceneXform.center[0],
00279 SceneXform.trans[1]+SceneXform.center[1],
00280 SceneXform.trans[2]+SceneXform.center[2]);
00281
00282 glRotatef (SceneXform.rot[0], 1.0, 0.0, 0.0);
00283 glRotatef (SceneXform.rot[1], 0.0, 1.0, 0.0);
00284 glRotatef (SceneXform.rot[2], 0.0, 0.0, 1.0);
00285
00286 glScalef (SceneXform.scale[0], SceneXform.scale[0], SceneXform.scale[0]);
00287
00288 glTranslatef (-SceneXform.center[0], -SceneXform.center[1], -SceneXform.center[2]);
00289
00290 for (i = 0; i < nL; i++) {
00291 Draw3DLine (Lines[i]);
00292 }
00293
00294
00295
00296
00297 res = 12; num_stack = 8;
00298
00299 if (!SceneDlist.disc_dlist) {
00300 r = 1.0;
00301 ncp = 15;
00302 dt = (2.0 * M_PI) / (ncp - 1);
00303 t = 0.0;
00304
00305 for (i = 0; i < ncp; i++) {
00306 cpts[i][0] = sin(t);
00307 cpts[i][1] = cos(t);
00308 t += dt;
00309 }
00310
00311 dlist = glGenLists (1);
00312
00313 glNewList (dlist, GL_COMPILE);
00314
00315 glBegin (GL_TRIANGLES);
00316 glNormal3f(0.0, 0.0, 1.0);
00317
00318 for (j = 0; j < ncp; j++)
00319 {
00320 if (j == ncp - 1) {
00321 k = 0;
00322 }
00323 else {
00324 k = j + 1;
00325 }
00326
00327 x = r*cpts[j][0];
00328 y = r*cpts[j][1];
00329 glVertex3d (x, y, 0.0);
00330 x = r*cpts[k][0];
00331 y = r*cpts[k][1];
00332 glVertex3d (x, y, 0.0);
00333 glVertex3d (0.0, 0.0, 0.0);
00334 }
00335
00336 glEnd ();
00337
00338 glBegin (GL_LINES);
00339 glColor3f (0, 0, 0);
00340
00341 for (j = 0; j < ncp; j++) {
00342 if (j == ncp - 1) {
00343 k = 0;
00344 }
00345 else {
00346 k = j + 1;
00347 }
00348
00349 x = r*cpts[j][0];
00350 y = r*cpts[j][1];
00351 glVertex3d (x, y, 0.0);
00352 x = r*cpts[k][0];
00353 y = r*cpts[k][1];
00354 glVertex3d (x, y, 0.0);
00355 }
00356
00357 glEnd ();
00358 glEndList();
00359 SceneDlist.disc_dlist = dlist;
00360 }
00361
00362 if (!SceneDlist.surf_dlist) {
00363 r = 1.0;
00364 dlist = glGenLists (1);
00365 glNewList (dlist, GL_COMPILE);
00366 opengl_SurfGenSphere (SPHERE_REP_SOLID, r, res, num_stack);
00367 glEndList();
00368 SceneDlist.surf_dlist = dlist;
00369 }
00370
00371 for (i = 0; i < nP;i++) {
00372 Draw3DPixel (Points[i]);
00373 }
00374
00375 if (drawframe)
00376 {
00377 float frame[12][6] = { {-1,-1,-1,-1,-1, 1},
00378 {-1, 1,-1,-1, 1, 1},
00379 { 1,-1,-1, 1,-1, 1},
00380 { 1, 1,-1, 1, 1, 1},
00381 {-1,-1,-1,-1, 1,-1},
00382 {-1,-1, 1,-1, 1, 1},
00383 { 1,-1,-1, 1, 1,-1},
00384 { 1,-1, 1, 1, 1, 1},
00385 {-1,-1,-1, 1,-1,-1},
00386 {-1,-1, 1, 1,-1, 1},
00387 {-1, 1,-1, 1, 1,-1},
00388 {-1, 1, 1, 1, 1, 1} };
00389 glColor3f (1.0, 1.0, 1.0);
00390 for(i=0;i<12;i++)
00391 {
00392 glBegin(GL_LINES);
00393 glVertex3d (frame[i][0],frame[i][1],frame[i][2]);
00394 glVertex3d (frame[i][3],frame[i][4],frame[i][5]);
00395 glEnd();
00396 }
00397 }
00398
00399 glPopMatrix ();
00400 }
00401
00402
00403
00404 int SYWindow::identify(int px, int py)
00405 {
00406 int i;
00407 int hit;
00408 double xs, ys, zs, Z;
00409 hit=-1;
00410 for(i=0;i<nP;i++)
00411 {
00412 int x, y, r;
00413 if(Points[i].dscrpt[0]!=0)
00414 {
00415 xs = Points[i].x;
00416 ys = Points[i].y;
00417 zs = Points[i].z;
00418
00419 PBCSHIFT(xs,pbcshift[0],0);
00420 PBCSHIFT(ys,-pbcshift[1],0);
00421 PBCSHIFT(zs,pbcshift[2],0);
00422
00423 Z=A31*xs+A32*ys+A33*zs;
00424 x=(int)CX(A11*xs+A12*ys+A13*zs,Z);
00425 y=(int)CY(A21*xs+A22*ys+A23*zs,Z);
00426 r=(int)CR(Points[i].r,Z);
00427 if((px<x+r)&&(px>x-r)&&(py<y+r)&&(py>y-r))
00428 {
00429 hit=i;
00430 #ifdef _GENERAL_H
00431 INFO("point("<<px<<","<<py<<"): "<<Points[i].dscrpt);
00432 #else
00433 fprintf(stdout,"point (%d,%d): %s\n",px,py,Points[i].dscrpt);
00434 #endif
00435 }
00436 }
00437 }
00438 return hit;
00439 }
00440
00441
00442 void SYWindow::update()
00443 {
00444 fprintf (stderr,"\n---------- SYWindow update ---------- \n");
00445 fflush (stderr);
00446
00447 if(!alive) return;
00448 Lock();
00449
00450 paint();
00451
00452 Unlock();
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462 static void (*action_func[BUTTON_MAX])(int, int, int, int, int);
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 void display (void)
00473 {
00474
00475 int win;
00476
00477 int wobj;
00478
00479
00480
00481
00482
00483 win = glutGetWindow();
00484 event_WinObjGet (win, &wobj);
00485 ((SYWindow *)wobj)->update();
00486 }
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 void viewport_Set (int win, int w, int h)
00498 {
00499
00500 float xmin, xmax, ymin, ymax, zmin, zmax;
00501
00502 float dz;
00503
00504 int wobj;
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 event_WinObjGet (win, &wobj);
00517
00518 xmin = ((SYWindow *)wobj)->VpExtent.xmin;
00519 ymin = ((SYWindow *)wobj)->VpExtent.ymin;
00520 zmin = ((SYWindow *)wobj)->VpExtent.zmin;
00521 xmax = ((SYWindow *)wobj)->VpExtent.xmax;
00522 ymax = ((SYWindow *)wobj)->VpExtent.ymax;
00523 zmax = ((SYWindow *)wobj)->VpExtent.zmax;
00524
00525
00526
00527
00528
00529
00530 glViewport (0, 0, w, h);
00531
00532 glMatrixMode (GL_PROJECTION);
00533
00534 glLoadIdentity();
00535
00536 dz = zmax - zmin;
00537 zmin -= 10*dz;
00538 zmax += 10*dz;
00539
00540 glOrtho (xmin, xmax, ymin, ymax, zmin, zmax);
00541
00542 glMatrixMode (GL_MODELVIEW);
00543 }
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 void opengl_SurfGenSphere (SphereRep dtype, float radius, int slices, int stacks)
00555 {
00556
00557 float rho, drho, theta, dtheta;
00558
00559 float x, y, z;
00560
00561 int i, j, imin, imax;
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 drho = M_PI / (float) stacks;
00575 dtheta = 2.0 * M_PI / (float) slices;
00576
00577 imin = 1;
00578 imax = stacks / 2;
00579
00580 if (dtype == SPHERE_REP_POINT) {
00581 glBegin (GL_POINTS);
00582
00583 for (j = 0; j <= slices; j++) {
00584 theta = (j == slices) ? 0.0 : j * dtheta;
00585 x = (float)(-sin(theta) * sin(drho));
00586 y = (float)(cos(theta) * sin(drho));
00587 z = (float)(cos(drho));
00588 glVertex3f (x * radius, y * radius, z * radius);
00589 }
00590
00591 for (i = imin; i < imax; i++) {
00592 rho = i * drho;
00593
00594 for (j = 0; j <= slices; j++) {
00595 theta = (j == slices) ? 0.0f : j * dtheta;
00596 x = (float)(-sin(theta) * sin(rho));
00597 y = (float)(cos(theta) * sin(rho));
00598 z = (float)(cos(rho));
00599 glVertex3f (x * radius, y * radius, z * radius);
00600 }
00601 }
00602
00603 glEnd();
00604 return;
00605 }
00606
00607 if (dtype == SPHERE_REP_LINE) {
00608 for (i = imin; i < imax; i++) {
00609 rho = i * drho;
00610 glBegin (GL_LINE_LOOP);
00611
00612 for (j = 0; j <= slices; j++) {
00613 theta = (j == slices) ? 0.0f : j * dtheta;
00614 x = (float)(-sin(theta) * sin(rho));
00615 y = (float)(cos(theta) * sin(rho));
00616 z = (float)(cos(rho));
00617 glVertex3f (x*radius, y*radius, z*radius);
00618 }
00619
00620 glEnd();
00621
00622 glBegin (GL_LINES);
00623
00624 for (j = 0; j <= slices; j++) {
00625 theta = (j == slices) ? 0.0 : j * dtheta;
00626 x = (float)(-sin(theta) * sin(rho));
00627 y = (float)(cos(theta) * sin(rho));
00628 z = (float)(cos(rho));
00629 glVertex3f (0.0, 0.0, 0.0);
00630 glVertex3f (x*radius, y*radius, z*radius);
00631 }
00632
00633 glEnd();
00634 }
00635
00636 return;
00637 }
00638
00639
00640
00641
00642 glBegin (GL_TRIANGLE_FAN);
00643 glNormal3f (0.0, 0.0, 1.0);
00644 glVertex3f (0.0, 0.0, radius);
00645
00646 for (j = 0; j <= slices; j++) {
00647 theta = (j == slices) ? 0.0 : j * dtheta;
00648 x = (float)(-sin(theta) * sin(drho));
00649 y = (float)(cos(theta) * sin(drho));
00650 z = (float)(cos(drho));
00651
00652 glNormal3f (x, y, z);
00653 glVertex3f (x * radius, y * radius, z * radius);
00654 }
00655
00656 glEnd();
00657
00658
00659
00660
00661 for (i = imin; i < imax; i++) {
00662 rho = i * drho;
00663
00664 glBegin (GL_QUAD_STRIP);
00665
00666 for (j = 0; j <= slices; j++) {
00667 theta = (j == slices) ? 0.0f : j * dtheta;
00668 x = (float)(-sin(theta) * sin(rho));
00669 y = (float)(cos(theta) * sin(rho));
00670 z = (float)(cos(rho));
00671 glNormal3f(x, y, z);
00672 glVertex3f(x * radius, y * radius, z * radius);
00673
00674 x = (GLfloat)(-sin(theta) * sin(rho + drho));
00675 y = (GLfloat)(cos(theta) * sin(rho + drho));
00676 z = (GLfloat)(cos(rho + drho));
00677 glNormal3f(x, y, z);
00678 glVertex3f(x * radius, y * radius, z * radius);
00679 }
00680
00681 glEnd();
00682 }
00683 }
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697 void event_WinObjGet (int win, int *p)
00698 {
00699
00700 int i;
00701
00702
00703
00704
00705
00706 for (i = 0; i < num_win; i++) {
00707 if (win == win_table[i][0]) {
00708 *p = win_table[i][1];
00709 }
00710 }
00711 }
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 void event_WinReshape (int width, int height)
00722 {
00723
00724 int win;
00725
00726 float xmin, xmax, ymin, ymax, zmin, zmax;
00727
00728 float cx, cy;
00729
00730 float dx, dy;
00731
00732 float f;
00733
00734 int wobj;
00735
00736
00737
00738
00739
00740
00741 win = glutGetWindow();
00742 event_WinObjGet (win, &wobj);
00743
00744 xmin = ((SYWindow *)wobj)->VpExtent.xmin;
00745 ymin = ((SYWindow *)wobj)->VpExtent.ymin;
00746 zmin = ((SYWindow *)wobj)->VpExtent.zmin;
00747 xmax = ((SYWindow *)wobj)->VpExtent.xmax;
00748 ymax = ((SYWindow *)wobj)->VpExtent.ymax;
00749 zmax = ((SYWindow *)wobj)->VpExtent.zmax;
00750
00751 cx = (xmax + xmin) / 2.0;
00752 cy = (ymax + ymin) / 2.0;
00753 dx = xmax - xmin;
00754 dy = ymax - ymin;
00755
00756
00757
00758
00759
00760 if (width <= height) {
00761 f = (float)height / (float)width;
00762 dy = dx * f;
00763 ymin = cy - dy / 2.0;
00764 ymax = cy + dy / 2.0;
00765 }
00766 else {
00767 f = (float)width / (float)height;
00768 dx = dy * f;
00769 xmin = cx - dx / 2.0;
00770 xmax = cx + dx / 2.0;
00771 }
00772
00773 ((SYWindow *)wobj)->VpExtent.xmin = xmin;
00774 ((SYWindow *)wobj)->VpExtent.xmax = xmax;
00775 ((SYWindow *)wobj)->VpExtent.ymin = ymin;
00776 ((SYWindow *)wobj)->VpExtent.ymax = ymax;
00777
00778 viewport_Set (win, width, height);
00779
00780 ((SYWindow *)wobj)->update();
00781 }
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791 void event_KeyboardProc (unsigned char ch, int x, int y)
00792 {
00793 int win, wobj;
00794
00795
00796
00797
00798 if (ch == KEY_ESCAPE) {
00799 exit (0);
00800 }
00801
00802 win = glutGetWindow();
00803 event_WinObjGet (win, &wobj);
00804
00805
00806
00807 switch (ch) {
00808 case 'p':
00809 ((SYWindow *)wobj)->TogglePause();
00810 #ifdef _GENERAL_H
00811 INFO("Pause="<<((SYWindow *)wobj)->pause);return;
00812 #else
00813 fprintf(stdout,"Pause=%d",(int)pause);return;
00814 #endif
00815 break;
00816
00817 case 'b':
00818 ((SYWindow *)wobj)->sphere_render++;
00819 ((SYWindow *)wobj)->sphere_render%=3;
00820 #ifdef _GENERAL_H
00821 INFO("Sphere render scheme ="<<((SYWindow *)wobj)->sphere_render);
00822 #else
00823 fprintf(stdout,"Sphere render scheme ="<<((SYWindow *)wobj)->sphere_render);
00824 #endif
00825 display ();
00826 break;
00827
00828 case 'h':
00829 const char helpstr[]=
00830 "YWindow based on OpenGL:\n"
00831 "Mouse drag to rotate\n"
00832 "Hot Keys:\n"
00833 "F1 : display this message\n"
00834 "b : change sphere rendering scheme\n"
00835 "F10 : output postscript\n";
00836 #ifdef _GENERAL_H
00837 INFO("YWindow: "<<helpstr);
00838 #else
00839 fprintf(stdout,"YWindow: %s\n",helpstr);
00840 #endif
00841 break;
00842
00843 }
00844 }
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854 void event_SpecialProc (int key, int x, int y)
00855 {
00856 int win, wobj;
00857
00858
00859
00860
00861 win = glutGetWindow();
00862 event_WinObjGet (win, &wobj);
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 switch (key)
00875 {
00876 case 10:
00877 ((SYWindow *)wobj)->writeps();
00878 fprintf(stderr,"not fully implemented yet\n");
00879 break;
00880 }
00881
00882 }
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892 void event_IdleProc()
00893 {
00894
00895 int i;
00896
00897 void *p;
00898
00899
00900
00901
00902
00903 for (i = 0; i < num_win; i++) {
00904 p = (void*)win_table[i][1];
00905
00906 if (((SYWindow *)p)->dirty) {
00907
00908 ((SYWindow *)p)->update();
00909 ((SYWindow *)p)->dirty = false;
00910 }
00911 }
00912 }
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922 void event_Butp (int button, int state, int x, int y)
00923 {
00924
00925 int mx, my;
00926
00927 int key_mod, shift, ctrl;
00928
00929 int win;
00930
00931 EventButtonId button_id;
00932
00933 int dx, dy;
00934
00935 int wobj;
00936
00937
00938
00939
00940
00941 #ifdef dbg_EventButp
00942 fprintf (stderr, "\n --------- EventButP --------- \n");
00943 fprintf (stderr, " >>>>>> button [%d] \n", button);
00944 fprintf (stderr, " >>>>>> state [%d] \n", state);
00945 #endif
00946
00947 win = glutGetWindow();
00948 event_WinObjGet (win, &wobj);
00949
00950 if (state == GLUT_UP) {
00951 event_Butr (x, y, button_id);
00952 return;
00953 }
00954
00955
00956
00957
00958 key_mod = glutGetModifiers();
00959 shift = (key_mod == GLUT_ACTIVE_SHIFT);
00960 ctrl = (key_mod == GLUT_ACTIVE_CTRL);
00961
00962 switch (button) {
00963 case GLUT_LEFT_BUTTON:
00964 if (shift)
00965 button_id = BUTTON_SHIFT_LEFT;
00966 else if (ctrl)
00967 button_id = BUTTON_CTRL_LEFT;
00968 else
00969 button_id = BUTTON_LEFT;
00970 break;
00971
00972 case GLUT_MIDDLE_BUTTON:
00973 if (shift)
00974 button_id = BUTTON_SHIFT_MIDDLE;
00975 else if (ctrl)
00976 button_id = BUTTON_CTRL_MIDDLE;
00977 else
00978 button_id = BUTTON_MIDDLE;
00979 break;
00980
00981 case GLUT_RIGHT_BUTTON:
00982 if (shift)
00983 button_id = BUTTON_SHIFT_RIGHT;
00984 else if (ctrl)
00985 button_id = BUTTON_CTRL_RIGHT;
00986 else
00987 button_id = BUTTON_RIGHT;
00988 break;
00989 }
00990
00991 mx = x;
00992 my = y;
00993
00994 ((SYWindow *)wobj)->Event_info.type = EVENT_BUTTON_PRESS;
00995 ((SYWindow *)wobj)->Event_info.button_id = button_id;
00996
00997 if (((SYWindow *)wobj)->Event_info.mouse_pos_set) {
00998 dx = mx - ((SYWindow *)wobj)->Event_info.mx;
00999 dy = my - ((SYWindow *)wobj)->Event_info.my;
01000
01001 if ((button_id >= 0) && (button_id < BUTTON_MAX)) {
01002 (*action_func[button_id])(win, mx, my, dx, dy);
01003 }
01004 }
01005
01006 else {
01007 ((SYWindow *)wobj)->Event_info.mouse_pos_set = 1;
01008 dx = 0;
01009 dy = 0;
01010
01011 if ((button_id >= 0) && (button_id < BUTTON_MAX)) {
01012 (*action_func[button_id])(win, mx, my, dx, dy);
01013 }
01014 }
01015
01016 ((SYWindow *)wobj)->Event_info.mx = mx;
01017 ((SYWindow *)wobj)->Event_info.my = my;
01018 }
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029 void event_Motion (int mx, int my)
01030 {
01031
01032 int win;
01033
01034 int dx, dy;
01035
01036 int wobj;
01037
01038
01039
01040
01041
01042 #ifdef EventMotion
01043 fprintf (stderr, "\n --------- EventMotion --------- \n");
01044 #endif
01045
01046 win = glutGetWindow();
01047 event_WinObjGet (win, &wobj);
01048 ((SYWindow *)wobj)->Event_info.type = EVENT_MOUSE_MOTION;
01049
01050 if (((SYWindow *)wobj)->Event_info.mouse_pos_set) {
01051 dx = mx - ((SYWindow*)wobj)->Event_info.mx;
01052 dy = my - ((SYWindow*)wobj)->Event_info.my;
01053
01054 if (((SYWindow *)wobj)->Event_info.action != WINDOW_ACTION_NONE) {
01055 (*((SYWindow *)wobj)->Event_info.action_func)(win, mx, my, dx, dy);
01056 }
01057 }
01058 else {
01059 ((SYWindow *)wobj)->Event_info.mx = mx;
01060 ((SYWindow *)wobj)->Event_info.my = my;
01061 ((SYWindow *)wobj)->Event_info.mouse_pos_set = 1;
01062 }
01063
01064 ((SYWindow *)wobj)->Event_info.mx = mx;
01065 ((SYWindow *)wobj)->Event_info.my = my;
01066 }
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 void event_Butr (int mx, int my, EventButtonId button_id)
01077 {
01078
01079 int win, wobj;
01080
01081
01082
01083
01084
01085
01086
01087 win = glutGetWindow();
01088 event_WinObjGet (win, &wobj);
01089
01090 ((SYWindow *)wobj)->Event_info.mx = mx;
01091 ((SYWindow *)wobj)->Event_info.my = my;
01092 ((SYWindow *)wobj)->Event_info.mouse_pos_set = 0;
01093 ((SYWindow *)wobj)->Event_info.type = EVENT_NONE;
01094 ((SYWindow *)wobj)->Event_info.action = WINDOW_ACTION_NONE;
01095 }
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105 void event_WinActionRotxy (int win, int mx, int my, int dx, int dy)
01106 {
01107
01108 float rx, ry;
01109
01110 int wobj;
01111
01112
01113
01114
01115
01116 event_WinObjGet (win, &wobj);
01117
01118
01119
01120
01121 ((SYWindow *)wobj)->Event_info.action = WINDOW_ACTION_ROTATE_XY;
01122 ((SYWindow *)wobj)->Event_info.action_func = event_WinActionRotxy;
01123
01124 if (((SYWindow *)wobj)->Event_info.type == EVENT_BUTTON_PRESS) {
01125 return;
01126 }
01127
01128 rx = (float)dy * ((SYWindow *)wobj)->SceneXformMap.rot;
01129 ry = (float)dx * ((SYWindow *)wobj)->SceneXformMap.rot;
01130
01131 if ((fabs(rx) < 1.0) && (fabs(ry) < 1.0)) {
01132 return;
01133 }
01134
01135 ((SYWindow *)wobj)->SceneXform.rot[0] += rx;
01136 ((SYWindow *)wobj)->SceneXform.rot[1] += ry;
01137
01138 display ();
01139 }
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149 void event_WinActionRotz (int win, int mx, int my, int dx, int dy)
01150 {
01151
01152 int wobj;
01153
01154 float rz;
01155
01156
01157
01158
01159
01160
01161
01162 event_WinObjGet (win, &wobj);
01163
01164 ((SYWindow *)wobj)->Event_info.action = WINDOW_ACTION_ROTATE_Z;
01165 ((SYWindow *)wobj)->Event_info.action_func = event_WinActionRotz;
01166
01167 rz = (float)(dx + dy) * ((SYWindow *)wobj)->SceneXformMap.rot;
01168 ((SYWindow *)wobj)->SceneXform.rot[2] += rz;
01169
01170 display ();
01171 }
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181 void event_WinActionPick (int win, int mx, int my, int dx, int dy)
01182 {
01183
01184
01185
01186
01187
01188 }
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198 void event_WinActionTransxy (int win, int mx, int my, int dx, int dy)
01199 {
01200
01201 int wobj;
01202
01203 float tx, ty;
01204
01205
01206
01207
01208
01209 event_WinObjGet (win, &wobj);
01210
01211 ((SYWindow *)wobj)->Event_info.action = WINDOW_ACTION_TRANSLATE_XY;
01212 ((SYWindow *)wobj)->Event_info.action_func = event_WinActionTransxy;
01213
01214 tx = (float)dx * ((SYWindow *)wobj)->SceneXformMap.translate[0];
01215 ty = (float)-dy * ((SYWindow *)wobj)->SceneXformMap.translate[1];
01216
01217 ((SYWindow *)wobj)->SceneXform.trans[0] += tx;
01218 ((SYWindow *)wobj)->SceneXform.trans[1] += ty;
01219
01220 display ();
01221 }
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231 void event_WinActionTransz (int win, int mx, int my, int dx, int dy)
01232 {
01233
01234 int wobj;
01235
01236 float tz;
01237
01238
01239
01240
01241
01242 event_WinObjGet (win, &wobj);
01243
01244 ((SYWindow *)wobj)->Event_info.action = WINDOW_ACTION_TRANSLATE_Z;
01245 ((SYWindow *)wobj)->Event_info.action_func = event_WinActionTransz;
01246
01247 tz = (float)(dx + dy) * ((SYWindow *)wobj)->SceneXformMap.translate[2];
01248
01249 ((SYWindow *)wobj)->SceneXform.trans[2] += tz;
01250
01251 display ();
01252 }
01253
01254
01255
01256
01257
01258
01259
01260
01261 void event_WinActionScale (int win, int mx, int my, int dx, int dy)
01262 {
01263
01264 int wobj;
01265
01266 float scale;
01267
01268 float d;
01269
01270
01271
01272
01273
01274
01275
01276
01277 event_WinObjGet (win, &wobj);
01278
01279 ((SYWindow *)wobj)->Event_info.action = WINDOW_ACTION_SCALE;
01280 ((SYWindow *)wobj)->Event_info.action_func = event_WinActionScale;
01281 d = (float)(dx + dy);
01282
01283 if (d < 0.0) {
01284 scale = 1.0 / ((SYWindow *)wobj)->SceneXformMap.scale;
01285 }
01286 else if (d == 0.0) {
01287 scale = 1.0;
01288 }
01289 else {
01290 scale = ((SYWindow *)wobj)->SceneXformMap.scale;
01291 }
01292
01293 ((SYWindow *)wobj)->SceneXform.scale[0] *= scale;
01294 ((SYWindow *)wobj)->SceneXform.scale[1] *= scale;
01295 ((SYWindow *)wobj)->SceneXform.scale[2] *= scale;
01296
01297 display ();
01298 }
01299
01300
01301
01302 void SYWindow::newGraph()
01303 {
01304 if (!alive) {
01305 alive = true;
01306 }
01307
01308 dirty = true;
01309 }
01310
01311 void SYWindow::Evolve()
01312 {
01313 fprintf (stderr,"\n----------SYWindow evolve ---------- \n");
01314 fflush (stderr);
01315
01316 if(!alive) return;
01317
01318 if(dirty)
01319 {
01320 dirty=false;
01321 update();
01322 }
01323 }
01324
01325 void SYWindow::DrawPoint(double x, double y, double z, double r,
01326 unsigned long c, unsigned long attr)
01327 {
01328 if(nP<MaxPoints-1)
01329 {
01330 Points[nP].x=x;
01331 Points[nP].y=y;
01332 Points[nP].z=z;
01333 Points[nP].r=r;
01334 Points[nP].c=c;
01335 Points[nP].attr=attr;
01336 Points[nP].dscrpt[0]=0;
01337 nP++;
01338 }
01339 else if(nP==MaxPoints-1)
01340 {
01341 #ifdef _GENERAL_H
01342 WARNING("SYWindow: Too many points (more than "
01343 << (int)MaxPoints
01344 << "), ignoring");
01345 #else
01346 fprintf(stderr,"SYWindow: Too many points (more than %d"
01347 "), ignoring\n\n", (int)MaxPoints );
01348 #endif
01349 Points[nP].x=x;
01350 Points[nP].y=y;
01351 Points[nP].z=z;
01352 Points[nP].r=r;
01353 Points[nP].c=c;
01354 Points[nP].attr=attr;
01355 Points[nP].dscrpt[0]=0;
01356 nP++;
01357 }
01358 }
01359
01360 void SYWindow::DrawPoint(double x, double y, double z, double r,
01361 unsigned long c, char *ds, unsigned long attr)
01362 {
01363 if(nP<MaxPoints-1)
01364 {
01365 Points[nP].x=x;
01366 Points[nP].y=y;
01367 Points[nP].z=z;
01368 Points[nP].r=r;
01369 Points[nP].c=c;
01370 Points[nP].attr=attr;
01371 strncpy(Points[nP].dscrpt,ds,DSCLEN-1);
01372 nP++;
01373 }
01374 else if (nP==MaxPoints-1)
01375 {
01376 #ifdef _GENERAL_H
01377 WARNING("SYWindow: Too many points (more than "
01378 << (int)MaxPoints
01379 << "), ignoring");
01380 #else
01381 fprintf(stderr,"SYWindow: Too many points (more than %d"
01382 "), ignoring", (int)MaxPoints );
01383 #endif
01384 Points[nP].x=x;
01385 Points[nP].y=y;
01386 Points[nP].z=z;
01387 Points[nP].r=r;
01388 Points[nP].c=c;
01389 Points[nP].attr=attr;
01390 strncpy(Points[nP].dscrpt,ds,DSCLEN-1);
01391 nP++;
01392 }
01393
01394 }
01395
01396 void SYWindow::DrawLine(double x0, double y0, double z0,
01397 double x1, double y1, double z1, unsigned long c,
01398 double r, unsigned long attr)
01399 {
01400 if(nL<MaxLines-1)
01401 {
01402 Lines[nL].x0=x0;
01403 Lines[nL].y0=y0;
01404 Lines[nL].z0=z0;
01405 Lines[nL].x1=x1;
01406 Lines[nL].y1=y1;
01407 Lines[nL].z1=z1;
01408 Lines[nL].c=c;
01409 Lines[nL].r=r;
01410 Lines[nL].attr=attr;
01411 nL++;
01412 }
01413 else if(nL==MaxLines-1)
01414 {
01415 #ifdef _GENERAL_H
01416 WARNING("SYWindow: Too many lines (more than "
01417 << (int)MaxLines
01418 << "), ignoring");
01419 #else
01420 fprintf(stderr,"SYWindow: Too many lines (more than %d"
01421 "), ignoring\n\n", (int)MaxLines );
01422 #endif
01423 Lines[nL].x0=x0;
01424 Lines[nL].y0=y0;
01425 Lines[nL].z0=z0;
01426 Lines[nL].x1=x1;
01427 Lines[nL].y1=y1;
01428 Lines[nL].z1=z1;
01429 Lines[nL].c=c;
01430 Lines[nL].r=r;
01431 Lines[nL].attr=attr;
01432 nL++;
01433 }
01434 }
01435
01436 SYWindow::SYWindow(int width_hint, int height_hint,
01437 const char *winname, bool s, bool so, bool fm)
01438 {
01439 #ifdef USE_X
01440 XSizeHints myhint;
01441 unsigned long mask;
01442 Cursor arrow;
01443 #endif
01444
01445
01446
01447
01448
01449
01450
01451
01452 initRot();copyRot();
01453
01454 int argc = 1;
01455
01456 char *argv = "md++";
01457
01458 float xmin, xmax, ymin, ymax, zmin, zmax;
01459
01460 float d, dx, dy, dz;
01461
01462 static float f = 0.001;
01463
01464
01465 glutInit (&argc, &argv);
01466
01467 glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
01468
01469 width = width_hint;
01470 height = height_hint;
01471 ksfeedback = 0;
01472
01473
01474
01475
01476 Event_info.mouse_pos_set = 0;
01477 Event_info.type = EVENT_NONE;
01478 Event_info.button_id = BUTTON_UNKNOWN;
01479 Event_info.button_state = EVENT_BUTTON_STATE_NONE;
01480 Event_info.action = WINDOW_ACTION_NONE;
01481 Event_info.mx = 0;
01482 Event_info.my = 0;
01483
01484
01485
01486
01487 d = 1.5;
01488 VpExtent.xmin = -d;
01489 VpExtent.ymin = -d;
01490 VpExtent.zmin = -10*d;
01491 VpExtent.xmax = d;
01492 VpExtent.ymax = d;
01493 VpExtent.zmax = 10*d;
01494
01495 SceneXform.rot[0] = 0.0;
01496 SceneXform.rot[1] = 0.0;
01497 SceneXform.rot[2] = 0.0;
01498
01499 SceneXform.trans[0] = 0.0;
01500 SceneXform.trans[1] = 0.0;
01501 SceneXform.trans[2] = 0.0;
01502
01503 SceneXform.scale[0] = 1.0;
01504 SceneXform.scale[1] = 1.0;
01505 SceneXform.scale[2] = 1.0;
01506
01507 SceneXform.center[0] = 0.0;
01508 SceneXform.center[1] = 0.0;
01509 SceneXform.center[2] = 0.0;
01510
01511 SceneDlist.disc_dlist = 0;
01512 SceneDlist.point_dlist = 0;
01513 SceneDlist.line_dlist = 0;
01514 SceneDlist.surf_dlist = 0;
01515
01516
01517
01518
01519 action_func[BUTTON_LEFT] = event_WinActionRotxy;
01520 action_func[BUTTON_SHIFT_LEFT] = event_WinActionRotz;
01521 action_func[BUTTON_CTRL_LEFT] = event_WinActionPick;
01522 action_func[BUTTON_RIGHT] = event_WinActionTransxy;
01523 action_func[BUTTON_SHIFT_RIGHT] = event_WinActionTransz;
01524 action_func[BUTTON_CTRL_RIGHT] = event_WinActionScale;
01525
01526
01527
01528
01529
01530 SceneXformMap.rot = 0.5;
01531 SceneXformMap.scale = 1.1;
01532
01533 xmin = VpExtent.xmin;
01534 ymin = VpExtent.xmin;
01535 zmin = VpExtent.zmin;
01536 xmax = VpExtent.xmax;
01537 ymax = VpExtent.xmax;
01538 zmax = VpExtent.zmax;
01539
01540 dx = xmax - xmin;
01541 dy = ymax - ymin;
01542 dz = zmax - zmin;
01543
01544 SceneXformMap.translate[0] = f * dx;
01545 SceneXformMap.translate[1] = f * dy;
01546 SceneXformMap.translate[2] = f * dz;
01547
01548 sphere_render = 0;
01549
01550 alive=false;
01551 pause=false;
01552
01553 autowritegif=false;
01554
01555 framecolor = cwhite;
01556
01557 newGraph();
01558
01559
01560 nL=nP=0;
01561
01562
01563
01564
01565
01566 InitSem();
01567 Unlock();
01568
01569
01570
01571
01572 InitSem2();
01573
01574
01575 square = s;
01576 sort = so;
01577 drawframe = fm;
01578 X0=Y0=X00=Y00=0;Scale=Scale0=1;Aspr=Aspr0=1;
01579
01580 D=D0=10000;
01581
01582 gifcount=0;pscount=0;
01583
01584
01585 lastDrag = (unsigned long) (-1);
01586
01587 rinterval=0;
01588 msrsp=ROTATION;
01589
01590 scalepoints = 1;
01591 enable_pbc = 0;
01592 pbcshift[0]=pbcshift[1]=pbcshift[2]=0 ;
01593 maxpointradius = 100;
01594 maxlinewidth = 100;
01595 }
01596
01597 SYWindow::~SYWindow()
01598 {
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609 FreeResource();
01610 }
01611
01612 void SYWindow::reversergb()
01613 {
01614 int j;
01615 unsigned long L;
01616
01617 for(j=0;j<6;j++)
01618 {
01619 L=CCT[0][j];
01620 CCT[0][j]=CCT[2][j];
01621 CCT[2][j]=L;
01622 }
01623 }
01624
01625
01626
01627
01628
01629
01630
01631
01632 unsigned long
01633 SYWindow::AllocRGBColor (unsigned r, unsigned g, unsigned b)
01634 {
01635
01636 #ifdef USE_X
01637 XColor c;
01638 c.red=r, c.green=g, c.blue=b;
01639
01640 #ifdef _GENERAL_H
01641 if(XAllocColor(theDisplay, cmap, &c)==0)
01642 WARNING("Error allocating color ("<<r<<", "<<g<<", "<<b<<")");
01643 #else
01644 if(XAllocColor(theDisplay, cmap, &c)==0)
01645 fprintf(stderr,"Error allocating color (%d,%d,%d)\n",r,g,b);
01646 #endif
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656 return c.pixel;
01657
01658 #else
01659
01660 unsigned long val;
01661 val = b + 256 * (g + 256*r);
01662
01663 fprintf (stderr, " SYWindow::AllocRGBColor: rgb (%d %d %d) \n", r, g, b);
01664 return val;
01665
01666 #endif
01667
01668 }
01669
01670
01671
01672
01673
01674
01675
01676
01677 unsigned long SYWindow::AllocShortRGBColor(unsigned r, unsigned g, unsigned b)
01678 {
01679 unsigned long val;
01680 val = b + 256 * (g + 256*r);
01681 return val;
01682 }
01683
01684
01685
01686
01687
01688
01689
01690
01691 unsigned long SYWindow::AllocNamedColor(char *name)
01692 {
01693 fprintf(stderr, "SYWindow::AllocNamedColor not supported in Windows version\n");
01694 return 0;
01695 }
01696
01697 void SYWindow::testcolor()
01698 {
01699
01700 }
01701
01702 void SYWindow::importgif()
01703 {
01704 fprintf(stderr, "SYWindow::importgif not supported in Windows version\n");
01705 }
01706
01707 void SYWindow::Draw3DLinetoPS(FILE *file,YLine line)
01708 {
01709 double xs1,ys1,zs1,xs2,ys2,zs2,Z,r;unsigned attr;
01710 double red,green,blue;
01711 double x1, y1, x2, y2;
01712 attr = line.attr;
01713 xs1 = line.x0;
01714 ys1 = line.y0;
01715 zs1 = line.z0;
01716
01717 PBCSHIFT(xs1,pbcshift[0],0);
01718 PBCSHIFT(ys1,-pbcshift[1],0);
01719 PBCSHIFT(zs1,pbcshift[2],0);
01720
01721 Z=A31*xs1+A32*ys1+A33*zs1;
01722 x1=CX(A11*xs1+A12*ys1+A13*zs1,Z);
01723 y1=CY(A21*xs1+A22*ys1+A23*zs1,Z);
01724 xs2 = line.x1;
01725 ys2 = line.y1;
01726 zs2 = line.z1;
01727
01728 PBCSHIFT(xs2,pbcshift[0],xs1);
01729 PBCSHIFT(ys2,-pbcshift[1],ys1);
01730 PBCSHIFT(zs2,pbcshift[2],zs1);
01731
01732 Z=A31*xs2+A32*ys2+A33*zs2;
01733 x2=CX(A11*xs2+A12*ys2+A13*zs2,Z);
01734 y2=CY(A21*xs2+A22*ys2+A23*zs2,Z);
01735 r=CR(line.r,0);
01736 if(r>maxlinewidth) r=maxlinewidth;
01737 if(r<0.5) r=0.5;
01738
01739
01740
01741 if((((x1<0)||(x1>(int)width))||((y1<0)||(y1>(int)height)))
01742 &&(((x2<0)||(x2>(int)width))||((y2<0)||(y2>(int)height))))
01743 return;
01744
01745
01746
01747
01748 red=REDany(line.c);
01749 green=GREENany(line.c);
01750 blue=BLUEany(line.c);
01751
01752 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb"
01753 " %5.2f %5.2f %5.2f %5.2f m l s\n",
01754 r,red,green,blue,
01755 x1,height-y1,x2,height-y2);
01756 if(attr!=0)
01757 {
01758 double dy,dx,dr;
01759 dy=y2-y1;dx=x2-x1;dr=sqrt(dy*dy+dx*dx);dy/=dr;dx/=dr;
01760 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb"
01761 " %5.2f %5.2f %5.2f %5.2f m l s\n",
01762 0.5,0.,0.,0.,
01763 x1+dy*r/2,height-(y1-dx*r/2),
01764 x2+dy*r/2,height-(y2-dx*r/2));
01765 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb"
01766 " %5.2f %5.2f %5.2f %5.2f m l s\n",
01767 0.5,0.,0.,0.,
01768 x1-dy*r/2,height-(y1+dx*r/2),
01769 x2-dy*r/2,height-(y2+dx*r/2));
01770 }
01771 }
01772
01773 void SYWindow::Draw3DPixeltoPS(FILE *file,YPoint point)
01774 {
01775 double x,y,r;
01776
01777 #ifndef _ALLCIRCLE
01778 unsigned attr;
01779 #endif
01780 double xs, ys, zs, Z;
01781 double red,green,blue;
01782 xs = point.x;
01783 ys = point.y;
01784 zs = point.z;
01785
01786 PBCSHIFT(xs,pbcshift[0],0);
01787 PBCSHIFT(ys,-pbcshift[1],0);
01788 PBCSHIFT(zs,pbcshift[2],0);
01789
01790 #ifndef _ALLCIRCLE
01791 attr = point.attr;
01792 #endif
01793 Z=A31*xs+A32*ys+A33*zs;
01794 x=CX(A11*xs+A12*ys+A13*zs,Z);
01795 y=CY(A21*xs+A22*ys+A23*zs,Z);
01796 r=CR(point.r,Z);
01797 if(((x<-r)||(x>(int)width+r))||((y<-r)||(y>(int)height+r))) return;
01798
01799
01800
01801 red=REDany(point.c);
01802 green=GREENany(point.c);
01803 blue=BLUEany(point.c);
01804
01805 if(r>maxpointradius) r=maxpointradius;
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815 if(attr==0)
01816 {
01817 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb %f %f %f ",
01818 0.5,
01819 1.,1.,1.,
01820 x,height-y,r);
01821 fprintf(file,"disc\n");
01822 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb %f %f %f ",
01823 0.5,
01824 0.,0.,0.,x,height-y,r);
01825 fprintf(file,"circle\n");
01826 }
01827 else if(attr==2)
01828 {
01829 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb %f %f %f ",
01830 0.5,
01831 red,green,blue,
01832 x,height-y,r);
01833 fprintf(file,"disc\n");
01834 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb %f %f %f ",
01835 0.5,
01836 0.,0.,0.,x,height-y,r);
01837 fprintf(file,"circle\n");
01838 }
01839 else
01840 {
01841 fprintf(file,"np %5.2f slw %5.2f %5.2f %5.2f srgb %f %f %f ",
01842 0.5,
01843 red,green,blue,
01844 x,height-y,r);
01845 fprintf(file,"circle\n");
01846 }
01847 }
01848
01849 void SYWindow::writeps()
01850 {
01851 int i;
01852
01853 const char fname[]="Yshot";
01854 char extname[100],tmp[100];
01855 char f1[100];
01856 FILE *file;
01857
01858 char head1[500]="%!PS-Adobe-3.0 EPSF-3.0\n"
01859 "%%Pages: (atend)\n";
01860 char head2[500]="%%BoundingBox:";
01861 char head3[5000]=
01862 "%%EndComments\n"
01863 "/l {lineto} def\n"
01864 "/m {moveto} def\n"
01865 "/t {translate} def\n"
01866 "/slw {setlinewidth} def\n"
01867 "/srgb {setrgbcolor} def\n"
01868 "/np {newpath} def\n"
01869 "/s {stroke} def\n"
01870 "/disc { 0 360 arc fill } def\n"
01871 "/circle { 0 360 arc s } def\n";
01872
01873 char tail[500]="showpage\n";
01874
01875 sprintf(tmp,"%04d",pscount);
01876 strcpy(extname,fname);
01877 strcat(extname,tmp);
01878 sprintf(f1,"%s.ps",extname);
01879 file=fopen(f1,"w");
01880 pscount++;
01881
01882 fprintf(file,"%s",head1);
01883 #ifdef _GENERAL_H
01884 INFO("writeps -> "<<f1);
01885 INFO("write to file");
01886 #else
01887 fprintf(stdout,"writeps -> %s\nwrite to file\n",f1);
01888 #endif
01889 fprintf(file,"%s %d %d %d %d\n",head2,0,0,width,height);
01890 fprintf(file,"%s",head3);
01891
01892 if (sort)
01893 {
01894 for(i=0;i<nL+nP;i++)
01895 {
01896 int n=Z_ind[i].index;
01897 if(n<nL) Draw3DLinetoPS(file,Lines[n]);
01898 else Draw3DPixeltoPS(file,Points[n-nL]);
01899 }
01900 }
01901 else
01902 {
01903 for(i=0;i<nL;i++)
01904 {
01905 Draw3DLinetoPS(file,Lines[i]);
01906 }
01907 for(i=0;i<nP;i++)
01908 {
01909 Draw3DPixeltoPS(file,Points[i]);
01910 }
01911 }
01912
01913 fprintf(file,"%s",tail);
01914 fclose(file);
01915 }
01916
01917 void YWindow::help()
01918 {
01919
01920 }
01921
01922 void YWindow::printWinSpec()
01923 {
01924 char tmp[1000];
01925 sprintf(tmp,"YWindow: Window Specification\n"
01926 "width=%d\theight=%d\n"
01927 "X0=%d\tY0=%d\n"
01928 "Scale=%f\tD=%f\n"
01929 "rotation matrix=[%10f %10f %10f\n"
01930 " %10f %10f %10f\n"
01931 " %10f %10f %10f]\n\n"
01932 ,width,height,X0,Y0,Scale,D
01933 ,A11,A12,A13,A21,A22,A23,A31,A32,A33
01934 );
01935 #ifdef _GENERAL_H
01936 INFO(tmp);
01937 #else
01938 fprintf(stdout,"%s\n",tmp);
01939 #endif
01940 }
01941
01942 void YWindow::setWinSpec(int x0,int y0,double s,double d,double a[3][3])
01943 {
01944 X0=x0;Y0=y0;Scale=s;D=d;
01945 A11=a[0][0];A12=a[0][1];A13=a[0][2];
01946 A21=a[1][0];A22=a[1][1];A23=a[1][2];
01947 A31=a[2][0];A32=a[2][1];A33=a[2][2];
01948 }
01949
01950
01951
01952
01953
01954
01955
01956
01957 void YWindow::update()
01958 {
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969 Lock();
01970
01971
01972 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01973
01974 paint();
01975
01976 glutSwapBuffers();
01977
01978 Unlock();
01979 }
01980
01981
01982 void YWindow::drawBoxFrame()
01983 {
01984
01985 }
01986
01987
01988
01989 void YWindow::applyRotate()
01990 {
01991 double d1,d2,d3;
01992 d1=B11*A11+B12*A21+B13*A31;
01993 d2=B21*A11+B22*A21+B23*A31;
01994 d3=B31*A11+B32*A21+B33*A31;
01995 A11=d1; A21=d2; A31=d3;
01996 d1=B11*A12+B12*A22+B13*A32;
01997 d2=B21*A12+B22*A22+B23*A32;
01998 d3=B31*A12+B32*A22+B33*A32;
01999 A12=d1; A22=d2; A32=d3;
02000 d1=B11*A13+B12*A23+B13*A33;
02001 d2=B21*A13+B22*A23+B23*A33;
02002 d3=B31*A13+B32*A23+B33*A33;
02003 A13=d1; A23=d2; A33=d3;
02004 dirty=true;
02005 }
02006
02007 void YWindow::horizontalRot(double arc)
02008 {
02009 double d1,d3;
02010 double c, s;
02011 c=cos(arc);
02012 s=sin(arc);
02013 d1=c*A11+s*A31;
02014 d3=-s*A11+c*A31;
02015 A11=d1;A31=d3;
02016 d1=c*A12+s*A32;
02017 d3=-s*A12+c*A32;
02018 A12=d1;A32=d3;
02019 d1=c*A13+s*A33;
02020 d3=-s*A13+c*A33;
02021 A13=d1;A33=d3;
02022 dirty=true;
02023 }
02024
02025 void YWindow::verticalRot(double arc)
02026 {
02027 double d2,d3;
02028 double c,s;
02029 s=sin(arc);
02030 c=cos(arc);
02031 d2=c*A21+s*A31;
02032 d3=-s*A21+c*A31;
02033 A21=d2;A31=d3;
02034 d2=c*A22+s*A32;
02035 d3=-s*A22+c*A32;
02036 A22=d2;A32=d3;
02037 d2=c*A23+s*A33;
02038 d3=-s*A23+c*A33;
02039 A23=d2;A33=d3;
02040 dirty=true;
02041 }
02042
02043 void YWindow::spinRot(double arc)
02044 {
02045 double d1,d2;
02046 double c,s;
02047 s=sin(arc);
02048 c=cos(arc);
02049 d1=c*A11+s*A21;
02050 d2=-s*A11+c*A21;
02051 A11=d1;A21=d2;
02052 d1=c*A12+s*A22;
02053 d2=-s*A12+c*A22;
02054 A12=d1;A22=d2;
02055 d1=c*A13+s*A23;
02056 d2=-s*A13+c*A23;
02057 A13=d1;A23=d2;
02058 dirty=true;
02059 }
02060
02061 void YWindow::zoom(double z)
02062 {
02063
02064 Scale*=z;
02065
02066 }
02067
02068 void YWindow::scaleTo(XEvent ev)
02069 {
02070 Scale*=exp((ev.xmotion.x-Xp+ev.xmotion.y-Yp)*0.001);
02071 if(Scale<5e-2) Scale=5e-2;
02072 if(Scale>1e2) Scale=1e2;
02073
02074 dirty=true;
02075 Xp=ev.xmotion.x;
02076 Yp=ev.xmotion.y;
02077 }
02078
02079 void YWindow::translateTo(XEvent ev)
02080 {
02081 X0+=ev.xmotion.x-Xp;Y0+=ev.xmotion.y-Yp;
02082
02083 dirty=true;
02084 Xp=ev.xmotion.x;
02085 Yp=ev.xmotion.y;
02086 }
02087
02088 void YWindow::pbcshiftTo(XEvent ev, int dir)
02089 {
02090 pbcshift[dir]+=(0.0+ev.xmotion.x-Xp+ev.xmotion.y-Yp)/(2.0*B*Scale);
02091
02092 dirty=true;
02093 Xp=ev.xmotion.x;
02094 Yp=ev.xmotion.y;
02095 }
02096
02097 void YWindow::pbcglideTo(XEvent ev)
02098 {
02099 pbcglide((ev.xmotion.x-Xp)/(2.0*B),(ev.xmotion.y-Yp)/(2.0*B));
02100
02101 dirty=true;
02102 Xp=ev.xmotion.x;
02103 Yp=ev.xmotion.y;
02104 }
02105
02106 void YWindow::pbcglide(double dx, double dy)
02107 {
02108 double Ainv11,Ainv12,Ainv13,Ainv21,Ainv22,Ainv23,Ainv31,Ainv32,Ainv33;
02109
02110 Ainv11=A22*A33-A23*A32;
02111 Ainv22=A33*A11-A31*A13;
02112 Ainv33=A11*A22-A12*A21;
02113 Ainv12=A23*A31-A21*A33;
02114 Ainv23=A31*A12-A32*A11;
02115 Ainv31=A12*A23-A13*A22;
02116 Ainv13=A21*A32-A31*A22;
02117 Ainv21=A32*A13-A12*A33;
02118 Ainv32=A13*A21-A23*A11;
02119
02120 pbcshift[0]+=Ainv11*dx+Ainv12*dy;
02121 pbcshift[1]+=Ainv21*dx+Ainv22*dy;
02122 pbcshift[2]+=Ainv31*dx+Ainv32*dy;
02123 }
02124
02125 void YWindow::projectTo(XEvent ev)
02126 {
02127 D*=exp(-(ev.xmotion.x-Xp+ev.xmotion.y-Yp)*0.001);
02128 if(D<0.2) D=0.2;
02129 if(D>1e2) D=1e2;
02130
02131 dirty=true;
02132 Xp=ev.xmotion.x;
02133 Yp=ev.xmotion.y;
02134 }
02135
02136 void YWindow::rotateTo(XEvent ev)
02137 {
02138
02139 double a1,a2,a3,b1,b2,b3,c1,c2,c3,d1,d2,d3,e1,e2,e3;
02140 double r,rp,xx,yy,xp,yp;
02141 #define _toler 1.0e-6
02142 xx=((double)ev.xmotion.x-width/2-X0)/R;
02143 yy=-((double)ev.xmotion.y-height/2-Y0)/R;
02144 xp=((double)Xp-width/2-X0)/R;
02145 yp=-((double)Yp-height/2-Y0)/R;
02146
02147 if((xp-xx)*(xp-xx)+(yp-yy)*(yp-yy)<_toler) return;
02148
02149
02150 rp=sqrt(xp*xp+yp*yp);
02151 r=sqrt(xx*xx+yy*yy);
02152 if(r>=1 || rp>=1)
02153 {
02154 d1=xp/rp;
02155 e1=yp/rp;
02156 d2=xx/r;
02157 e2=yy/r;
02158
02159 d3=cos((r-rp)*M_PI);
02160 e3=sin((r-rp)*M_PI);
02161
02162 B11=d3*d1*d2+e1*e2;
02163 B12=d3*e1*d2-d1*e2;
02164 B13=e3*d2;
02165 B21=d3*d1*e2-e1*d2;
02166 B22=d3*e1*e2+d1*d2;
02167 B23=e3*e2;
02168 B31=-e3*d1;
02169 B32=-e3*e1;
02170 B33=d3;
02171 }
02172 else
02173 {
02174 a1=xp;a2=yp;a3=sqrt(1-a1*a1-a2*a2);
02175 b1=xx;b2=yy;b3=sqrt(1-b1*b1-b2*b2);
02176 c1=a2*b3-a3*b2;
02177 c2=a3*b1-a1*b3;
02178 c3=a1*b2-a2*b1;
02179 r=sqrt(c1*c1+c2*c2+c3*c3);
02180 c1/=r;c2/=r;c3/=r;
02181
02182 d1=a2*c3-a3*c2;
02183 d2=a3*c1-a1*c3;
02184 d3=a1*c2-a2*c1;
02185 e1=b2*c3-b3*c2;
02186 e2=b3*c1-b1*c3;
02187 e3=b1*c2-b2*c1;
02188
02189 B11=b1*a1+e1*d1+c1*c1;
02190 B12=b1*a2+e1*d2+c1*c2;
02191 B13=b1*a3+e1*d3+c1*c3;
02192 B21=b2*a1+e2*d1+c2*c1;
02193 B22=b2*a2+e2*d2+c2*c2;
02194 B23=b2*a3+e2*d3+c2*c3;
02195 B31=b3*a1+e3*d1+c3*c1;
02196 B32=b3*a2+e3*d2+c3*c2;
02197 B33=b3*a3+e3*d3+c3*c3;
02198
02199 }
02200
02201
02202
02203
02204 Xp=ev.xmotion.x;
02205 Yp=ev.xmotion.y;
02206
02207 applyRotate();
02208 }
02209
02210 void YWindow::Evolve()
02211 {
02212 if(!alive) return;
02213
02214 if(enableRot) applyRotate();
02215 if(dirty)
02216 {
02217 dirty=false;
02218 update();
02219 }
02220 }
02221
02222
02223
02224 #ifdef _TEST
02225
02226 int main(int argc, char *argv[])
02227 {
02228 int i, j, k;
02229 int ni=6,nj=6,nk=6;
02230 double x,y,z,x1,y1,z1,r,br,dx,dy,dz,dr;
02231 unsigned c, attr;
02232 char s[100];
02233 YWindow *win;
02234
02235 win=new YWindow(400,400,"Test Window Display",true);
02236
02237 #define yw (*win)
02238
02239 yw.Lock();
02240 yw.Clear();
02241 ni=nj=nk=6;
02242
02243 yw.bgcolor=yw.AllocShortRGBColor(100,100,100);
02244 for(i=0;i<ni;i++)for(j=0;j<nj;j++)for(k=0;k<nk;k++)
02245 {
02246 sprintf(s,"Ball:%d,%d,%d",i,j,k);
02247 attr=1;
02248 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;
02249 c=yw.AllocShortRGBColor(i*0x33, j*0x33, k*0x33);
02250 yw.DrawPoint(x,y,z,r,c,s,attr);
02251 if(i>0)
02252 {
02253 x1=x-2./ni;y1=y;z1=z;
02254 dx=x1-x;dy=y1-y;dz=z1-z;dr=sqrt(dx*dx+dy*dy+dz*dz);dx/=dr;dy/=dr;dz/=dr;
02255 yw.DrawLine(x+dx*r,y+dy*r,z+dz*r,x1-dx*r,y1-dy*r,z1-dz*r,c,br,1);
02256
02257 }
02258 if(j>0)
02259 {
02260 x1=x;y1=y-2./nj;z1=z;
02261 dx=x1-x;dy=y1-y;dz=z1-z;dr=sqrt(dx*dx+dy*dy+dz*dz);dx/=dr;dy/=dr;dz/=dr;
02262 yw.DrawLine(x+dx*r,y+dy*r,z+dz*r,x1-dx*r,y1-dy*r,z1-dz*r,c,br,1);
02263
02264 }
02265 if(k>0)
02266 {
02267 x1=x;y1=y;z1=z-2./nk;
02268 dx=x1-x;dy=y1-y;dz=z1-z;dr=sqrt(dx*dx+dy*dy+dz*dz);dx/=dr;dy/=dr;dz/=dr;
02269 yw.DrawLine(x+dx*r,y+dy*r,z+dz*r,x1-dx*r,y1-dy*r,z1-dz*r,c,br,1);
02270
02271 }
02272 }
02273
02274 yw.Unlock();
02275 yw.Refresh();
02276 #ifdef NO_THREAD
02277 yw.Routine();
02278 #else
02279 yw.Run();
02280 i=99;
02281 #ifndef NO_GENERAL
02282 _IO << "I can live for <<"<<i<<" seconds.\n" ;
02283 #else
02284 printf("I can live for %d seconds.\n",i);
02285 #endif
02286 for(j=0;j<i;j++)
02287 {
02288 sleep(1);
02289 #ifndef NO_GENERAL
02290 _IO << i-j << ' ';
02291 #else
02292 printf("%d \n",i-j);
02293 #endif
02294 }
02295 #ifndef NO_GENERAL
02296 _IO << "Bye.\n";
02297 #else
02298 printf("Bye.\n");
02299 #endif
02300 #endif
02301 return 0;
02302 }
02303
02304 #endif //_TEST