diff options
Diffstat (limited to 'src/argand.c')
-rw-r--r-- | src/argand.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/argand.c b/src/argand.c new file mode 100644 index 0000000..7e94398 --- /dev/null +++ b/src/argand.c @@ -0,0 +1,118 @@ +/* + * argand.c + * + * "Argand plane tracking" + * + * (c) 2006-2007 Thomas White <taw27@cam.ac.uk> + * + * synth2d - Two-Dimensional Crystallographic Fourier Synthesis + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gtk/gtk.h> +#include <png.h> +#include <math.h> +#include <stdlib.h> + +#include "reflist.h" +#include "displaywindow.h" + +GtkWidget *argand_pixmap_widget = NULL; +GdkPixbuf *argand_pixbuf = NULL; +GtkWidget *argand_window = NULL; + +static fftw_complex *argand_draw(ReflectionList *reflections, unsigned int width, unsigned int height) { + + unsigned int x, y, i; + double mag = 6; + double max = 0; + fftw_complex *data; + + data = malloc(height*width*sizeof(fftw_complex)); + + for ( y=0; y<height; y++ ) { + for ( x=0; x<width; x++ ) { + data[y + height*x][0] = 0; + data[y + height*x][1] = 0; + } + } + + for ( i=0; i<reflections->n_reflections; i++ ) { + double am = reflections->refs[i].amplitude; + if ( am > max ) max = am; + } + mag = (width/2) / max; + + for ( i=0; i<reflections->n_reflections; i++ ) { + + unsigned int xd, yd; + double real, imag; + double am = reflections->refs[i].amplitude; + double ph = reflections->refs[i].phase_known; + + real = am * cos(ph); + imag = am * sin(ph); + + xd = (width-1-((width/2)+(real*mag))); + yd = (height-1-((height/2)+(imag*mag))); + + data[yd + height*xd][0] = 1; + data[yd + height*xd][1] = 0; + + } + + data[(height/2) + height*(width/2)][0]=-1; + data[(height/2-1) + height*(width/2)][0]=-1; + data[(height/2+1) + height*(width/2)][0]=-1; + data[(height/2-2) + height*(width/2)][0]=-1; + data[(height/2+2) + height*(width/2)][0]=-1; + data[(height/2) + height*(width/2+1)][0]=-1; + data[(height/2) + height*(width/2-1)][0]=-1; + data[(height/2) + height*(width/2+2)][0]=-1; + data[(height/2) + height*(width/2-2)][0]=-1; + + return data; + +} + +void argand_update(ReflectionList *reflections) { + + fftw_complex *data; + + if ( argand_window == NULL ) return; + + if ( argand_pixbuf ) gdk_pixbuf_unref(argand_pixbuf); + if ( argand_pixmap_widget ) gtk_widget_destroy(argand_pixmap_widget); + + data = argand_draw(reflections, 321, 321); + argand_pixbuf = displaywindow_render_pixbuf(data, 1, 321, 321, M_PI_2, 1, 1); + argand_pixmap_widget = gtk_image_new_from_pixbuf(argand_pixbuf); + gtk_container_add(GTK_CONTAINER(argand_window), argand_pixmap_widget); + gtk_widget_show(argand_pixmap_widget); + free(data); + +} + +static void argand_close() { + argand_window = NULL; + argand_pixbuf = NULL; + argand_pixmap_widget = NULL; +} + +void argand_open(ReflectionList *reflections) { + + if ( argand_window ) return; + + argand_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(argand_window), "Argand Plane"); + g_signal_connect(GTK_OBJECT(argand_window), "destroy", G_CALLBACK(argand_close), NULL); + gtk_widget_show_all(argand_window); + + argand_update(reflections); + +} + |