00001
00002 #include "xstarplot.h"
00003
00004 static float linespacing;
00005
00006
00007
00008 void initialize_graphics(float r_factor,
00009 bool b_flag,
00010 unsigned long& win,
00011 unsigned long& instr,
00012 unsigned long& colwin,
00013 unsigned long* c_index,
00014 unsigned long* c_energy,
00015 int& win_size,
00016 int& xorigin, int& yorigin)
00017 {
00018
00019
00020
00021
00022
00023 if (r_factor >= 1.0) {
00024 set_default_font("9x15");
00025 linespacing = 1.2;
00026 } else if (r_factor >= 0.8) {
00027 set_default_font("7x13");
00028 if (r_factor >= 0.9)
00029 linespacing = 1.15;
00030 else
00031 linespacing = 1.1;
00032 } else if (r_factor >= 0.65) {
00033 set_default_font("6x12");
00034 if (r_factor >= 0.725)
00035 linespacing = 1.05;
00036 else
00037 linespacing = 1.0;
00038 } else if (r_factor >= 0.5) {
00039 set_default_font("6x10");
00040 if (r_factor >= 0.575)
00041 linespacing = 1.05;
00042 else
00043 linespacing = 1.0;
00044 } else if (r_factor >= 0.4) {
00045 set_default_font("6x9");
00046 linespacing = 1.0;
00047 } else {
00048 set_default_font("5x8");
00049 linespacing = 1.0;
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 int title = 27;
00065 int bottom = 0;
00066 int edge = 5;
00067
00068 if (r_factor <= 0.75) {
00069 title = 20;
00070 bottom = 20;
00071 }
00072
00073 title = 0;
00074 bottom = 0;
00075
00076
00077
00078 xorigin = 0;
00079 yorigin = 0;
00080 int xsize = _R_(400);
00081 int ysize = _R_(400);
00082 win = lux_openwin(xorigin, yorigin, xsize, ysize);
00083 lux_set_window_name(win, "Starlab");
00084
00085 win_size = xsize;
00086
00087
00088
00089
00090
00091
00092
00093 int disp_width = lux_get_display_width();
00094 int disp_height = lux_get_display_height();
00095
00096
00097
00098 yorigin += ysize + title + bottom + 2*edge;
00099
00100 ysize = _R_(350);
00101 if (r_factor <= 0.6) {
00102 xsize = (int) (xsize * 1.25);
00103 ysize = (int) (ysize * 1.1);
00104 }
00105
00106 if (yorigin+ysize >= disp_height) {
00107 yorigin = 0;
00108 xorigin += xsize + 2*edge;
00109 }
00110
00111 instr = lux_openwin(xorigin, yorigin, xsize, ysize);
00112 lux_set_window_name(instr, "Status & Commands");
00113
00114
00115
00116 yorigin += ysize + title + bottom + 2*edge;
00117
00118 #if 0
00119 if (r_factor <= 1.1 && r_factor > 0.75) {
00120 yorigin += ysize + title + bottom + 2*edge;
00121 } else {
00122 if (r_factor <= 0.6) xsize = (int) (xsize / 1.25);
00123 xorigin += xsize + 2*edge;
00124 yorigin = 0;
00125 }
00126 #endif
00127
00128 if (r_factor <= 0.6) {
00129 xsize = (int) (xsize * 1.25);
00130 ysize = (int) (ysize * 1.1);
00131 } else {
00132 ysize = _R_(135);
00133 }
00134
00135 if (yorigin+ysize >= disp_height) {
00136 yorigin = 0;
00137 xorigin += xsize + 2*edge;
00138 }
00139
00140 colwin = lux_openwin(xorigin, yorigin, xsize, ysize);
00141 lux_set_window_name(colwin, "Color Scheme");
00142
00143 init_colors(win, c_energy, c_index, b_flag);
00144
00145 lux_set_noupdate(win);
00146 lux_set_bgcolor(win,c_energy[background_color]);
00147 lux_set_window_bgcolor(win,c_energy[background_color]);
00148 lux_set_color(win,c_energy[default_color]);
00149
00150 lux_set_noupdate(colwin);
00151 lux_set_bgcolor(colwin,c_energy[background_color]);
00152 lux_set_window_bgcolor(colwin,c_energy[background_color]);
00153 lux_set_color(colwin,c_energy[default_color]);
00154
00155 lux_set_noupdate(instr);
00156 lux_set_bgcolor(instr,c_energy[background_color]);
00157 lux_set_window_bgcolor(instr,c_energy[background_color]);
00158 lux_set_color(instr,c_energy[default_color]);
00159
00160 lux_setup_region(win, 1.0, 1.0, 8.0, 8.0);
00161
00162
00163
00164 if (r_factor <= 1.1 && r_factor > 0.75) {
00165 int edge = 3;
00166 xorigin += xsize + edge;
00167 yorigin = 0;
00168 } else
00169 yorigin += ysize + title + bottom;
00170 }
00171
00172
00173
00174 void project3d(float x, float y, float z, float& X, float& Y,
00175 float ct, float st, float cp, float sp,
00176 float vx, float vy, float vz, float& dv2)
00177 {
00178 float xp, yp, zp, xf, yf, zf;
00179
00180
00181 xp = ct*x + st*y;
00182 yp = -st*x + ct*y;
00183 zp = z;
00184
00185
00186 xf = cp*xp + sp*zp;
00187 yf = yp;
00188 zf = -sp*xp + cp*zp;
00189
00190
00191 X = yf; Y=zf;
00192 dv2 = (vx-xf)*(vx-xf) + (vy-yf)*(vy-yf) + (vz-zf)*(vz-zf);
00193 }
00194
00195 void project3d(float x, float y, float z, float& X, float& Y,
00196 float ct, float st, float cp, float sp)
00197 {
00198 float xp, yp, zp, xf, yf, zf;
00199
00200
00201 xp = ct*x + st*y;
00202 yp = -st*x + ct*y;
00203 zp = z;
00204
00205
00206 xf = cp*xp + sp*zp;
00207 yf = yp;
00208 zf = -sp*xp + cp*zp;
00209
00210
00211 X = yf; Y=zf;
00212 }
00213
00214 void draw3d_axis(unsigned long win, float lmax,
00215 float ct, float st, float cp, float sp)
00216 {
00217 float X[8], Y[8], Z[8], XP[8], YP[8], D[8], X0, Y0, Z0, dmax = 0.0;
00218 float xp,yp;
00219 int i, i0;
00220 static int od1[] = {1,2,4,3,5,6,8,7,1,2,4,3};
00221 static int od2[] = {2,4,3,1,6,8,7,5,5,6,8,7};
00222
00223 X0 = lmax; Y0 = 0.0; Z0 = 0.0;
00224 for (i=0;i<8;i++) {
00225 X[i] = lmax*((i&0x0001)?-1:1);
00226 Y[i] = lmax*((i&0x0002)?-1:1);
00227 Z[i] = lmax*((i&0x0004)?-1:1);
00228 project3d(X[i], Y[i], Z[i], XP[i], YP[i],
00229 ct, st, cp, sp,
00230 X0, Y0, Z0, D[i]);
00231 if (D[i] > dmax) {dmax = D[i]; i0 = i;}
00232 }
00233
00234 for (i=0;i<12;i++) {
00235 if (od1[i] == i0+1 || od2[i] == i0+1) lux_set_linestyle(win,1);
00236 else lux_set_linestyle(win,0);
00237 lux_draw_linef(win,XP[od1[i]-1],YP[od1[i]-1],XP[od2[i]-1],YP[od2[i]-1]);
00238 }
00239 lux_set_linestyle(win,0);
00240
00241
00242 project3d(0.0,-lmax*1.1,-lmax*1.1, xp, yp, ct,st,cp,sp);
00243 lux_draw_string(win, xp, yp, -0.5, "x", 0);
00244 project3d(-lmax*1.1,0.0,-lmax*1.1, xp, yp, ct,st,cp,sp);
00245 lux_draw_string(win, xp, yp, -0.5, "y", 0);
00246 project3d(-lmax*1.1,-lmax*1.1,0.0, xp, yp, ct,st,cp,sp);
00247 lux_draw_string(win, xp, yp, -0.5, "z", 0);
00248 }
00249
00250 void draw2d_axis(unsigned long win, float xmin, float xmax,
00251 float ymin, float ymax, int k)
00252 {
00253 lux_draw_axis(win);
00254
00255
00256
00257 switch (k) {
00258 case 3: lux_draw_string(win, (xmin+xmax)/2, ymin, -2.2, "x", 0); break;
00259 case 1: lux_draw_string(win, (xmin+xmax)/2, ymin, -2.2, "y", 0); break;
00260 case 2: lux_draw_string(win, (xmin+xmax)/2, ymin, -2.2, "z", 0); break;
00261 }
00262
00263
00264
00265 switch (k) {
00266 case 3: lux_draw_vstring(win, xmin, (ymin+ymax)/2,
00267 1.2, " y ", 0); break;
00268 case 1: lux_draw_vstring(win, xmin, (ymin+ymax)/2,
00269 1.2, " z ", 0); break;
00270 case 2: lux_draw_vstring(win, xmin, (ymin+ymax)/2,
00271 1.2, " x ", 0); break;
00272 }
00273 }
00274
00275
00276 void update_with_delay(unsigned long win, float t)
00277 {
00278 lux_update_fg(win);
00279 if (t > 0.0) lux_pause((int)(t*1000.0));
00280 }
00281
00282
00283
00284 void show_instructions(unsigned long win, float r, char* buffer,
00285 int update)
00286 {
00287 float statusx, statusy;
00288 char s[255];
00289 int ptr = 0, len, line = 0;
00290
00291 lux_clear_window(win);
00292 lux_reconvert_rcoord(win,0,0,&statusx, &statusy);
00293 istrstream ins(buffer,strlen(buffer));
00294 while(ins.get(s,255,'\n')) {
00295 lux_set_nobuffer();
00296 lux_draw_image_string(win, statusx, statusy,
00297 -(line+1)*linespacing, s, -1);
00298 ins.get(s[0]);
00299 line = line+1;
00300 }
00301 if (update) lux_update_fg(win);
00302 }
00303
00304
00305 void show_instructions(unsigned long win, float r, char* buffer,
00306 int line, int update)
00307 {
00308 float statusx, statusy;
00309 char s[255];
00310 int ptr = 0, len;
00311
00312 lux_reconvert_rcoord(win,0,0,&statusx, &statusy);
00313 istrstream ins(buffer,strlen(buffer));
00314 while(ins.get(s,255,'\n')) {
00315 lux_set_nobuffer();
00316 lux_draw_string(win, statusx, statusy,
00317 -(line+1)*linespacing, s, -1);
00318 ins.get(s[0]);
00319 line = line+1;
00320 }
00321 if (update) lux_update_fg(win);
00322 }
00323
00324 #include <sys/time.h>
00325 #include <unistd.h>
00326
00327 #define INSTR_TIME_LIMIT 2.0
00328
00329 local double current_time()
00330 {
00331 struct timeval tv;
00332 struct timezone tz;
00333
00334 gettimeofday(&tv, &tz);
00335 return tv.tv_sec + 1.e-6*tv.tv_usec;
00336 }
00337
00338
00339 local void create_instr_string(char *instr_string, int dim, bool eod,
00340 int nodes, int links, int multiples,
00341 int unperturbed, int root)
00342 {
00343 char tmp[64];
00344
00345 sprintf(tmp, "Running in %d-D mode", dim);
00346 strcpy(instr_string, tmp);
00347
00348 if (eod) strcat(instr_string, " (at end of data)");
00349 strcat(instr_string, "\n");
00350 strcat(instr_string, " d: dialog, R: rotate, i: idle, q: quit\n");
00351 strcat(instr_string, " p/P decrease/increase point size\n");
00352 strcat(instr_string, " t add/remove tracking\n");
00353
00354 strcat(instr_string, " n/l/m/u/r show nodes/links/multiples\n");
00355 strcat(instr_string, " /unperturbed/root\n");
00356 sprintf(tmp, " (%d/%d/%d/%d/%d)\n",
00357 nodes, links, multiples, unperturbed, root);
00358 strcat(instr_string, tmp);
00359
00360 sprintf(tmp, " %d enter %d-D mode\n", 5-dim, 5-dim);
00361 strcat(instr_string, tmp);
00362
00363 strcat(instr_string, " x/y/k ");
00364 if (dim == 3) strcat(instr_string, "2-D and ");
00365 strcat(instr_string, "change viewing axis\n");
00366
00367 strcat(instr_string, " e toggle energy color\n");
00368 strcat(instr_string, " < > ^ V rotate left right up down\n");
00369 strcat(instr_string, " +/- change delay time (0: fastest)\n");
00370 strcat(instr_string, " / * or \\ change or reverse frame dt\n");
00371 strcat(instr_string, " j (J) jump to time (and set dt)\n");
00372 strcat(instr_string, " z/Z zoom in or out \n");
00373 strcat(instr_string, " arrow/page shift in x, y, z\n");
00374 strcat(instr_string, " h/home restore origin to (0,0,0)\n");
00375 strcat(instr_string, " a resize to enclose all stars\n");
00376 strcat(instr_string, " f/b/c step forward/backward/continue\n");
00377 }
00378
00379 void show_main_instructions(unsigned long instr, float r, int d, int u,
00380 bool eod,
00381 int nodes, int links, int multiples,
00382 int unperturbed, int root)
00383 {
00384
00385
00386
00387
00388 static double prev_time = 0.0;
00389
00390
00391
00392 real time = current_time();
00393 if (time - prev_time < INSTR_TIME_LIMIT) return;
00394 prev_time = time;
00395
00396 static char instr_string[1024];
00397 create_instr_string(instr_string, 2+d, eod,
00398 nodes, links, multiples, unperturbed, root);
00399
00400 show_instructions(instr, r, instr_string, u);
00401 }
00402
00403 local void format_and_show_instructions(unsigned long co, float r,
00404 unsigned long *c_i, int index, int tab,
00405 char* cstring, int line, int u)
00406 {
00407 if (index > 0) lux_set_color(co, c_i[index]);
00408
00409 static char temp[80], temp1[80];
00410 sprintf(temp, " ");
00411 for (int i = 0; i < tab; i++) strcat(temp, TAB);
00412 sprintf(temp1, "%d - %s", index, cstring);
00413 strcat(temp, temp1);
00414
00415 show_instructions(co, r, temp, line, u);
00416 }
00417
00418 void show_color_scheme(unsigned long co, unsigned long *c_e, unsigned long *c_i,
00419 float r, char ce, bool b_flag, int u)
00420 {
00421
00422
00423
00424
00425
00426
00427 static double prev_time = 0.0;
00428
00429
00430
00431 real time = current_time();
00432 if (time - prev_time < INSTR_TIME_LIMIT) return;
00433 prev_time = time;
00434
00435 lux_clear_window(co);
00436
00437 if (ce) {
00438
00439 static char tmp[80];
00440
00441 strcpy(tmp, "Color by energy:\n");
00442 show_instructions(co, r, tmp, 0, u);
00443 lux_set_color(co, c_e[default_color]);
00444
00445 if (b_flag)
00446 strcpy(tmp, " White = default (bound to cluster)\n");
00447 else
00448 strcpy(tmp, " Black = default (bound to cluster)\n");
00449 show_instructions(co, r, tmp, 1, u);
00450
00451 lux_set_color(co, c_e[bound_single]);
00452 strcpy(tmp, " Blue = bound to nearest neighbor\n");
00453 show_instructions(co, r, tmp, 2, u);
00454
00455 lux_set_color(co, c_e[bound_binary]);
00456 strcpy(tmp, " Green = bound binary\n");
00457 show_instructions(co, r, tmp, 3, u);
00458
00459 lux_set_color(co, c_e[unbound_single]);
00460 strcpy(tmp, " Red = unbound single star\n");
00461 show_instructions(co, r, tmp, 4, u);
00462
00463 lux_set_color(co, c_e[unbound_binary]);
00464 strcpy(tmp, " Gold = unbound binary\n");
00465 show_instructions(co, r, tmp, 5, u);
00466
00467 lux_set_color(co, c_e[default_color]);
00468
00469 } else {
00470
00471 static char tmp[80];
00472
00473 strcpy(tmp, "Color by index:\n");
00474 show_instructions(co, r, tmp, 0, u);
00475 lux_set_color(co, c_i[1]);
00476
00477 if (b_flag) {
00478 format_and_show_instructions(co, r, c_i, 1, 0, "white", 1, u);
00479 format_and_show_instructions(co, r, c_i, 2, 1, RV_COLOR2, 1, u);
00480 format_and_show_instructions(co, r, c_i, 3, 2, RV_COLOR3, 1, u);
00481 format_and_show_instructions(co, r, c_i, 4, 0, RV_COLOR4, 2, u);
00482 format_and_show_instructions(co, r, c_i, 5, 1, RV_COLOR5, 2, u);
00483 format_and_show_instructions(co, r, c_i, 6, 2, RV_COLOR6, 2, u);
00484 format_and_show_instructions(co, r, c_i, 7, 0, RV_COLOR7, 3, u);
00485 format_and_show_instructions(co, r, c_i, 8, 1, RV_COLOR8, 3, u);
00486 format_and_show_instructions(co, r, c_i, 9, 2, RV_COLOR9, 3, u);
00487 format_and_show_instructions(co, r, c_i, 10, 0, RV_COLORa, 4, u);
00488 format_and_show_instructions(co, r, c_i, 11, 1, RV_COLORb, 4, u);
00489 format_and_show_instructions(co, r, c_i, 12, 2, RV_COLORc, 4, u);
00490 format_and_show_instructions(co, r, c_i, 13, 0, RV_COLORd, 5, u);
00491 format_and_show_instructions(co, r, c_i, 14, 1, RV_COLORe, 5, u);
00492 format_and_show_instructions(co, r, c_i, 15, 2, RV_COLORf, 5, u);
00493 format_and_show_instructions(co, r, c_i, 16, 0, RV_COLORg, 6, u);
00494 } else {
00495 format_and_show_instructions(co, r, c_i, 1, 0, "black", 1, u);
00496 format_and_show_instructions(co, r, c_i, 2, 1, NV_COLOR2, 1, u);
00497 format_and_show_instructions(co, r, c_i, 3, 2, NV_COLOR3, 1, u);
00498 format_and_show_instructions(co, r, c_i, 4, 0, NV_COLOR4, 2, u);
00499 format_and_show_instructions(co, r, c_i, 5, 1, NV_COLOR5, 2, u);
00500 format_and_show_instructions(co, r, c_i, 6, 2, NV_COLOR6, 2, u);
00501 format_and_show_instructions(co, r, c_i, 7, 0, NV_COLOR7, 3, u);
00502 format_and_show_instructions(co, r, c_i, 8, 1, NV_COLOR8, 3, u);
00503 format_and_show_instructions(co, r, c_i, 9, 2, NV_COLOR9, 3, u);
00504 format_and_show_instructions(co, r, c_i, 10, 0, NV_COLORa, 4, u);
00505 format_and_show_instructions(co, r, c_i, 11, 1, NV_COLORb, 4, u);
00506 format_and_show_instructions(co, r, c_i, 12, 2, NV_COLORc, 4, u);
00507 format_and_show_instructions(co, r, c_i, 13, 0, NV_COLORd, 5, u);
00508 format_and_show_instructions(co, r, c_i, 14, 1, NV_COLORe, 5, u);
00509 format_and_show_instructions(co, r, c_i, 15, 2, NV_COLORf, 5, u);
00510 format_and_show_instructions(co, r, c_i, 16, 0, NV_COLORg, 6, u);
00511 }
00512 lux_set_color(co, c_i[default_color]);
00513 }
00514 }
00515
00516 void init_colors(unsigned long win, unsigned long *ce, unsigned long *ci,
00517 bool b_flag)
00518 {
00519
00520
00521
00522
00523 if (b_flag) {
00524
00525
00526
00527 ce[background_color] = ci[background_color]
00528 = lux_rgb_pixel(win, 0.0,0.0,0.0);
00529 ce[default_color] = ci[default_color]
00530 = lux_rgb_pixel(win, 1.0,1.0,1.0);
00531
00532
00533
00534 ce[bound_single] = lux_lookup_color(win, "deepskyblue");
00535 ce[bound_binary] = lux_lookup_color(win, "green");
00536 ce[unbound_single] = lux_lookup_color(win, "red");
00537 ce[unbound_binary] = lux_lookup_color(win, "goldenrod");
00538
00539
00540
00541 ci[2] = lux_lookup_color(win, RV_COLOR2);
00542 ci[3] = lux_lookup_color(win, RV_COLOR3);
00543 ci[4] = lux_lookup_color(win, RV_COLOR4);
00544 ci[5] = lux_lookup_color(win, RV_COLOR5);
00545 ci[6] = lux_lookup_color(win, RV_COLOR6);
00546 ci[7] = lux_lookup_color(win, RV_COLOR7);
00547 ci[8] = lux_lookup_color(win, RV_COLOR8);
00548 ci[9] = lux_lookup_color(win, RV_COLOR9);
00549 ci[10] = lux_lookup_color(win, RV_COLORa);
00550 ci[11] = lux_lookup_color(win, RV_COLORb);
00551 ci[12] = lux_lookup_color(win, RV_COLORc);
00552 ci[13] = lux_lookup_color(win, RV_COLORd);
00553 ci[14] = lux_lookup_color(win, RV_COLORe);
00554 ci[15] = lux_lookup_color(win, RV_COLORf);
00555 ci[16] = lux_lookup_color(win, RV_COLORg);
00556
00557 } else {
00558
00559 ce[background_color] = ci[background_color]
00560 = lux_rgb_pixel(win, 1.0,1.0,1.0);
00561 ce[default_color] = ci[default_color]
00562 = lux_rgb_pixel(win, 0.0,0.0,0.0);
00563
00564
00565
00566 ce[bound_single] = lux_lookup_color(win, "blue");
00567 ce[bound_binary] = lux_lookup_color(win, "limegreen");
00568 ce[unbound_single] = lux_lookup_color(win, "red");
00569 ce[unbound_binary] = lux_lookup_color(win, "goldenrod");
00570
00571
00572
00573 ci[2] = lux_lookup_color(win, NV_COLOR2);
00574 ci[3] = lux_lookup_color(win, NV_COLOR3);
00575 ci[4] = lux_lookup_color(win, NV_COLOR4);
00576 ci[5] = lux_lookup_color(win, NV_COLOR5);
00577 ci[6] = lux_lookup_color(win, NV_COLOR6);
00578 ci[7] = lux_lookup_color(win, NV_COLOR7);
00579 ci[8] = lux_lookup_color(win, NV_COLOR8);
00580 ci[9] = lux_lookup_color(win, NV_COLOR9);
00581 ci[10] = lux_lookup_color(win, NV_COLORa);
00582 ci[11] = lux_lookup_color(win, NV_COLORb);
00583 ci[12] = lux_lookup_color(win, NV_COLORc);
00584 ci[13] = lux_lookup_color(win, NV_COLORd);
00585 ci[14] = lux_lookup_color(win, NV_COLORe);
00586 ci[15] = lux_lookup_color(win, NV_COLORf);
00587 ci[16] = lux_lookup_color(win, NV_COLORg);
00588
00589 }
00590
00591
00592
00593 for (int ke = bound_single; ke <= unbound_binary; ke++)
00594 if (ce[ke] == ce[background_color]) ce[ke] = ce[default_color];
00595 for (int ki = 2; ki < 16; ki++)
00596 if (ci[ki] == ci[background_color]) ci[ki] = ci[default_color];
00597 }
00598
00599 void set_limits(float* origin, float lmax3d,
00600 int kx, float& xmin, float& xmax,
00601 int ky, float& ymin, float& ymax)
00602 {
00603 xmin = origin[kx] - lmax3d;
00604 xmax = origin[kx] + lmax3d;
00605 ymin = origin[ky] - lmax3d;
00606 ymax = origin[ky] + lmax3d;
00607 }
00608
00609
00610 float interp_to_x(float r, float s, float rr, float ss, float x)
00611 {
00612 return s + (ss - s) * (x - r) / (rr - r);
00613 }
00614
00615
00616 float interp_to_y(float r, float s, float rr, float ss, float y)
00617 {
00618 return r + (rr - r) * (y - s) / (ss - s);
00619 }