1 /* NIGHTFALL OpenGL Interface */
2 /* Copyright (C) 2001 Rainer Wichmann & Markus Kuster */
3 /* */
4 /* This program is free software; you can redistribute it */
5 /* and/or modify */
6 /* it under the terms of the GNU General Public License as */
7 /* published by */
8 /* the Free Software Foundation; either version 2 of the License, or */
9 /* (at your option) any later version. */
10 /*
11 */
12 /* This program is distributed in the hope that it will be useful, */
13 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
14 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
15 /* GNU General Public License for more details. */
16 /* */
17 /* You should have received a copy of the GNU General Public License */
18 /* along with this program; if not, write to the Free Software */
19 /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 /* ANSI C forbids an empty source file, so put this outside */
22 /* do nothing here if we don't have OpenGL */
23
24 #include <math.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include "Light.h"
29
30 #ifdef _WITH_OPENGL
31 #include "LightGLPrefs.h"
32
33
34 /******************************************************************
35 @package nightfall
36 @author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
37 @version 1.3
38 @short The color wedge code
39 @param (int) Comp the component
40 @return (void)
41 @heading Open GL Animation
42 *******************************************************************/
GLDisplayWedge(int Comp)43 void GLDisplayWedge( int Comp )
44 {
45 float maxval = texture_maxval[Comp];
46 float minval = texture_minval[Comp];
47 char label[128];
48
49 /* plot borders
50 */
51 float xmin = -0.5;
52 float lmin = -0.9;
53 float xmax = 0.5;
54 float ymin = -0.5;
55 float ymax = 0.5;
56
57 double ScaleMass; /* units conversion */
58 double G_SI = 6.6726e-11; /* gravitational constant */
59 char texwhat[16];
60
61 struct GLColorSystem NTSC = {0.64, 0.33, 0.29, 0.60, 0.15, 0.06, CWP};
62 struct GLColorSystem *cs;
63 double x, y, z, R, G, B, max;
64
65 /* R.W. 23.12.2002 set colours to BB colour
66 */
67 cs = &NTSC;
68 GLBBtoxyz(Binary[Comp].Temperature, &x, &y, &z);
69 GLxyztoRGB(cs, x, y, z, &R, &G, &B);
70 max = (R > G) ? R : G;
71 max = (B > max) ? B : max;
72 R = (1.0 / max) * R;
73 G = (1.0 / max) * G;
74 B = (1.0 / max) * B;
75
76 if (Flags.textype == TEMP)
77 {
78 strcpy(texwhat, "Kelvin");
79 }
80 else if (Flags.textype == GRAV)
81 {
82 ScaleMass = Binary[Primary].Mq / ( 1.0 + Binary[Primary].Mq);
83 minval = minval * Orbit.TrueMass * (1.0 - ScaleMass)
84 * G_SI
85 / (Orbit.TrueDistance * Orbit.TrueDistance);
86 maxval = maxval * Orbit.TrueMass * (1.0 - ScaleMass)
87 * G_SI
88 / (Orbit.TrueDistance * Orbit.TrueDistance);
89 strcpy(texwhat, "m kg/s^2");
90 }
91 else if (Flags.textype == FLUX)
92 {
93 minval = (1.0 / maxval) * minval;
94 maxval = 1.0;
95 strcpy(texwhat, "relative flux");
96 }
97 else if (Flags.textype == VELOCITY)
98 {
99 strcpy(texwhat, "m/s");
100 }
101 else
102 {
103 strcpy(texwhat, "?");
104 }
105
106
107 if (gtk_gl_area_make_current(GTK_GL_AREA(glArea)))
108 {
109 /* disable lighting, we don't want ligthing with */
110 /* the axes */
111 glDisable(GL_LIGHTING);
112
113 glMatrixMode(GL_PROJECTION);
114 glLoadIdentity();
115 glOrtho(-1, 1, -1, 1, -1, 1);
116 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
117
118 /* draw border for plot */
119 glBegin(GL_QUADS);
120 glColor3f(0.0, 0.0, 0.0);
121 glVertex3f(xmin, ymin, 0.0);
122 glVertex3f(xmin, ymax, 0.0);
123 glColor3f(R, G, B);
124 glVertex3f(xmax, ymax, 0.0);
125 glVertex3f(xmax, ymin, 0.0);
126 glEnd();
127 glPopMatrix();
128
129 #if 0
130 /* draw tickmarks */
131 glBegin(GL_LINES);
132 glVertex2f(-0.5, bot_xtick);
133 glVertex2f(-0.5, top_xtick);
134 glVertex2f( 0.0, bot_xtick);
135 glVertex2f( 0.0, top_xtick);
136 glVertex2f( 0.5, bot_xtick);
137 glVertex2f( 0.5, top_xtick);
138 glVertex2f( 1.0, bot_xtick);
139 glVertex2f( 1.0, top_xtick);
140 glEnd();
141 #endif
142
143 /* select font */
144 GLSetFont(HELVETICA, 12);
145
146 glDisable(GL_LIGHTING);
147
148 glPushMatrix();
149
150 /* print labels */
151 glColor3f(1.0, 1.0, 1.0);
152 snprintf(label, 127, "%c: %10.4g",
153 (Comp == Primary) ? 'P' :
154 (Comp == Secondary) ? 'S' : 'D', minval);
155 GLDrawStr(lmin, -0.2, 0.0, label);
156 snprintf(label, 127, "%10.4g (%s)", maxval, texwhat);
157 GLDrawStr(xmax, -0.2, 0.0, label);
158
159 #if 0
160 /* print tick marks */
161 GLDrawStr(-0.545,bot_xtick-0.1*length_y,0.0,"0.5");
162 GLDrawStr(-0.05,bot_xtick-0.1*length_y,0.0,"0.0");
163 GLDrawStr( 0.455,bot_xtick-0.1*length_y,0.0,"0.5");
164 GLDrawStr( 0.96,bot_xtick-0.1*length_y,0.0,"1.0");
165
166 /* print title string */
167 glColor3f(1.0, 1.0, 1.0);
168 GLDrawStr(coord.titlepos,yaxis.max_value+0.15*length_y,0.0,coord.title);
169 #endif
170 glPopMatrix();
171
172 /* switch on lighing */
173 glEnable(GL_LIGHTING);
174
175 /* set line width to 1 */
176 glLineWidth(1);
177 }
178 }
179
180
181 /******************************************************************
182 @package nightfall
183 @author Markus Kuster (kuster@astro.uni-tuebingen.de)
184 @version 0.5
185 @short The main 3D window rendering code
186 @param (GtkWidget) *widget discarded
187 @return (void)
188 @heading Open GL Animation
189 *******************************************************************/
GLDisplay3d(GtkWidget * widget)190 void GLDisplay3d( GtkWidget *widget )
191 {
192 float com; /* center of mass */
193
194 GLfloat m[4][4] /* ,h */;
195 OrbitType *OrbPtr = &Orbit; /* pointer to Orbit */
196 DispInfo *DispInfoPtr;
197
198 struct GLColorSystem NTSC = {0.64, 0.33, 0.29, 0.60, 0.15, 0.06, CWP};
199 struct GLColorSystem *cs;
200 double x, y, z, R, G, B, max;
201
202 /* R.W. 23.12.2002 set colours to BB colour
203 */
204 cs = &NTSC;
205 GLBBtoxyz(Binary[Primary].Temperature, &x, &y, &z);
206 GLxyztoRGB(cs, x, y, z, &R, &G, &B);
207 max = (R > G) ? R : G;
208 max = (B > max) ? B : max;
209 primary_colour[0] = (1.0 / max) * R;
210 primary_colour[1] = (1.0 / max) * G;
211 primary_colour[2] = (1.0 / max) * B;
212
213 cs = &NTSC;
214 GLBBtoxyz(Binary[Secondary].Temperature, &x, &y, &z);
215 GLxyztoRGB(cs, x, y, z, &R, &G, &B);
216 max = (R > G) ? R : G;
217 max = (B > max) ? B : max;
218 secondary_colour[0] = (1.0 / max) * R;
219 secondary_colour[1] = (1.0 / max) * G;
220 secondary_colour[2] = (1.0 / max) * B;
221
222 #ifdef HAVE_DISK
223 cs = &NTSC;
224 GLBBtoxyz(Binary[Disk].Temperature, &x, &y, &z);
225 GLxyztoRGB(cs, x, y, z, &R, &G, &B);
226 max = (R > G) ? R : G;
227 max = (B > max) ? B : max;
228 disk_colour[0] = (1.0 / max) * R;
229 disk_colour[1] = (1.0 / max) * G;
230 disk_colour[2] = (1.0 / max) * B;
231 #endif
232
233 DispInfoPtr = (DispInfo*)gtk_object_get_data(GTK_OBJECT(glArea), "DispInfo");
234 /* get the dimension of the GTK window */
235
236 /* h= (GLfloat) glArea->allocation.height / (GLfloat) glArea->allocation.width; */
237
238 if (gtk_gl_area_make_current(GTK_GL_AREA(glArea)))
239 {
240 glMatrixMode(GL_PROJECTION);
241 glLoadIdentity();
242
243 glOrtho((-1 - DispInfoPtr->xpos) * DispInfoPtr->zoom,
244 ( 1 - DispInfoPtr->xpos) * DispInfoPtr->zoom,
245 -1 * DispInfoPtr->zoom,1 * DispInfoPtr->zoom,.1,1000.);
246
247 glMatrixMode(GL_MODELVIEW);
248
249 /* the x coordinate of the center of mass */
250 com = (((float)(Binary[Primary].Mq))/( 1.0 + (float)(Binary[Primary].Mq)));
251
252 /* load identity transformation matrix */
253 glLoadIdentity();
254
255 /* set the drawing mode to polygon mode */
256 if (Flags.wireframe == ON) {
257 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
258 } else {
259 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
260 }
261
262 /* set view point position to (Flags.GLdistancex,0,Flags.GLdistancez)*/
263 /* look to point (Flags.GLdistancex,0, 0 )*/
264 /* with head up pointing to ( 0 ,1, 0 )*/
265 gluLookAt(Flags.GLdistancex,0,Flags.GLdistancez,Flags.GLdistancex,0,0,0,1,0);
266
267 build_rotmatrix(m,DispInfoPtr->quat);
268 glMultMatrixf(&m[0][0]);
269
270 /* rotate orbit accoding to the inclination */
271 glRotated((270.0-((OrbPtr->Inclination-PI/2.0)*180.0/PI)),1,0,0);
272
273 /* rotate phase steps */
274 glRotated((OrbPtr->Phase-0.5*PI)*180.0/PI,0,0,1);
275
276 glTranslatef(-(com),0.0,0.0);
277
278 if (Flags.axes == ON) {
279 /* draw x-,y- and z-axes */
280 glPushMatrix();
281 GLDrawAxes(0.4,glArea);
282 glPopMatrix();
283 }
284 if (Flags.labels == ON) {
285 glPushMatrix();
286 GLDrawLabels(glArea);
287 glPopMatrix();
288 }
289
290 /* save transformation matix */
291 glPushMatrix();
292
293 /* set the material options for primary */
294 /* primary emission; should be set according */
295 /* to the primary temperature */
296 glMaterialfv(GL_FRONT, GL_EMISSION, primary_colour);
297 glMaterialfv(GL_FRONT, GL_DIFFUSE, primary_mat_diffuse);
298 glMaterialfv(GL_FRONT, GL_SPECULAR, primary_mat_specular);
299 glMaterialfv(GL_FRONT, GL_SHININESS, primary_mat_shininess);
300 glFrontFace(GL_CCW);
301
302 if ((Flags.texture == ON) && (Texture[Primary].IsOn == ON)) {
303 /* enable texturing */
304 glEnable(GL_TEXTURE_2D);
305 /* assign texture to the primary display list */
306 glBindTexture(GL_TEXTURE_2D, Texture[Primary].TexName);
307 /* call primary lobe display list */
308 glCallList(PrimaryList);
309 glBindTexture(GL_TEXTURE_2D, 0);
310 /* switch off texturing */
311 glDisable(GL_TEXTURE_2D);
312 } else {
313 /* call primary lobe display list */
314 glCallList(PrimaryList);
315 }
316
317 /* restore transformation matrix */
318 glPopMatrix();
319
320 /* save transformation matrix */
321 glPushMatrix();
322
323 /* translate to the position of the secondary */
324 glTranslatef (1.0, 0.0, 0.0);
325
326 /* set the material options for secondary */
327 glMaterialfv(GL_FRONT, GL_EMISSION, secondary_colour);
328 glFrontFace(GL_CW);
329
330 if ((Flags.texture == ON) && (Texture[Secondary].IsOn == ON)) {
331 /* enable texturing */
332 glEnable(GL_TEXTURE_2D);
333 /* assign texture to the secondary display list */
334 glBindTexture(GL_TEXTURE_2D, Texture[Secondary].TexName);
335 /* call secondary lobe display list */
336 glCallList(SecondaryList);
337 glBindTexture(GL_TEXTURE_2D, 0);
338 /* switch off texturing */
339 glDisable(GL_TEXTURE_2D);
340 } else {
341 /* call secondary lobe display list */
342 glCallList(SecondaryList);
343 }
344 glPopMatrix();
345
346 #ifdef HAVE_DISK
347 glPushMatrix();
348 /* set the material options for the disk */
349 /* primary emission; should be set according */
350 /* to the disk temperature */
351 glMaterialfv(GL_FRONT, GL_EMISSION, disk_colour);
352 glMaterialfv(GL_FRONT, GL_DIFFUSE, disk_mat_diffuse);
353 glMaterialfv(GL_FRONT, GL_SPECULAR, disk_mat_specular);
354 glMaterialfv(GL_FRONT, GL_SHININESS, disk_mat_shininess);
355
356 /* translate to the position of the secondary */
357 glTranslatef (1.0, 0.0, 0.0);
358 /* rotate in opposite direction according to orbital motion */
359 glRotated(-(OrbPtr->Phase-0.5*PI)*180.0/PI,0,0,1);
360
361 if (Flags.disk == ON ) {
362 if ((Flags.texture == ON) && ( Texture[Disk].IsOn == ON)){
363 /* enable texturing */
364 glEnable(GL_TEXTURE_2D);
365 /* assign texture to the disk display list */
366 glBindTexture(GL_TEXTURE_2D, Texture[Disk].TexName);
367 /* call accretion disk display list */
368 glCallList(DiskList);
369 glBindTexture(GL_TEXTURE_2D, 0);
370 /* switch off texturing */
371 glDisable(GL_TEXTURE_2D);
372 } else {
373 glCallList(DiskList);
374 }
375 }
376 /* restore transformation matrix */
377 glPopMatrix();
378 #endif
379
380 glPushMatrix();
381 /* set light positions */
382 glLightfv(SCENE_LIGHT, GL_POSITION , Lights[SCENE_LIGHT-GL_LIGHT0].Pos);
383 glLightfv(DISK_SPOT , GL_POSITION , Lights[DISK_SPOT-GL_LIGHT0].Pos);
384 glLightfv(DISK_SPOT , GL_SPOT_DIRECTION, Lights[DISK_SPOT-GL_LIGHT0].Direction);
385 /*glLightfv(GL_LIGHT2, GL_POSITION, lightpos);*/
386 /*glLightfv(GL_LIGHT2, GL_SPOT_DIRECTION, primary_spot2_direction);*/
387 glPopMatrix();
388 }
389 }
390
391 /******************************************************************
392 @package nightfall
393 @author Markus Kuster (kuster@astro.uni-tuebingen.de)
394 @version 0.5
395 @short The main light curve/rad. vel. rendering code
396 @param (GtkWidget) *widget discarded
397 @return (void)
398 @heading Open GL Animation
399 *******************************************************************/
GLDisplayPlot(GtkWidget * widget,int type)400 void GLDisplayPlot( GtkWidget *widget, int type)
401 {
402 AxisType xaxis;
403 AxisType yaxis;
404
405 xaxis = CoordSys[type].xaxis;
406 yaxis = CoordSys[type].yaxis;
407
408 if (gtk_gl_area_make_current(GTK_GL_AREA(glArea)))
409 {
410 glMatrixMode(GL_PROJECTION);
411 glLoadIdentity();
412
413 glOrtho(xaxis.min_value-0.2*xaxis.length, xaxis.max_value+0.04*xaxis.length,
414 yaxis.min_value-0.3*yaxis.length, yaxis.max_value+0.2*yaxis.length,
415 -2.0,2.0);
416
417 glMatrixMode(GL_MODELVIEW);
418 glLoadIdentity();
419
420 /* set the drawing mode to polygon mode */
421 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
422
423 /* Call plot list */
424 glCallList(PlotList[type]);
425 }
426 }
427
428 /******************************************************************
429 @package nightfall
430 @author Markus Kuster (kuster@astro.uni-tuebingen.de)
431 @version 1.0
432 @short The light curve drawing code
433 @param (void)
434 @return (void)
435 @heading Open GL Animation
436 *******************************************************************/
GLMakeLCPlot(void)437 void GLMakeLCPlot( void )
438 {
439 double Calib; /* normalization for flux */
440 int i,test;
441 float *Xplot,*Yplot/*,Xtick*/;/* x, y position */
442 float MinMag, MaxMag; /* Min,Max scaling for plot */
443 PhotoOut *FluxPtr = FluxOut; /* pointer to flux */
444 int js; /* j minus invalid */
445
446 if (gtk_gl_area_make_current(GTK_GL_AREA(glArea)))
447 {
448 /* Initialize memory for plot */
449 Xplot = malloc(3 * MAXELEMENTS * sizeof(float));
450 Yplot = malloc(3 * MAXELEMENTS * sizeof(float));
451
452 if (Xplot == NULL || Yplot == NULL)
453 #ifdef _WITH_GTK
454 {
455 if (Flags.interactive == ON) {
456 make_dialog (_(errmsg[0]));
457 if (Xplot != NULL) free(Xplot);
458 if (Yplot != NULL) free(Yplot);
459 return;
460 } else nf_error(_(errmsg[5]));
461 }
462 #else
463 nf_error(_(errmsg[5]));
464 #endif
465
466 /* >>>>>>>>>>>> Light Curve <<<<<<<<<<<<<<<<<<<<<<<<<< */
467 /* photometric zeropoint */
468 Calib = FluxOut[0].Mag[Vmag];
469
470 /* get photometric data and scale */
471 js = 0;
472 MinMag = 10.;
473 MaxMag = -10.;
474 FluxPtr = FluxOut;
475
476 /* 2002-05-03 rwichmann: the problem is that
477 lightcurve normalization has been done already, resulting
478 in MinMag = nan MaxMag = nan.
479 */
480 for (i = 0; i <= phaseind; ++i) {
481 if (i == 0 || FluxPtr->Mag[Vmag] != 0)
482 {
483 if (fabs(Calib) < DBL_EPSILON) {
484 /* already normalized */
485 Yplot[js] = - FluxPtr->Mag[Vmag];
486 }
487 else {
488 /* normalize and transform flux -> magnitude */
489 Yplot[js] = 2.5 * log10(FluxPtr->Mag[Vmag]/Calib);
490 }
491 MinMag = MIN(MinMag,Yplot[js]); MaxMag = MAX(MaxMag,Yplot[js]);
492 Xplot[js] = (FluxPtr->Phase/(PI+PI)) - 0.5;
493 ++js;
494 }
495 ++FluxPtr;
496 }
497
498 /* shift phase if necessary */
499 test = ON;
500 do {
501 if (Xplot[0] > 0.0) {
502 for (i = 0; i <= js; ++i) {
503 Xplot[i] = Xplot[i] - 1.0;
504 }
505 test = ON; /* there was something to do */
506 } else {
507 if (Xplot[0] < (-1.0)) {
508 for (i = 0; i <= js; ++i) {
509 Xplot[i] = Xplot[i] + 1.0;
510 }
511 test = ON; /* there was something to do */
512 } else { test = OFF; }
513 }
514 } while (test == ON);
515
516 if (fabs(MinMag-MaxMag) < 0.1) MinMag = -0.1;
517
518 /* plot box */
519 /* Xtick = (int)(100.*(MaxMag-MinMag+0.1)/3.)/100.; */
520
521 CoordSys[LIGHTCURVE] =
522 SetupCoords(MinMag, MaxMag, _("Phase"), "", _("Brightness (Delta mag)"));
523
524 /* plot coordinate system */
525 GLMake2DAxes(CoordSys[LIGHTCURVE], glArea);
526
527 glPointSize(2);
528 glDisable(GL_LIGHTING);
529
530 glColor3f(1.0, 1.0, 0.0);
531 glBegin(GL_POINTS);
532 for (i = 0; i < js; ++i) {
533 glVertex2f(Xplot[i], Yplot[i]);
534 }
535 glEnd();
536
537 glEnable(GL_LIGHTING);
538 glPointSize(1);
539
540 free(Xplot);
541 free(Yplot);
542 }
543 }
544
545 /******************************************************************
546 @package nightfall
547 @author Markus Kuster (kuster@astro.uni-tuebingen.de)
548 @version 1.0
549 @short The radial velocity drawing code
550 @param (void)
551 @return (void)
552 @heading Open GL Animation
553 *******************************************************************/
GLMakeRVPlot(void)554 void GLMakeRVPlot ( void )
555 {
556 int i,test;
557 float *Xplot,*Yplot,*Zplot; /* x, y, z position */
558 float MinVel, MaxVel; /* plot scaling */
559 PhotoOut *FluxPtr = FluxOut; /* pointer to flux */
560 int js; /* j minus invalid */
561
562 if (gtk_gl_area_make_current(GTK_GL_AREA(glArea)))
563 {
564 /* Initialize memory for plot */
565 /* Initialize memory for plot */
566 Xplot = malloc(3 * MAXELEMENTS * sizeof(float));
567 Yplot = malloc(3 * MAXELEMENTS * sizeof(float));
568 Zplot = malloc(3 * MAXELEMENTS * sizeof(float));
569
570 if (Xplot == NULL || Yplot == NULL)
571 #ifdef _WITH_GTK
572 {
573 if (Flags.interactive == ON) {
574 make_dialog (_(errmsg[0]));
575 if (Xplot != NULL) free(Xplot);
576 if (Yplot != NULL) free(Yplot);
577 return;
578 } else nf_error(_(errmsg[5]));
579 }
580 #else
581 nf_error(_(errmsg[5]));
582 #endif
583 /* >>>>>>>>>>>> Light Curve <<<<<<<<<<<<<<<<<<<<<<<<<< */
584
585 /* get photometric data and scale */
586 js = 0;
587 MinVel = (FluxPtr->RV[Primary]) /1000.;
588 MaxVel = (FluxPtr->RV[Secondary])/1000.;
589
590 if (Flags.elliptic == ON) {
591 for (i = 0; i <= phaseind; ++i) {
592 if (i == 0 || FluxPtr->Mag[Vmag] != 0)
593 {
594 Xplot[js] = (FluxPtr->Phase/(PI+PI)) - 0.5;
595 Yplot[js] = (FluxPtr->RV[Primary]) /1000.;
596 Zplot[js] = (FluxPtr->RV[Secondary])/1000.;
597 MinVel = MIN(MinVel,Yplot[js]); MaxVel = MAX(MaxVel,Yplot[js]);
598 MinVel = MIN(MinVel,Zplot[js]); MaxVel = MAX(MaxVel,Zplot[js]);
599 ++js;
600 }
601 ++FluxPtr;
602 }
603 } else {
604 for (i = 0; i <= phaseind; ++i) {
605 if (i == 0 || FluxPtr->Mag[Vmag] != 0)
606 {
607 Xplot[js] = (FluxPtr->Phase/(PI+PI)) - 0.5;
608 Yplot[js] = - (FluxPtr->RV[Primary]) /1000.;
609 Zplot[js] = - (FluxPtr->RV[Secondary])/1000.;
610 MinVel = MIN(MinVel,Yplot[js]); MaxVel = MAX(MaxVel,Yplot[js]);
611 MinVel = MIN(MinVel,Zplot[js]); MaxVel = MAX(MaxVel,Zplot[js]);
612 ++js;
613 }
614 ++FluxPtr;
615 }
616 }
617
618 /* shift phase if necessary */
619 test = ON;
620 do {
621 if (Xplot[0] > 0.0) {
622 for (i = 0; i <= js; ++i) {
623 Xplot[i] = Xplot[i] - 1.0;
624 }
625 test = ON; /* there was something to do */
626 } else {
627 if (Xplot[0] < (-1.0)) {
628 for (i = 0; i <= js; ++i) {
629 Xplot[i] = Xplot[i] + 1.0;
630 }
631 test = ON; /* there was something to do */
632 } else { test = OFF; }
633 }
634 } while (test == ON);
635
636 if (fabs(MinVel-MaxVel) < 5.) {
637 MinVel = -5.01;
638 MaxVel = 5.01;
639 }
640
641 /* plot box */
642 CoordSys[RADVELOCITY] =
643 SetupCoords(MinVel, MaxVel, _("Phase"), "", _("Radial Velocity (km/s)"));
644
645 /* plot coordinate system */
646 GLMake2DAxes(CoordSys[RADVELOCITY], glArea);
647
648 glPointSize(2);
649 glDisable(GL_LIGHTING);
650
651 glBegin(GL_POINTS);
652 for (i = 0; i < js; ++i) {
653 /* Primary data (red) */
654 glColor3f(1.0, 0.37, 0.0);
655 glVertex2f(Xplot[i], Yplot[i]);
656 /* Secondary data (blue) */
657 glColor3f(0.6, 0.86, 1.0);
658 glVertex2f(Xplot[i], Zplot[i]);
659 }
660 glEnd();
661
662 glEnable(GL_LIGHTING);
663 glPointSize(1);
664
665 free(Xplot);
666 free(Yplot);
667 }
668 }
669
670 /******************************************************************
671 @package nightfall
672 @author Markus Kuster (kuster@astro.uni-tuebingen.de)
673 @version 1.0
674 @short Draw x-, y- and z-axes of the binary systems reference
675 coordinate system according to Djurasevic, 1991
676 Note: this is not the OpenGL Viewing coordinate
677 system !!
678 @param (GLfloat) length length of the axes
679 @return (void)
680 @heading Open GL Animation
681 *******************************************************************/
GLDrawAxes(GLfloat length,GtkWidget * widget)682 void GLDrawAxes(GLfloat length, GtkWidget *widget)
683 {
684 float com;
685
686 /* the x coordinate of the center of mass */
687 com = (((float)(Binary[Primary].Mq))/( 1.0 + (float)(Binary[Primary].Mq)));
688
689 if (gtk_gl_area_make_current(GTK_GL_AREA(glArea)))
690 {
691 /* draw axes with thick lines */
692 glLineWidth(2);
693
694 /* disable lighting, we don't want ligthing with */
695 /* the axes */
696 glDisable(GL_LIGHTING);
697
698 /* draw axes as lines */
699 glBegin(GL_LINES);
700 /* blue x-axis */
701 glColor3f(0.0, 0.0, 1.0);
702 glVertex3f(com, 0.0, 0.0);
703 glVertex3f(com+length, 0.0, 0.0);
704
705 /* green y-axis */
706 glColor3f(0.0, 1.0, 0.0);
707 glVertex3f(com, 0.0, 0.0);
708 glVertex3f(com, -length, 0.0);
709
710 /* red z-axis */
711 glColor3f(1.0, 0.0, 0.0);
712 glVertex3f(com, 0.0, 0.0);
713 glVertex3f(com, 0.0, length);
714 glEnd();
715
716 /* switch on lighing */
717 glEnable(GL_LIGHTING);
718
719 /* set line width to 1 */
720 glLineWidth(1);
721 }
722 }
723
724 /******************************************************************
725 @package nightfall
726 @author Markus Kuster (kuster@astro.uni-tuebingen.de)
727 @version 1.1
728 @short Build a display list for x- and y-axes of the
729 coordinate system
730 @param (GLfloat) length length of the axes
731 @return (void)
732 @heading Open GL Animation
733 *******************************************************************/
GLMake2DAxes(CoordType coord,GtkWidget * widget)734 void GLMake2DAxes(CoordType coord, GtkWidget *widget)
735 {
736 float length_x, length_y, eye_x;
737 float top_xtick, bot_xtick;
738 float right_ytick, left_ytick;
739 float xmin_border,xmax_border,ymin_border,ymax_border;
740
741 double min, max, inc, store;
742
743 AxisType xaxis;
744 AxisType yaxis;
745
746 xaxis = coord.xaxis;
747 yaxis = coord.yaxis;
748
749 /* length of x- and y-axes */
750 length_x = xaxis.length;
751 length_y = yaxis.length;
752
753 if (gtk_gl_area_make_current(GTK_GL_AREA(glArea)))
754 {
755 min = yaxis.min_value;
756 max = yaxis.max_value;
757
758 DefineAxis(&min, &max, &inc);
759 store = min;
760
761 ymin_border = yaxis.min_value-coord.yborder_size;
762 ymax_border = yaxis.max_value+coord.yborder_size;
763
764 xmin_border = xaxis.min_value-coord.xborder_size;
765 xmax_border = xaxis.max_value+coord.xborder_size;
766
767 /* viewers position */
768 eye_x = xaxis.min_value + 0.5*length_x;
769
770 /* tickmarks on x-axis */
771 top_xtick = ymin_border + 0.02*length_y;
772 bot_xtick = ymin_border - 0.02*length_y;
773
774 /* tickmarks on y-axis */
775 right_ytick = xmin_border + 0.02*length_x;
776 left_ytick = xmin_border - 0.02*length_x;
777
778 /* draw axes with thick lines */
779 glLineWidth(2);
780
781 /* disable lighting, we don't want ligthing with */
782 /* the axes */
783 glDisable(GL_LIGHTING);
784
785 glColor3f(1.0, 1.0, 1.0);
786 /* draw border for plot */
787 glBegin(GL_LINES);
788 glVertex2f(xmin_border, ymin_border);
789 glVertex2f(xmin_border, ymax_border);
790
791 glVertex2f(xmin_border, ymax_border);
792 glVertex2f(xmax_border, ymax_border);
793
794 glVertex2f(xmax_border, ymax_border);
795 glVertex2f(xmax_border, ymin_border);
796
797 glVertex2f(xmax_border, ymin_border);
798 glVertex2f(xmin_border, ymin_border);
799 glEnd();
800
801 /* draw tickmarks */
802 glBegin(GL_LINES);
803 glVertex2f(-0.5, bot_xtick);
804 glVertex2f(-0.5, top_xtick);
805 glVertex2f( 0.0, bot_xtick);
806 glVertex2f( 0.0, top_xtick);
807 glVertex2f( 0.5, bot_xtick);
808 glVertex2f( 0.5, top_xtick);
809 glVertex2f( 1.0, bot_xtick);
810 glVertex2f( 1.0, top_xtick);
811 glEnd();
812
813 /* draw tickmarks */
814 glBegin(GL_LINES);
815 min = store;
816 do {
817 if (min > ymin_border && min < ymax_border)
818 {
819 glVertex2f(left_ytick, min);
820 glVertex2f(right_ytick, min);
821 }
822 min += inc;
823 } while (min < max);
824 glEnd();
825
826
827 /* select font */
828 GLSetFont(HELVETICA, 12);
829
830 glDisable(GL_LIGHTING);
831
832 glPushMatrix();
833
834 /* print labels for axes */
835 glColor3f(1.0, 1.0, 1.0);
836 GLDrawStr(eye_x-0.1, yaxis.min_value - 0.15*length_y, 0.0, xaxis.label);
837 /* GLDrawStr( -0.6, yaxis.min_value + 0.5*length_y, 0.0, yaxis.label); */
838
839 /* print tick marks */
840 GLDrawStr( -0.545, bot_xtick-0.1*length_y, 0.0, "0.5");
841 GLDrawStr( -0.050, bot_xtick-0.1*length_y, 0.0, "0.0");
842 GLDrawStr( 0.455, bot_xtick-0.1*length_y, 0.0, "0.5");
843 GLDrawStr( 0.960, bot_xtick-0.1*length_y, 0.0, "1.0");
844
845 min = store;
846 do {
847 if (min > ymin_border && min < ymax_border)
848 {
849 GLDrawStrRightAdj( -0.68, min - 0.02*length_y, 0.0, "%5.1f", min);
850 /* fprintf(stderr, "FIXME %f %f\n", left_ytick-0.1*length_x, min); */
851 }
852 min += inc;
853 } while (min < max);
854
855 /* print title string */
856 glColor3f(1.0, 1.0, 1.0);
857 GLDrawStr(coord.titlepos,yaxis.max_value+0.15*length_y,0.0,coord.title);
858
859 glPopMatrix();
860
861 /* switch on lighing */
862 glEnable(GL_LIGHTING);
863
864 /* set line width to 1 */
865 glLineWidth(1);
866 }
867 }
868
869 /******************************************************************
870 @package nightfall
871 @author Markus Kuster (kuster@astro.uni-tuebingen.de)
872 @version 0.9
873 @short Set default parameters for coordinate system
874 @param (float) ymin minimum y value
875 @param (float) ymax maximum y value
876 @param (char *) xlabel label of the x-axis
877 @param (char *) ylabel label of the y-axis
878 @param (char *) title title of the plot
879 @return (CoordType) structure containing information of the
880 coordinate system
881 @heading Open GL Animation
882 *******************************************************************/
SetupCoords(float ymin,float ymax,char * xlabel,char * ylabel,char * title)883 CoordType SetupCoords(float ymin, float ymax,
884 char *xlabel, char *ylabel, char *title)
885 {
886 AxisType x,y;
887 CoordType coord;
888 size_t str_length;
889
890 memset (&coord, '\0', sizeof(CoordType));
891
892 x = coord.xaxis;
893 y = coord.yaxis;
894
895 strncpy(coord.title, title , MAX_STR_LEN-1);
896 str_length = strlen(title);
897 if (str_length <= 12) {
898 coord.titlepos = 0.08;
899 } else {
900 coord.titlepos = 0.02;
901 }
902
903 strncpy(x.label, xlabel, MAX_STR_LEN-1);
904 strncpy(y.label, ylabel, MAX_STR_LEN-1);
905
906 /* min/max values for x/y axis */
907 x.max_value = 1.0;
908 x.min_value = -0.5;
909 y.max_value = ymax;
910 y.min_value = ymin;
911
912 /* set size of border between plot and window */
913 /* to 0.1 axes length */
914 x.length = x.max_value - x.min_value;
915 coord.xborder_size = 0.0166 * x.length;
916
917 y.length = y.max_value - y.min_value;
918 coord.yborder_size = 0.03 * y.length;
919
920 /* number of tickmarks */
921 x.numticks = 4;
922 y.numticks = 4;
923
924 coord.xaxis = x;
925 coord.yaxis = y;
926 return(coord);
927 }
928
929 #endif /* OpenGL end */
930
931
932
933
934
935