aboutsummaryrefslogtreecommitdiff
path: root/src/argand.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/argand.c')
-rw-r--r--src/argand.c118
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);
+
+}
+