void gtk_graph_axis_set_tick(GtkGraph *graph, GtkGraphAxisType axis, gfloat majtick, gfloat mintick) { GtkGraphAxis *target; g_return_if_fail (GTK_IS_GRAPH (graph)); switch(axis) { case GTK_GRAPH_AXIS_INDEPENDANT: target = graph->independant; break; case GTK_GRAPH_AXIS_DEPENDANT: target = graph->dependant; break; default: return; break; } target->maj_tick = majtick; if (mintick) target->min_tick = mintick; else target->min_tick = target->maj_tick; target->autoscale_tick = FALSE; }
void gtk_graph_smith_plot_traces(GtkGraph *graph) { gint i, n; GtkGraphTrace *tmp; gfloat CA, CB, CC, CD; GdkPoint *pts = NULL; g_return_if_fail (graph != NULL); g_return_if_fail (GTK_IS_GRAPH (graph)); g_return_if_fail (GTK_WIDGET_REALIZED (graph)); g_return_if_fail (graph->graph_type == SMITH); tmp = graph->traces; for (n = 0 ; n < graph->num_traces ; n++) { /* Make sure that there is some data in the trace */ if (tmp->Xdata == NULL || tmp->Ydata == NULL) continue; /* Assign the storage for the co-ordinates of each data point */ pts = (GdkPoint *) g_malloc ((tmp->num_points) * sizeof(GdkPoint)); /* The Xdata array contains the resistance whilst the Ydata array has the reactance */ CA = tmp->Xdata[0] - graph->smith_Z0; CB = tmp->Ydata[0]; CC = tmp->Xdata[0] + graph->smith_Z0; CD = tmp->Ydata[0]; pts[0].x = centre_x + (CA*CC + CB*CD)/(CC*CC + CD*CD) * graph->dependant->scale_factor; pts[0].y = centre_y - (CB*CC - CA*CD)/(CC*CC + CD*CD) * graph->dependant->scale_factor; for (i = 1 ; i < tmp->num_points ; i++) { CA = tmp->Xdata[i] - graph->smith_Z0; CB = tmp->Ydata[i]; CC = tmp->Xdata[i] + graph->smith_Z0; CD = tmp->Ydata[i]; pts[i].x = centre_x + (CA*CC + CB*CD)/(CC*CC + CD*CD) * graph->dependant->scale_factor; pts[i].y = centre_y - (CB*CC - CA*CD)/(CC*CC + CD*CD) * graph->dependant->scale_factor; } gdk_draw_lines (buffer, tmp->format->line_gc, pts, tmp->num_points);/* Draw the lines */ for (i = 1 ; i < tmp->num_points ; i++)/* and then draw the markers */ if (tmp->format->marker_type != GTK_GRAPH_MARKER_NONE) { gdk_gc_set_clip_origin(tmp->format->marker_gc, pts[i].x-5, pts[i].y-5); gdk_draw_pixmap(buffer, tmp->format->marker_gc, tmp->format->marker, 0, 0, pts[i].x-5, pts[i].y-5, -1, -1); } g_free(pts);// Free up all storage after use tmp = tmp->next;// and then move onto the next trace } }
/** * gtk_graph_smith_set_Z0: * @graph: the #GtkGraph containing the Smith Chart to be modified * @Z0: the unique identifier of the trace * * Sets the normalising value for Smith's Charts. All Smith's Charts * are normalised to a particular value - A #GtkGraph defaults to a * normalisation of 50 Ohms. This function allows the user to select * any @Z0 that they choose * */ void gtk_graph_smith_set_Z0(GtkGraph *graph, gfloat Z0) { g_return_if_fail (graph != NULL); g_return_if_fail (GTK_IS_GRAPH (graph)); g_return_if_fail (GTK_WIDGET_REALIZED (graph)); graph->smith_Z0 = Z0; }
void gtk_graph_axis_format_grid(GtkGraph *graph, GtkGraphAxisType axis, gboolean visible) { GtkGraphAxis *target; g_return_if_fail (GTK_IS_GRAPH (graph)); target = graph->independant; /* Assume it's the independant axis */ if (axis == GTK_GRAPH_AXIS_DEPENDANT) /* and correct things it its not */ target = graph->dependant; g_return_if_fail (target != NULL); /* --- Do error checking --- */ target->grid_visible = visible; }
/* Allow user to set the value at which the other axis crosses the specified axis */ void gtk_graph_axis_set_crossing(GtkGraph *graph, GtkGraphAxisType axis, GtkGraphCrossingType type, gfloat crossing_value) { GtkGraphAxis *target; g_return_if_fail (GTK_IS_GRAPH (graph)); target = graph->independant; /* Assume it's the independant axis */ if (axis == GTK_GRAPH_AXIS_DEPENDANT) /* and correct things it its not */ target = graph->dependant; g_return_if_fail (target != NULL); target->crossing_type = type; target->crossing_value = 0; if (type == GTK_GRAPH_USERVALUE) target->crossing_value = crossing_value; }
void gtk_graph_clear(GtkGraph *graph) { int i; g_return_if_fail(graph); g_return_if_fail(GTK_IS_GRAPH(graph)); for (i=0; i<graph->nodes->len; i++) { if (NODE(graph, i)->label) g_free(NODE(graph, i)->label); g_free(NODE(graph, i)); } for (i=0; i<graph->edges->len; i++) g_free(EDGE(graph, i)); graph->nodes->len = graph->edges->len = 0; gtk_graph_update(graph); }
/* Format_Axis: Specifiy Axis Labels and Titles */ void gtk_graph_axis_format(GtkGraph *graph, GtkGraphAxisType axis, GtkGraphNumberFormat number_format, gint precision, const gchar *title) { GtkGraphAxis *target; g_return_if_fail (GTK_IS_GRAPH (graph)); target = graph->independant; /* Assume it's the independant axis */ if (axis == GTK_GRAPH_AXIS_DEPENDANT) /* and correct things it its not */ target = graph->dependant; g_return_if_fail (target != NULL); /* --- Do error checking --- */ target->format = number_format; target->precision = precision; if (target->title != NULL) g_free(target->title); target->title = g_strdup(title); }
/* Set_Limits: Set upper and lower limits, as well as tick increments */ void gtk_graph_axis_set_limits(GtkGraph *graph, GtkGraphAxisType axis, gfloat max, gfloat min) { GtkGraphAxis *target; g_return_if_fail (GTK_IS_GRAPH (graph)); switch(axis) { case GTK_GRAPH_AXIS_INDEPENDANT: target = graph->independant; break; case GTK_GRAPH_AXIS_DEPENDANT: target = graph->dependant; break; default: return; break; } target->axis_max = max; target->axis_min = min; target->autoscale_limits = FALSE; }
/* Scale_Axis: A simple Axis Scaler */ void gtk_graph_axis_scale_axis(GtkGraph *graph, gint user_width, gint user_height) { GtkGraphTrace *t; gfloat global_X_max = -1E99, global_Y_max= -1E99, global_X_min=1E99, global_Y_min=1E99; gint i; /* --- Do error checking --- */ g_return_if_fail (graph != NULL); g_return_if_fail (GTK_IS_GRAPH (graph)); t = graph->traces; if (graph->independant->autoscale_limits || graph->dependant->autoscale_limits) { for (i = 0 ; i < graph->num_traces ; i++) { if (t->xmax > global_X_max) global_X_max = t->xmax; if (t->xmin < global_X_min) global_X_min = t->xmin; if (t->ymax > global_Y_max) global_Y_max = t->ymax; if (t->ymin < global_Y_min) global_Y_min = t->ymin; t = t->next; } } switch (graph->graph_type) { case XY: if (graph->independant->autoscale_limits) /* we're autoscaling the independant axis limits*/ { graph->independant->axis_max = nicenum(global_X_max, 0); graph->independant->axis_min = nicenum(global_X_min, 0); } if (graph->independant->autoscale_tick) /* we're autoscaling the independant axis ticks*/ { graph->independant->n_maj_tick = 10; graph->independant->n_min_tick = 5; graph->independant->maj_tick = (graph->independant->axis_max - graph->independant->axis_min) / graph->independant->n_maj_tick; graph->independant->min_tick = graph->independant->maj_tick/ graph->independant->n_min_tick; } else { graph->independant->n_maj_tick = ceil((graph->independant->axis_max - graph->independant->axis_min) / (float) graph->independant->maj_tick); graph->independant->n_min_tick = graph->independant->maj_tick / graph->independant->min_tick; } if (graph->dependant->autoscale_limits) /* we're autoscaling the dependant axis limits*/ { graph->dependant->axis_max = nicenum(global_Y_max, 0); graph->dependant->axis_min = nicenum(global_Y_min, 0); } if (graph->dependant->autoscale_tick) /* we're autoscaling the dependant axis ticks*/ { graph->dependant->n_maj_tick = 10; graph->dependant->n_min_tick = 5; graph->dependant->maj_tick = (graph->dependant->axis_max - graph->dependant->axis_min) / graph->dependant->n_maj_tick; graph->dependant->min_tick = graph->dependant->maj_tick/ graph->dependant->n_min_tick; } else { graph->dependant->n_maj_tick = ceil((graph->dependant->axis_max - graph->dependant->axis_min) / (float)graph->dependant->maj_tick); graph->dependant->n_min_tick = graph->dependant->maj_tick / graph->dependant->min_tick; } graph->independant->pxls_per_maj_tick = user_width / graph->independant->n_maj_tick; graph->independant->scale_factor = (gfloat) (graph->independant->pxls_per_maj_tick) / graph->independant->maj_tick; graph->dependant->pxls_per_maj_tick = user_height / graph->dependant->n_maj_tick; graph->dependant->scale_factor = (gfloat) (graph->dependant->pxls_per_maj_tick) / graph->dependant->maj_tick; break; case POLAR: if (graph->dependant->autoscale_limits) /* we're autoscaling the dependant axis limits*/ { graph->dependant->axis_max = nicenum(global_Y_max, 0); graph->dependant->axis_min = nicenum(global_Y_min, 0); } if (graph->dependant->autoscale_tick) /* we're autoscaling the dependant axis ticks*/ { graph->dependant->n_maj_tick = 10; graph->dependant->n_min_tick = 5; graph->dependant->maj_tick = (graph->dependant->axis_max - graph->dependant->axis_min) / graph->dependant->n_maj_tick; graph->dependant->min_tick = graph->dependant->maj_tick/ graph->dependant->n_min_tick; } else { graph->dependant->n_maj_tick = ceil((graph->dependant->axis_max - graph->dependant->axis_min) / (float)graph->dependant->maj_tick); graph->dependant->n_min_tick = graph->dependant->maj_tick / graph->dependant->min_tick; } switch(graph->polar_format.type) { case DEGREES_SYMMETRIC: graph->independant->axis_min = -180.0; graph->independant->axis_max = 179.9; break; case DEGREES_ANTISYMMETRIC: graph->independant->axis_min = 0.0; graph->independant->axis_max = 359.9; break; case RADIANS_SYMMETRIC: graph->independant->axis_min = -3.141592654; graph->independant->axis_max = 3.141592654; break; case RADIANS_ANTISYMMETRIC: graph->independant->axis_min = 0.0; graph->independant->axis_max = 2*3.141592654; break; } graph->dependant->pxls_per_maj_tick = user_height / (2.0 * graph->dependant->n_maj_tick); graph->dependant->scale_factor = (gfloat) (graph->dependant->pxls_per_maj_tick) / graph->dependant->maj_tick; break; case SMITH: graph->dependant->n_maj_tick = 1.0; graph->dependant->maj_tick = 1.0; graph->dependant->pxls_per_maj_tick = user_height / (2.0 * graph->dependant->n_maj_tick); graph->dependant->scale_factor = (gfloat) (graph->dependant->pxls_per_maj_tick) / graph->dependant->maj_tick; break; } }
/* Smith.c: Routines for plotting Smith charts */ void gtk_graph_smith_plot_axes(GtkGraph *graph) { gint i ; gint x, y, w, h; gfloat ri[] = {0.2, 0.5, 1.0, 2.0, 5.0}, rxl[]={0.20, 0.5, 1, 2, 5}, coeff1, r, store, arc_angle; gfloat yend, xend; // The x and y co-ordinates of the end of the reactance lines gchar label[10]; gint text_width, text_height; gint xpos = 0, ypos = 0; // X and Y co-ordinate locations of radial labels PangoFontDescription *fontdesc = NULL; PangoLayout *layout = NULL; g_return_if_fail (graph != NULL); g_return_if_fail (GTK_IS_GRAPH (graph)); g_return_if_fail (GTK_WIDGET_REALIZED (graph)); g_return_if_fail (graph->graph_type == SMITH); fontdesc = pango_font_description_from_string("Sans 10"); layout = gtk_widget_create_pango_layout(GTK_WIDGET(graph), NULL); pango_layout_set_font_description(layout, fontdesc); /* Plot the concentric grid */ centre_x = user_origin_x + user_width / 2; centre_y = user_origin_y + user_width / 2; gdk_draw_arc(buffer, Gridcontext, FALSE, centre_x - graph->dependant->scale_factor, centre_y - graph->dependant->scale_factor, 2.0 * graph->dependant->scale_factor, 2.0 * graph->dependant->scale_factor, 0, 23040); for (i = 0 ; i < 5 ; i++) { /* Draw the circles of Constant Resistance */ coeff1 = ri[i] / (1.0+ri[i]); r = 1.0 / (ri[i] + 1.0); x = centre_x + (gint)((coeff1 - r) * graph->dependant->scale_factor); y = centre_y - (gint) (r * graph->dependant->scale_factor); w = 2.0 * r * graph->dependant->scale_factor; h = 2.0 * r * graph->dependant->scale_factor; gdk_draw_arc(buffer, Gridcontext, FALSE, x, y, w, h, 0, 23039); g_snprintf(label, 10, "%.0f", ri[i] * graph->smith_Z0); pango_layout_set_text(layout, label, -1); pango_layout_get_pixel_size(layout, &text_width, &text_height); xpos = x - text_width / 2; ypos = centre_y ; gdk_draw_layout(buffer, BandWcontext, xpos, ypos, layout); /* Draw the circles of Constant Reactance */ r = 1.0 / rxl[i]; x = centre_x + (gint) ((1 - r) * graph->dependant->scale_factor); w = 2.0 * r * graph->dependant->scale_factor; h = 2.0 * r * graph->dependant->scale_factor; /* Now Label the Constant Reactance curves */ g_snprintf(label, 10, "+j%0.f", rxl[i]*graph->smith_Z0); pango_layout_set_text(layout, label, -1); pango_layout_get_pixel_size(layout, &text_width, &text_height); store = 2.0 * r/(r*r + 1); yend = store * (gfloat)(graph->dependant->scale_factor); xend = sqrt(1 - store*store) * (gfloat)(graph->dependant->scale_factor); switch(i) { case 0: case 1: g_snprintf(label, 10, "+j%0.f", rxl[i]*graph->smith_Z0); pango_layout_set_text(layout, label, -1); pango_layout_get_pixel_size(layout, &text_width, &text_height); ypos = centre_y - (gint)yend; xpos = centre_x - (gint)xend; gdk_draw_layout(buffer, BandWcontext, xpos - text_width, ypos - text_height, layout); g_snprintf(label, 10, "-j%0.f", rxl[i]*graph->smith_Z0); pango_layout_set_text(layout, label, -1); ypos = centre_y + (gint)yend; gdk_draw_layout(buffer, BandWcontext, xpos - text_width, ypos, layout); arc_angle = atan((gfloat)(centre_x + graph->dependant->scale_factor - xpos)/(gfloat)((centre_y + r * graph->dependant->scale_factor)-ypos)) *180.0 / 3.141592654; gdk_draw_arc(buffer, Gridcontext, FALSE, x, centre_y, w, h, 5760, (gint)(arc_angle * 64.0)); // Capacitive Circles gdk_draw_arc(buffer, Gridcontext, FALSE, x, centre_y - (gint) ((2 *r) * graph->dependant->scale_factor), w, h, 17280 - (gint) (arc_angle*64.0), (gint) (arc_angle*64.0)); // Inductive Circles break; case 2: g_snprintf(label, 10, "+j%0.f", rxl[i]*graph->smith_Z0); pango_layout_set_text(layout, label, -1); pango_layout_get_pixel_size(layout, &text_width, &text_height); ypos = centre_y - (gint)yend; xpos = centre_x - (gint)xend; gdk_draw_layout(buffer, BandWcontext, xpos - text_width/2, ypos - text_height, layout); g_snprintf(label, 10, "-j%0.f", rxl[i]*graph->smith_Z0); pango_layout_set_text(layout, label, -1); ypos = centre_y + yend; gdk_draw_layout(buffer, BandWcontext, xpos - text_width/2, ypos, layout); arc_angle = atan((gfloat)(centre_x + graph->dependant->scale_factor - xpos)/(gfloat)(ypos - (centre_y + r * graph->dependant->scale_factor))) *180.0 / 3.141592654; gdk_draw_arc(buffer, Gridcontext, FALSE, x, centre_y, w, h, 5760, (gint) (arc_angle*64.0)); // Capacitive Circles gdk_draw_arc(buffer, Gridcontext, FALSE, x, centre_y - (gint) ((2 *r) * graph->dependant->scale_factor), w, h, 17280 - (gint) (arc_angle*64.0), (gint) (arc_angle*64.0)); // Inductive Circles break; case 3: case 4: g_snprintf(label, 10, "+j%0.f", rxl[i]*graph->smith_Z0); pango_layout_set_text(layout, label, -1); pango_layout_get_pixel_size(layout, &text_width, &text_height); ypos = centre_y - (gint)yend; xpos = centre_x + (gint)xend; gdk_draw_layout(buffer, BandWcontext, xpos, ypos - text_height, layout); g_snprintf(label, 10, "-j%0.f", rxl[i]*graph->smith_Z0); pango_layout_set_text(layout, label, -1); ypos = centre_y + (gint)yend; gdk_draw_layout(buffer, BandWcontext, xpos, ypos, layout); arc_angle = atan((gfloat)(centre_x + graph->dependant->scale_factor - xpos)/(gfloat)(ypos - (centre_y + r * graph->dependant->scale_factor))) *180.0 / 3.141592654; gdk_draw_arc(buffer, Gridcontext, FALSE, x, centre_y, w, h, 5760, 11520 - (gint) (arc_angle*64.0)); // Capacitive Circles gdk_draw_arc(buffer, Gridcontext, FALSE, x, centre_y - (gint) ((2 *r) * graph->dependant->scale_factor), w, h, 5760 + (gint) (arc_angle*64.0), 11520 - (gint) (arc_angle*64.0)); // Inductive Circles break; } } /* Draw the Real Axis */ gdk_draw_line(buffer, Gridcontext, centre_x - user_width/2, centre_y, centre_x + user_width/2, centre_y); g_snprintf(label, 10, "+inf"); pango_layout_set_text(layout, label, -1); pango_layout_get_pixel_size(layout, &text_width, &text_height); xpos = centre_x + user_width/2.0 - text_width/2 ; ypos = centre_y ; gdk_draw_layout(buffer, BandWcontext, xpos, ypos, layout); pango_font_description_free(fontdesc); g_object_unref(layout); }