* Seems to be coming along. Not convinced that the bowing conversions are right.
authortrelane@digitasaru.net <trelane@digitasaru.net>
Fri, 25 Jul 2008 20:54:12 +0000 (15:54 -0500)
committertrelane@digitasaru.net <trelane@digitasaru.net>
Fri, 25 Jul 2008 20:54:12 +0000 (15:54 -0500)
graph.c
graph.h
graphwidget.c
scdataviz.c

diff --git a/graph.c b/graph.c
index 423ff84..1af3cb8 100644 (file)
--- a/graph.c
+++ b/graph.c
@@ -81,13 +81,33 @@ int graph_add_point(Graph* graph, double x, double y, const GString *label) {
   return 0;
 }
 
   return 0;
 }
 
+int graph_add_graph_line(Graph* graph, struct graph_line *l) {
+  if(graph->lines == NULL) {
+    if((graph->lines = g_ptr_array_new()) == NULL) return 1;
+  }
+  g_ptr_array_add(graph->lines, l);
+  if((graph->points->len == 0) && 
+     (graph->lines->len == 1)) {
+    graph->maxx = graph->minx = l->p0_x;
+    graph->maxy = graph->miny = l->p0_y;
+  }else{
+    if(l->p0_x > graph->maxx) graph->maxx = l->p0_x;
+    if(l->p0_x < graph->minx) graph->minx = l->p0_x;
+    if(l->p0_y > graph->maxy) graph->maxy = l->p0_y;
+    if(l->p0_y < graph->miny) graph->miny = l->p0_y;
+  }
+  if(l->p3_x > graph->maxx) graph->maxx = l->p3_x;
+  if(l->p3_x < graph->minx) graph->minx = l->p3_x;
+  if(l->p3_y > graph->maxy) graph->maxy = l->p3_y;
+  if(l->p3_y < graph->miny) graph->miny = l->p3_y;
+  return 0;
+}
+
+
 int graph_add_line(Graph* graph, double p0_x, double p0_y, double p1_x, double p1_y, double p2_x, double p2_y, double p3_x, double p3_y) {
   #ifdef DEBUG
   fprintf(stderr, "graph_add_line(%d, p0_x=%g, p0_y=%g, p1_x=%g, p1_y=%g, p2_x=%g, p2_y=%g, p3_x=%g, p3_y=%g\n", (unsigned int) graph, p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y);
   #endif
 int graph_add_line(Graph* graph, double p0_x, double p0_y, double p1_x, double p1_y, double p2_x, double p2_y, double p3_x, double p3_y) {
   #ifdef DEBUG
   fprintf(stderr, "graph_add_line(%d, p0_x=%g, p0_y=%g, p1_x=%g, p1_y=%g, p2_x=%g, p2_y=%g, p3_x=%g, p3_y=%g\n", (unsigned int) graph, p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y);
   #endif
-  if(graph->lines == NULL) {
-    if((graph->lines = g_ptr_array_new()) == NULL) return 1;
-  }
   struct graph_line *l;
   if((l=(struct graph_line*)malloc(sizeof(struct graph_line))) == NULL) return 2;
   l->p0_x=p0_x;
   struct graph_line *l;
   if((l=(struct graph_line*)malloc(sizeof(struct graph_line))) == NULL) return 2;
   l->p0_x=p0_x;
@@ -98,22 +118,7 @@ int graph_add_line(Graph* graph, double p0_x, double p0_y, double p1_x, double p
   l->p2_y=p2_y;
   l->p3_x=p3_x;
   l->p3_y=p3_y;
   l->p2_y=p2_y;
   l->p3_x=p3_x;
   l->p3_y=p3_y;
-  g_ptr_array_add(graph->lines, l);
-  if((graph->points->len == 0) && 
-     (graph->lines->len == 1)) {
-    graph->maxx = graph->minx = p0_x;
-    graph->maxy = graph->miny = p0_y;
-  }else{
-    if(p0_x > graph->maxx) graph->maxx = p0_x;
-    if(p0_x < graph->minx) graph->minx = p0_x;
-    if(p0_y > graph->maxy) graph->maxy = p0_y;
-    if(p0_y < graph->miny) graph->miny = p0_y;
-  }
-  if(p3_x > graph->maxx) graph->maxx = p3_x;
-  if(p3_x < graph->minx) graph->minx = p3_x;
-  if(p3_y > graph->maxy) graph->maxy = p3_y;
-  if(p3_y < graph->miny) graph->miny = p3_y;
-  return 0;
+  return graph_add_graph_line(graph, l);
 }
     
 struct cxt {
 }
     
 struct cxt {
@@ -146,7 +151,11 @@ void graph_bezier_linear_to_cubic(double x0, double x3, double *x1, double *x2)
   *x2 = (2.0*x3 + x0)/3.0;
 }
 
   *x2 = (2.0*x3 + x0)/3.0;
 }
 
-void graph_bezier_qudratic_to_cubic(double x0, double x3, double *x1, double *x2) {
-  *x2 = (x3 - x0)/3.0 + (*x1);
-  *x1 = (x0 - 3.0*(*x1))/2.0;
+void graph_bezier_linear_to_quadratic(double x0, double x3, double *x1) {
+  *x1 = (x3 + x0)/2.0;
+}
+
+void graph_bezier_quadratic_to_cubic(double x0, double x3, double *x1, double *x2) {
+  *x2 = (x3-2.0*(*x1))/3.0;
+  *x1 = (x0-2.0*(*x1))/3.0;
 }
 }
diff --git a/graph.h b/graph.h
index 68aa97b..927935b 100644 (file)
--- a/graph.h
+++ b/graph.h
@@ -80,11 +80,12 @@ Graph *graph_new(void);
 int graph_add_point(Graph* graph, double x, double y, const GString *label);
 int graph_add_graph_point(Graph* graph, struct graph_point *pt);
 int graph_add_line(Graph* graph, double p0_x, double p0_y, double p1_x, double p1_y, double p2_x, double p2_y, double p3_x, double p3_y);
 int graph_add_point(Graph* graph, double x, double y, const GString *label);
 int graph_add_graph_point(Graph* graph, struct graph_point *pt);
 int graph_add_line(Graph* graph, double p0_x, double p0_y, double p1_x, double p1_y, double p2_x, double p2_y, double p3_x, double p3_y);
+int graph_add_graph_line(Graph* graph, struct graph_line *l);
 void graph_add_linear_connectors(Graph* graph);
 /*Provide x0, x3; x1 and x2 will be set*/
 void graph_bezier_linear_to_cubic(double x0, double x3, double *x1, double *x2);
 /*Provide x0, x1, x2.  x1 and x2 will be set appropriately.*/
 void graph_add_linear_connectors(Graph* graph);
 /*Provide x0, x3; x1 and x2 will be set*/
 void graph_bezier_linear_to_cubic(double x0, double x3, double *x1, double *x2);
 /*Provide x0, x1, x2.  x1 and x2 will be set appropriately.*/
-void graph_bezier_qudratic_to_cubic(double x0, double x3, double *x1, double *x2);
+void graph_bezier_quadratic_to_cubic(double x0, double x3, double *x1, double *x2);
 
 
 
 
 
 
index 7f2d944..95b9722 100644 (file)
@@ -113,15 +113,16 @@ static void draw(GtkWidget *graph, cairo_t *cr) {
   cairo_select_font_face (cr, "Georgia",
                          CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
   cairo_set_font_size (cr, 0.05);
   cairo_select_font_face (cr, "Georgia",
                          CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
   cairo_set_font_size (cr, 0.05);
-  cairo_set_source_rgb(cr, 1, 1, 1);
-  cairo_fill_preserve(cr);
-  cairo_set_source_rgb(cr, 0, 0, 0);
-  cairo_stroke(cr);
-  g_ptr_array_foreach(gw->graph->points, &draw_point, (gpointer)&cxt);
   if(gw->graph->lines != NULL) {
   if(gw->graph->lines != NULL) {
+    cairo_set_source_rgba(cr, 0, 0, 0, 0.25);
     g_ptr_array_foreach(gw->graph->lines, &draw_lines, (gpointer)&cxt);
     cairo_stroke(cr);
   }
     g_ptr_array_foreach(gw->graph->lines, &draw_lines, (gpointer)&cxt);
     cairo_stroke(cr);
   }
+  cairo_set_source_rgb(cr, 1, 1, 1);
+  cairo_fill_preserve(cr);
+  cairo_set_source_rgb(cr, 0, 0, 0);
+  g_ptr_array_foreach(gw->graph->points, &draw_point, (gpointer)&cxt);
+  cairo_stroke(cr);
   cairo_restore(cr);
 }
 
   cairo_restore(cr);
 }
 
index 4171631..bfed526 100644 (file)
 #include <gtk/gtk.h>
 #include <graphwidget.h>
 #include <matdb-dotcode.h>
 #include <gtk/gtk.h>
 #include <graphwidget.h>
 #include <matdb-dotcode.h>
+#include <stdlib.h>
+#include <strings.h>
 
 
-#undef DEBUG
+#define DEBUG_SHOW_ONLY_BOWED
 
 struct xy_properties {
   GString *xprop;
   GString *yprop;
   Graph *graph;
 
 struct xy_properties {
   GString *xprop;
   GString *yprop;
   Graph *graph;
+  struct matdb *mdb;
+  struct matdb_material *mat;
 };
 
 };
 
+static void lookup_xy(GHashTable* propts, GString* xprop, GString* yprop, double **x, double **y) {
+  *x=g_hash_table_lookup(propts, xprop->str);
+  *y=g_hash_table_lookup(propts, yprop->str);
+}
 
 static void put_mat_in_graph(gpointer key, gpointer value, gpointer user_data) {
   struct xy_properties *propmap = user_data;
 
 static void put_mat_in_graph(gpointer key, gpointer value, gpointer user_data) {
   struct xy_properties *propmap = user_data;
@@ -49,8 +57,8 @@ static void put_mat_in_graph(gpointer key, gpointer value, gpointer user_data) {
   #ifdef DEBUG
   fprintf(stderr, "put_mat_in_graph(%s) (x->%s, y->%s): ", (char*)key, propmap->xprop->str, propmap->yprop->str);
   #endif
   #ifdef DEBUG
   fprintf(stderr, "put_mat_in_graph(%s) (x->%s, y->%s): ", (char*)key, propmap->xprop->str, propmap->yprop->str);
   #endif
-  if(((x=g_hash_table_lookup(mat->properties, propmap->xprop->str)) != NULL)
-     && ((y=g_hash_table_lookup(mat->properties, propmap->yprop->str)) != NULL)) {
+  lookup_xy(mat->properties, propmap->xprop, propmap->yprop, &x, &y);
+  if((x != NULL) && (y != NULL)) {
     graph_add_point(propmap->graph, *x, *y, mat->name);
   #ifdef DEBUG
     fprintf(stderr, "added (x->%s=%g, y->%s=%g)\n", propmap->xprop->str, *x, propmap->yprop->str, *y);
     graph_add_point(propmap->graph, *x, *y, mat->name);
   #ifdef DEBUG
     fprintf(stderr, "added (x->%s=%g, y->%s=%g)\n", propmap->xprop->str, *x, propmap->yprop->str, *y);
@@ -60,6 +68,75 @@ static void put_mat_in_graph(gpointer key, gpointer value, gpointer user_data) {
   }
 }
 
   }
 }
 
+static void inner_link_materials(gpointer key, gpointer value, gpointer user_data) {
+  struct xy_properties *propmap = user_data;
+  struct matdb_material *mat = value;
+  if(!strcasecmp(mat->name->str, "vacuum")) return;
+  if(!strcasecmp(mat->name->str, "pvb")) return;
+  if(g_string_equal(mat->name, propmap->mat->name)) return;
+  struct graph_line *l = (struct graph_line *)malloc(sizeof(struct graph_line));
+  if(l == NULL) return;
+  struct matdb_bowing *bow = NULL;
+  GHashTable *subtable;
+  double *p0_x, *p0_y, *p1_x, *p1_y, *p3_x, *p3_y;
+  lookup_xy(propmap->mat->properties, propmap->xprop, propmap->yprop, &p0_x, &p0_y);
+  lookup_xy(mat->properties, propmap->xprop, propmap->yprop, &p3_x, &p3_y);
+#ifdef DEBUG
+  fprintf(stderr, "%s:%s x=%s y=%s p0(%g,%g) p3(%g,%g)\n", propmap->mat->name->str, mat->name->str, propmap->xprop->str, propmap->yprop->str, (p0_x)?*p0_x:0, (p0_y)?*p0_y:0, (p3_x)?*p3_x:0, (p3_y)?*p3_y:0);
+#endif
+  if((p0_x != NULL) && (p0_y != NULL) && (p3_x != NULL) && (p3_y != NULL)) {
+    l->p0_x = *p0_x;
+    l->p0_y = *p0_y;
+    l->p3_x = *p3_x;
+    l->p3_y = *p3_y;
+    if((subtable = g_hash_table_lookup(propmap->mdb->bowings, propmap->mat->name->str)) == NULL) {
+      /*Try the other way 'round*/
+      if((subtable = g_hash_table_lookup(propmap->mdb->bowings, mat->name->str) )
+         != NULL) {
+       bow = g_hash_table_lookup(subtable, propmap->mat->name->str);
+      }
+    }else{
+      bow = g_hash_table_lookup(subtable, mat->name->str);
+    }
+    if(bow != NULL) {
+      if((p1_x = g_hash_table_lookup(bow->properties, propmap->xprop->str)) != NULL) {
+       l->p1_x = *p1_x;
+       graph_bezier_quadratic_to_cubic(l->p0_x, l->p3_x, &(l->p1_x), &(l->p2_x));
+      }else{
+       graph_bezier_linear_to_cubic(l->p0_x, l->p3_x, &(l->p1_x), &(l->p2_x));
+      }
+      if((p1_y = g_hash_table_lookup(bow->properties, propmap->yprop->str)) != NULL) {
+       l->p1_y = *p1_y;
+       graph_bezier_quadratic_to_cubic(l->p0_y, l->p3_y, &(l->p1_y), &(l->p2_y));
+      }else{
+       graph_bezier_linear_to_cubic(l->p0_y, l->p3_y, &(l->p1_y), &(l->p2_y));
+      }
+    }else{
+      #ifdef DEBUG_SHOW_ONLY_BOWED
+      free(l);
+      return;
+      #endif;
+      graph_bezier_linear_to_cubic(l->p0_x, l->p3_x, &(l->p1_x), &(l->p2_x));
+      graph_bezier_linear_to_cubic(l->p0_y, l->p3_y, &(l->p1_y), &(l->p2_y));
+    }
+    #ifdef DEBUG
+    fprintf(stderr, "%s:%s p0(%g,%g) p1(%g,%g) p2(%g,%g), p3(%g,%g)\n", propmap->mat->name->str, mat->name->str, l->p0_x, l->p0_y, l->p1_x, l->p1_y, l->p2_x, l->p2_y, l->p3_x, l->p3_y);
+    #endif
+    graph_add_graph_line(propmap->graph, l);
+  }else{
+    free(l);
+  }
+}
+
+static void link_materials(gpointer key, gpointer value, gpointer user_data) {
+  struct xy_properties *propmap = user_data;
+  struct matdb_material *mat = value;
+  if(!strcasecmp(mat->name->str, "vacuum")) return;
+  if(!strcasecmp(mat->name->str, "pvb")) return;
+  propmap->mat = mat;
+  g_hash_table_foreach(propmap->mdb->materials, &inner_link_materials, propmap);
+}
+
 int main(int   argc, char *argv[]) 
 {
     GtkWidget *window;
 int main(int   argc, char *argv[]) 
 {
     GtkWidget *window;
@@ -81,8 +158,10 @@ int main(int   argc, char *argv[])
     propmap.xprop = g_string_new("a_lc");
     propmap.yprop = g_string_new("E_g_Gamma");
     propmap.graph = graph_widget_get_graph(GRAPH_WIDGET(graph));
     propmap.xprop = g_string_new("a_lc");
     propmap.yprop = g_string_new("E_g_Gamma");
     propmap.graph = graph_widget_get_graph(GRAPH_WIDGET(graph));
+    propmap.mdb = mdb;
     g_hash_table_foreach(mdb->materials, &put_mat_in_graph, &propmap);
     g_hash_table_foreach(mdb->materials, &put_mat_in_graph, &propmap);
-    graph_add_linear_connectors(propmap.graph);
+    //graph_add_linear_connectors(propmap.graph);
+    g_hash_table_foreach(mdb->materials, &link_materials, &propmap);
 
 
     //Connect signals
 
 
     //Connect signals