/* NIGHTFALL Light Curve Synthesis Program */ /* Copyright (C) 1998 Rainer Wichmann */ /* */ /* This program is free software; you can redistribute it */ /* and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include "Light.h" #ifdef _WITH_PGPLOT #ifndef _WITH_GNUPLOT #include "cpgplot.h" #endif #endif #ifdef _WITH_GTK #ifdef _WITH_PGPLOT /* global variables */ static float slicePosition = 0; /* position of slice */ static int slicePlane = 1; /* plane of slice (ON == xy) */ static int sliceState; /* store current plane */ /**************************************************************************** @package nightfall @author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de) @version 1.1 @short Compute potential in cartesian coordinates @param (double) x The x position @param (double) y The y position @param (double) z The z position @param (double) q The mass ratio @param (double) f Asynchronicity @return (double) The potential @heading Plotting ****************************************************************************/ double RocheXYSlice(double x, double y, double z, double q, double f) { double Eval; /* return value = potential */ double r1, r2; /* radius to point from primary/secondary */ double h1, h2, h3;/* helper variables */ h1 = SQR(x); h2 = SQR(y); h3 = SQR(z); r1 = sqrt(h1 + h2 + h3); h1 = SQR(x-1); r2 = sqrt(h1 + h2 + h3); if (r1 > DBL_EPSILON && r2 > DBL_EPSILON) { h1 = SQR(x); h3 = SQR(f); Eval = 1.0/r1 + q * ( 1.0/r2 - x ) + ( (q+1.0)/2.0 ) * (h1 + h2) * h3; } else { if (Flags.debug[VERBOSE] == ON || Flags.debug[WARN] == ON) fprintf(stderr, "**Warning**: Divide by zero, File %s, Line %d \n", __FILE__, __LINE__); Eval = 1.0; } return(Eval); } /**************************************************************************** @package nightfall @author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de) @version 1.37 @short Contour plot a slice through the potential @param (int) GtkEnd What to plot @return (void) @heading Plotting ****************************************************************************/ void PlotGtkSlice(int GtkEnd) { register unsigned long i, j = 0; /* loop variables */ float RocheXYArray[120][180]; /* matrix for slice */ float x, y; /* position in plane */ float q; /* mass ratio */ float f; /* asynchronicity */ float cont_levels[6]; /* contour levels */ int Ncont; /* number of contour levels */ char sliceTitle[32]; /* plot title */ float transform[6] = {-1.0-0.5*(1.0/60.), /* transformation matrix */ (1.0/60.), 0, -1.0-0.5*(1.0/60.), 0, (1.0/60.)}; float *a_ptr = &RocheXYArray[0][0]; /* pointer to slice matrix */ char file_out[256+4]; /* ps output file */ sprintf(file_out, "%s%s", Out_Plot_File, "/CPS"); /* >>>>>>>>>>>>>>>>>>>> open plot device <<<<<<<<<<<<<<<<<<<<<<< */ #ifdef _WITH_GNUPLOT if (GtkEnd == 3) { if (cpgopen("/XSERVE") != 1) { make_dialog (_(errmsg[2])); return; } } if (GtkEnd == 2) { cpgend(); /* end previous interactive plot */ if (cpgopen(file_out) != 1) { make_dialog (_(errmsg[1])); return; } } gnu_start(); #else if (GtkEnd != 2) { if(cpgopen("/XSERVE") != 1) { make_dialog (_(errmsg[2])); return; } } else { if(cpgopen(file_out) != 1) { make_dialog (_(errmsg[1])); return; } } #endif /* >>>>>>>>>>>>>>>>>>>> compute slice <<<<<<<<<<<<<<<<<<<<<<< */ q = Binary[Primary].Mq; if (Flags.asynchron1 == ON) f = Binary[Primary].Fratio; else f = 1.0; for (i = 0; i < 120; ++i) { for (j = 0; j < 180; ++j) { y = -1.0 + (i/60.0); x = -1.0 + (j/60.0); if (slicePlane == 1) RocheXYArray[i][j] = -RocheXYSlice(x, y, slicePosition, q, f); else RocheXYArray[i][j] = -RocheXYSlice(x, slicePosition, y, q, f); } } cont_levels[0] = -Binary[Primary].RCLag1; cont_levels[1] = -Binary[Primary].RCLag2; cont_levels[2] = -Binary[Primary].RCLag3; cont_levels[3] = -Binary[Primary].RochePot; RochePot = 0.0; Mq = Binary[Primary].Mq; cont_levels[4] = -RochePerpendSecond(Binary[Secondary].Radius); /* cont_levels[4] = -Binary[Secondary].RochePot; */ Ncont = 5; /* >>>>>>>>>>>>>>>>>>>> plot slice <<<<<<<<<<<<<<<<<<<<<<< */ cpgscf(2); cpgslw(1); cpgsch(1.2); cpgsvp(0.15,0.9,0.1,1.0); cpgwnad(-1., 2., -1.0, 1.0); if (slicePlane == 1) { /* slice is parallel to xy plane */ sprintf(sliceTitle, _("Roche Potential at Z = %4.2f"), slicePosition); cpglab(_("X"), _("Y"), sliceTitle); } else { /* slice is parallel to xz plane */ sprintf(sliceTitle, _("Roche Potential at Y = %4.2f"), slicePosition); cpglab(_("X"), _("Z"), sliceTitle); } #ifdef _WITH_GNUPLOT cpgbox("BCNST", 0.5, 0, "BCNST", 0.5, 0); #else cpgbox("BCNST", 0,0, "BCNST", 0,0); #endif cpgcont(a_ptr, 180, 120, 1, 180, 1, 120, cont_levels, (-Ncont), transform); /* >>>>>>>>>>>>>>>>>>>> end plot <<<<<<<<<<<<<<<<<<<<<<< */ if (GtkEnd == 2) my_cpgend(); else cpgend(); return; } /**************************************************************************** @package nightfall @author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de) @version 1.0 @short Make hardcopy of slice (ps file) @param (GtkWidget) *widget Discarded @param (gpointer) *data Discarded @return (void) @heading Plotting ****************************************************************************/ void hard_slice (GtkWidget *widget, gpointer *data) { PlotGtkSlice (2); return; } /**************************************************************************** @package nightfall @author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de) @version 1.0 @short Destroy the Slicer @param (GtkWidget) *widget Discarded @param (gpointer) *data Widget to destroy @return (void) @heading Plotting ****************************************************************************/ void delete_slice (GtkWidget *widget, gpointer *data) { gtk_widget_destroy (GTK_WIDGET (data) ); return; } /**************************************************************************** @package nightfall @author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de) @version 1.0 @short Adjust slice position @param (GtkAdjustment) *adj The new position @param (gpointer) *data Discarded @return (void) @heading Plotting ****************************************************************************/ void slice_change (GtkAdjustment *adj, GtkWidget *data) { slicePosition = 0.01 * adj->value; PlotGtkSlice (ON); return; } /**************************************************************************** @package nightfall @author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de) @version 1.0 @short Change slice plane @param (GtkWidget) *widget Discarded @param (gpointer) *data Discarded @return (void) @heading Plotting ****************************************************************************/ void slice_plane (GtkWidget *widget, gpointer *data) { /* 0 = xz, 1 = xy */ sscanf ((char *) data, "%d", &slicePlane); if (slicePlane != sliceState) { PlotGtkSlice (ON); sliceState = slicePlane; } return; } /**************************************************************************** @package nightfall @author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de) @version 1.0 @short Interactive display of slices through Roche potential @param (void) @return (void) @heading Plotting ****************************************************************************/ void MakeSliceBox() { GtkWidget *label; GtkWidget *button; GtkWidget *vbox; GtkWidget *hbox; GtkWidget *frame; GtkWidget *separator; GtkWidget *scale1; GtkObject *adj1; GtkWidget *slice_window; GSList *group; GtkTooltips *tooltips; /* >>>>>>>>>>>>>>>>>>>>>>> MAKE WIDGET <<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ tooltips = gtk_tooltips_new (); gtk_tooltips_set_delay (tooltips, 1200); slice_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); /* gtk_widget_set_usize (slice_window, 200, 150); */ gtk_window_set_position(GTK_WINDOW(slice_window), GTK_WIN_POS_MOUSE); #ifdef USING_GTK2 gtk_window_set_resizable(GTK_WINDOW(slice_window), TRUE); #else gtk_window_set_policy (GTK_WINDOW(slice_window), FALSE, FALSE, TRUE); #endif /* gtk_window_set_policy (GTK_WINDOW(slice_window), TRUE, TRUE, FALSE); */ gtk_signal_connect (GTK_OBJECT (slice_window), "destroy", (GtkSignalFunc) delete_slice, GTK_WIDGET (slice_window)); gtk_window_set_title (GTK_WINDOW (slice_window), _("Roche Slicer") ); gtk_container_set_border_width (GTK_CONTAINER (slice_window), 0); frame = gtk_frame_new (_("Viewing Options") ); gtk_container_add (GTK_CONTAINER (slice_window), frame); gtk_container_set_border_width(GTK_CONTAINER(frame), 2); gtk_widget_show (frame); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (frame), vbox); gtk_widget_show (vbox); adj1 = gtk_adjustment_new (0.0, -100.0, 100.0, 0.1, 1.0, 1.0); gtk_signal_connect (GTK_OBJECT (adj1), "value_changed", GTK_SIGNAL_FUNC (slice_change), NULL); hbox = gtk_hbox_new (TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (hbox), 4); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); scale1 = gtk_hscale_new(GTK_ADJUSTMENT (adj1)); #ifdef _WITH_GNUPLOT /* with GTK_UPDATE_CONTINUOUS, I get the error: */ /* ** ERROR **: sigpipe caught */ /* Broken pipe */ /* is contour plotting in gnuplot too slow ?? or the fprintf to fifo ?? */ gtk_range_set_update_policy (GTK_RANGE (scale1), GTK_UPDATE_DISCONTINUOUS); #else gtk_range_set_update_policy (GTK_RANGE (scale1), GTK_UPDATE_CONTINUOUS); #endif gtk_box_pack_start (GTK_BOX (hbox), scale1, TRUE, TRUE, 0); gtk_widget_show (scale1); hbox = gtk_hbox_new (TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (hbox), 4); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); label = gtk_label_new (_("Slice Position") ); gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); gtk_widget_show (label); hbox = gtk_hbox_new (TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (hbox), 4); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); button = gtk_radio_button_new_with_label (NULL, _("X-Z Plane") ); gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) slice_plane, (gpointer) "0"); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); gtk_widget_show (button); group = gtk_radio_button_group (GTK_RADIO_BUTTON (button)); button = gtk_radio_button_new_with_label(group, _("X-Y Plane") ); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) slice_plane, (gpointer) "1"); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); gtk_widget_show (button); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0); gtk_widget_show (separator); hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0); gtk_widget_show (hbox); #ifdef USING_GTK2 button = gtk_button_new_with_label (_("Postscript") ); gtk_button_set_image (GTK_BUTTON(button), gtk_image_new_from_stock (GTK_STOCK_PRINT, GTK_ICON_SIZE_SMALL_TOOLBAR) ); #else button = gtk_button_new_with_label (_("Postscript") ); #endif gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) hard_slice, NULL); gtk_tooltips_set_tip (tooltips, button, _("Make postscript hardcopy from current plot"), NULL); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); (GTK_WIDGET_FLAGS (button) |= (GTK_CAN_DEFAULT)); gtk_widget_grab_default (button); gtk_widget_show (button); #ifdef USING_GTK2 button = gtk_button_new_from_stock(GTK_STOCK_OK); #else button = gtk_button_new_with_label (_("Close") ); #endif gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) delete_slice, GTK_WIDGET (slice_window)); gtk_tooltips_set_tip (tooltips, button, _("Close Roche Slicer"),NULL); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); (GTK_WIDGET_FLAGS (button) |= (GTK_CAN_DEFAULT)); gtk_widget_grab_default (button); gtk_widget_show (button); gtk_widget_show (slice_window); /* >>>>>>>>>>>>>>>>>>>>>>> initial plot <<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ slicePlane = 1; sliceState = 1; PlotGtkSlice (3); return; } /* with pgplot */ #endif /* with gtk */ #endif