From: trelane@digitasaru.net Date: Fri, 25 Jul 2008 20:54:12 +0000 (-0500) Subject: * Seems to be coming along. Not convinced that the bowing conversions are right. X-Git-Url: http://git.maemo.org/git/?p=scdataviz;a=commitdiff_plain;h=f3ddf2cd811f53afd0edaa3b1263035d9faab318 * Seems to be coming along. Not convinced that the bowing conversions are right. --- diff --git a/graph.c b/graph.c index 423ff84..1af3cb8 100644 --- 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; } +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 - 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; @@ -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; - 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 { @@ -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; } -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 --- 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_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_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); diff --git a/graphwidget.c b/graphwidget.c index 7f2d944..95b9722 100644 --- a/graphwidget.c +++ b/graphwidget.c @@ -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_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) { + cairo_set_source_rgba(cr, 0, 0, 0, 0.25); 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); } diff --git a/scdataviz.c b/scdataviz.c index 4171631..bfed526 100644 --- a/scdataviz.c +++ b/scdataviz.c @@ -30,15 +30,23 @@ #include #include #include +#include +#include -#undef DEBUG +#define DEBUG_SHOW_ONLY_BOWED 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; @@ -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 - 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); @@ -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; @@ -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.mdb = mdb; 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