static void gtk_plot_surface_draw_triangle (GtkPlotSurface *surface, GtkPlotDTtriangle *triangle, gint sign) { GtkPlot *plot; GtkPlotVector side1, side2, light, normal; GtkPlotVector points[3]; GtkPlotPoint t[3]; GdkDrawable *drawable; GdkColor color, real_color; gdouble factor, norm; gboolean visible = TRUE; plot = GTK_PLOT(GTK_PLOT_DATA(surface)->plot); drawable = plot->drawable; points[0].x = triangle->na->x; points[0].y = triangle->na->y; points[0].z = triangle->na->z; points[1].x = triangle->nb->x; points[1].y = triangle->nb->y; points[1].z = triangle->nb->z; points[2].x = triangle->nc->x; points[2].y = triangle->nc->y; points[2].z = triangle->nc->z; t[0].x = triangle->na->px; t[0].y = triangle->na->py; t[1].x = triangle->nb->px; t[1].y = triangle->nb->py; t[2].x = triangle->nc->px; t[2].y = triangle->nc->py; side1.x = (points[1].x - points[0].x) * sign; side1.y = (points[1].y - points[0].y) * sign; side1.z = (points[1].z - points[0].z) * sign; side2.x = (points[2].x - points[0].x) * sign; side2.y = (points[2].y - points[0].y) * sign; side2.z = (points[2].z - points[0].z) * sign; if(surface->height_gradient){ gtk_plot_data_get_gradient_level(GTK_PLOT_DATA(surface), (triangle->na->z + triangle->nb->z + triangle->nc->z) / 3.0, &real_color); }else{ color = surface->color; light = surface->light; norm = sqrt(light.x*light.x + light.y*light.y + light.z*light.z); light.x /= norm; light.y /= norm; light.z /= norm; if(GTK_IS_PLOT3D(plot)){ normal.x = side1.y * side2.z - side1.z * side2.y; normal.y = side1.z * side2.x - side1.x * side2.z; normal.z = side1.x * side2.y - side1.y * side2.x; norm = sqrt(normal.x*normal.x + normal.y*normal.y + normal.z*normal.z); factor = (normal.x*light.x + normal.y*light.y + normal.z*light.z) / norm; } else { factor = 1.0; } gtk_plot_surface_lighting(&color, &real_color, factor, surface->ambient); } if(GTK_IS_PLOT3D(plot)) if(((t[1].x-t[0].x)*(t[2].y-t[0].y) - (t[1].y-t[0].y)*(t[2].x-t[0].x))*sign > 0) visible = FALSE; if(visible) gtk_plot_pc_set_color(plot->pc, &real_color); else gtk_plot_pc_set_color(plot->pc, &surface->shadow); gtk_plot_pc_draw_polygon(plot->pc, !surface->transparent, t, 3); if(visible) gtk_plot_pc_set_color(plot->pc, &surface->grid_foreground); else gtk_plot_pc_set_color(plot->pc, &surface->grid_background); if(surface->show_mesh || !surface->dt->quadrilateral) gtk_plot_pc_draw_polygon(plot->pc, FALSE, t, 3); if(!surface->show_mesh && surface->show_grid && surface->dt->quadrilateral) gtk_plot_pc_draw_line(plot->pc, t[1].x, t[1].y, t[2].x, t[2].y); }
static void gtk_plot_flux_draw_arrow(GtkPlotFlux *flux, gdouble x1, gdouble y1, gdouble x2, gdouble y2) { GtkPlot *plot; GtkPlotData *data; GtkPlotPoint arrow[3]; gdouble xm, ym; gdouble width, height; gdouble arrow_width; gdouble line_width; gdouble angle; gdouble length; gdouble m; data = GTK_PLOT_DATA(flux); plot = data->plot; m = plot->magnification; width = fabs(x2 - x1); height = fabs(y2 - y1); /* This is a nan */ if (width != width || height != height) return; if(width == 0 && height == 0) return; if(width != 0) angle = atan2((y2 - y1), (x2 - x1)); else angle = asin((y2 - y1)/height); length = (y2 - y1)*(y2 - y1) + (x2 - x1)*(x2 - x1); if (length > 0.0) length = sqrt(length); arrow_width = flux->arrow_width; line_width = data->symbol.border.line_width; gtk_plot_pc_set_color(plot->pc, &data->symbol.color); gtk_plot_pc_set_lineattr (plot->pc, line_width, 0, 0, 0); gtk_plot_pc_set_dash (plot->pc, 0, 0, 0); if(flux->centered && width != 0){ x1 -= cos(angle) * length / 2.0; x2 -= cos(angle) * length / 2.0; } if(flux->centered && height != 0){ y1 -= sin(angle) * length / 2.0; y2 -= sin(angle) * length / 2.0; } if(flux->arrow_style == GTK_PLOT_SYMBOL_EMPTY) gtk_plot_pc_draw_line(plot->pc, x1, y1, x2, y2); else gtk_plot_pc_draw_line(plot->pc, x1, y1, x2 - flux->arrow_length * m * cos(angle) / 2., y2 - flux->arrow_length * m * sin(angle) / 2.); arrow[1].x = x2; arrow[1].y = y2; xm = x2 - cos(angle) * flux->arrow_length * m; ym = y2 - sin(angle) * flux->arrow_length * m; arrow[0].x = xm - sin(angle)* arrow_width * m / 2.0; arrow[0].y = ym + cos(angle)* arrow_width * m / 2.0; arrow[2].x = xm + sin(angle)* arrow_width * m / 2.0; arrow[2].y = ym - cos(angle)* arrow_width * m / 2.0; switch(flux->arrow_style){ case GTK_PLOT_SYMBOL_EMPTY: gtk_plot_pc_draw_lines (plot->pc, arrow, 3); break; case GTK_PLOT_SYMBOL_OPAQUE: gtk_plot_pc_set_color(plot->pc, &plot->background); gtk_plot_pc_draw_polygon (plot->pc, TRUE, arrow, 3); gtk_plot_pc_set_color(plot->pc, &data->symbol.color); gtk_plot_pc_draw_polygon (plot->pc, FALSE, arrow, 3); break; case GTK_PLOT_SYMBOL_FILLED: gtk_plot_pc_draw_polygon (plot->pc, TRUE, arrow, 3); } }