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