/* gtkplot3d - 3d scientific plots widget for gtk+ * Copyright 1999-2001 Adrian E. Feiguin * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include "gtkplot.h" #include "gtkplotdata.h" #include "gtkplotsurface.h" #include "gtkplot3d.h" #include "gtkpsfont.h" #define DEFAULT_WIDTH 420 #define DEFAULT_HEIGHT 340 #define DEFAULT_FONT_HEIGHT 10 #ifndef PI #define PI 3.141592653589793238462643383279502884197 #endif #ifndef SQRT2 #define SQRT2 1.41421356237309504880168872420969807856967 #endif #define P_(string) string enum { PROP_0, PROP_CENTER, PROP_ORIGIN, PROP_A1, PROP_A2, PROP_A3, PROP_XY_VISIBLE, PROP_YZ_VISIBLE, PROP_ZX_VISIBLE, PROP_COLOR_XY, PROP_COLOR_YZ, PROP_COLOR_ZX, PROP_FRAME, PROP_CORNER, PROP_CORNER_VISIBLE, PROP_ZMIN, PROP_ZMAX, PROP_ZSCALE, PROP_TITLES_OFFSET, PROP_XFACTOR, PROP_YFACTOR, PROP_ZFACTOR, }; static void gtk_plot3d_class_init (GtkPlot3DClass *klass); static void gtk_plot3d_init (GtkPlot3D *plot); static void gtk_plot3d_destroy (GtkObject *object); static void gtk_plot3d_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gtk_plot3d_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void gtk_plot3d_real_paint (GtkWidget *widget); static void gtk_plot3d_draw_plane (GtkPlot3D *plot, GtkPlotVector v1, GtkPlotVector v2, GtkPlotVector v3, GtkPlotVector v4, GdkColor background); static void gtk_plot3d_draw_grids (GtkPlot3D *plot, GtkPlotAxis *axis, GtkPlotVector origin); static void gtk_plot3d_draw_axis (GtkPlot3D *plot, GtkPlotAxis *axis, GtkPlotVector tick, GtkPlotVector delta); static void gtk_plot3d_draw_labels (GtkPlot3D *plot, GtkPlotAxis *axis, GtkPlotVector delta); static void gtk_plot3d_real_get_pixel (GtkWidget *widget, gdouble x, gdouble y, gdouble z, gdouble *px, gdouble *py, gdouble *pz); extern gint roundint (gdouble x); static GtkPlotClass *parent_class = NULL; GtkType gtk_plot3d_get_type (void) { static GtkType plot_type = 0; if (!plot_type) { GtkTypeInfo plot_info = { "GtkPlot3D", sizeof (GtkPlot3D), sizeof (GtkPlot3DClass), (GtkClassInitFunc) gtk_plot3d_class_init, (GtkObjectInitFunc) gtk_plot3d_init, /* reserved 1*/ NULL, /* reserved 2 */ NULL, (GtkClassInitFunc) NULL, }; plot_type = gtk_type_unique (gtk_plot_get_type(), &plot_info); } return plot_type; } static void gtk_plot3d_class_init (GtkPlot3DClass *klass) { GtkObjectClass *object_class; GtkWidgetClass *widget_class; GtkPlotClass *plot_class; GtkPlot3DClass *plot3d_class; GObjectClass *gobject_class = G_OBJECT_CLASS (klass); parent_class = gtk_type_class (gtk_plot_get_type ()); object_class = (GtkObjectClass *) klass; widget_class = (GtkWidgetClass *) klass; plot_class = (GtkPlotClass *) klass; plot3d_class = (GtkPlot3DClass *) klass; object_class->destroy = gtk_plot3d_destroy; gobject_class->set_property = gtk_plot3d_set_property; gobject_class->get_property = gtk_plot3d_get_property; plot_class->plot_paint = gtk_plot3d_real_paint; plot3d_class->get_pixel = gtk_plot3d_real_get_pixel; g_object_class_install_property(gobject_class, PROP_CENTER, g_param_spec_pointer ("center_vector", P_("Center"), P_("Position of the center point"), G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_ORIGIN, g_param_spec_pointer ("origin_vector", P_("Origin"), P_("Position of the origin"), G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_A1, g_param_spec_double ("a1", P_("Angle 1"), P_("Angle 1"), -G_MAXDOUBLE, G_MAXDOUBLE,0.0, G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_A2, g_param_spec_double ("a2", P_("Angle 2"), P_("Angle 2"), -G_MAXDOUBLE, G_MAXDOUBLE,0.0, G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_A3, g_param_spec_double ("a3", P_("Angle 3"), P_("Angle 3"), -G_MAXDOUBLE, G_MAXDOUBLE,0.0, G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_XY_VISIBLE, g_param_spec_boolean ("xy_visible", P_("XY Visible"), P_("XY Plane visible"), FALSE, G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_YZ_VISIBLE, g_param_spec_boolean ("yz_visible", P_("YZ Visible"), P_("YZ Plane visible"), FALSE, G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_ZX_VISIBLE, g_param_spec_boolean ("zx_visible", P_("ZX Visible"), P_("ZX Plane visible"), FALSE, G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_COLOR_XY, g_param_spec_pointer ("color_xy", P_("XY Color"), P_("Color of XY Plane"), G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_COLOR_YZ, g_param_spec_pointer ("color_yz", P_("YZ Color"), P_("Color of YZ Plane"), G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_COLOR_ZX, g_param_spec_pointer ("color_zx", P_("ZX Color"), P_("Color of ZX Plane"), G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_FRAME, g_param_spec_pointer ("frame_line", P_("Frame Line"), P_("Frame Line"), G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_CORNER, g_param_spec_pointer ("corner_line", P_("Corner Line"), P_("Corner Line"), G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_CORNER_VISIBLE, g_param_spec_boolean ("corner_visible", P_("Corner Visible"), P_("Draw the entire cube"), FALSE, G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_ZMIN, g_param_spec_double ("zmin", P_("Z Min"), P_("Min value of the Z axis"), -G_MAXDOUBLE, G_MAXDOUBLE,0.0, G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_ZMAX, g_param_spec_double ("zmax", P_("Z Max"), P_("Max value of the Z axis"), -G_MAXDOUBLE, G_MAXDOUBLE,0.0, G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_ZSCALE, g_param_spec_int ("zscale", P_("Z Scale"), P_("Scale used for the Z axis"), 0,G_MAXINT,0, G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_TITLES_OFFSET, g_param_spec_int ("titles_offset", P_("Titles Offset"), P_("Titles distance from the axes"), -G_MAXINT,G_MAXINT,0, G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_XFACTOR, g_param_spec_double ("xfactor", P_("X Factor"), P_("Relative size of the x axis"), 0.0, G_MAXDOUBLE,0.0, G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_YFACTOR, g_param_spec_double ("yfactor", P_("Y Factor"), P_("Relative size of the y axis"), 0.0, G_MAXDOUBLE,0.0, G_PARAM_READABLE|G_PARAM_WRITABLE)); g_object_class_install_property(gobject_class, PROP_ZFACTOR, g_param_spec_double ("zfactor", P_("Z Factor"), P_("Relative size of the z axis"), 0.0, G_MAXDOUBLE,0.0, G_PARAM_READABLE|G_PARAM_WRITABLE)); } static void gtk_plot3d_init (GtkPlot3D *plot) { GtkWidget *widget; GdkColor color; gint i; GTK_WIDGET_SET_FLAGS(plot, GTK_NO_WINDOW); for(i = 0; i < 360; i++){ plot->ncos[i] = cos(i*PI/180.); plot->nsin[i] = sin(i*PI/180.); } widget = GTK_WIDGET(plot); gdk_color_black(gtk_widget_get_colormap(widget), &widget->style->black); gdk_color_white(gtk_widget_get_colormap(widget), &widget->style->white); GTK_PLOT(plot)->legends_x = .8; plot->ax = GTK_PLOT(plot)->bottom; plot->ay = GTK_PLOT(plot)->left; plot->az = GTK_PLOT(plot)->top; plot->center.x = 0.5; plot->center.y = 0.5; plot->center.z = 0.5; plot->xfactor = 1.0; plot->yfactor = 1.0; plot->zfactor = 1.0; gtk_plot3d_reset_angles(plot); gtk_plot3d_rotate_x(plot, 60.); gtk_plot3d_rotate_z(plot, 30.); GTK_PLOT(plot)->xmin = 0.; GTK_PLOT(plot)->xmax = 1.000000; GTK_PLOT(plot)->ymin = 0.; GTK_PLOT(plot)->ymax = 1.000000; plot->zmin = 0.; plot->zmax = 1.000000; plot->xy_visible = TRUE; plot->yz_visible = TRUE; plot->zx_visible = TRUE; plot->ax->show_major_grid = FALSE; plot->ax->show_minor_grid = FALSE; plot->ay->show_major_grid = FALSE; plot->ay->show_minor_grid = FALSE; plot->az->show_major_grid = FALSE; plot->az->show_minor_grid = FALSE; plot->ax->show_major_grid = TRUE; plot->ax->show_minor_grid = TRUE; plot->ay->show_major_grid = TRUE; plot->ay->show_minor_grid = TRUE; plot->az->show_major_grid = TRUE; plot->az->show_minor_grid = TRUE; plot->ax->ticks.nmajorticks = 0; plot->ax->ticks.nminorticks = 0; plot->ax->ticks.values = NULL; plot->ax->ticks.set_limits = FALSE; plot->ax->ticks.begin = 0; plot->ax->ticks.end = 0; plot->ax->ticks.step = .100000000; plot->ax->ticks.nminor = 1; plot->ay->ticks.nmajorticks = 0; plot->ay->ticks.nminorticks = 0; plot->ay->ticks.values = NULL; plot->ay->ticks.set_limits = FALSE; plot->ay->ticks.begin = 0; plot->ay->ticks.end = 0; plot->ay->ticks.step = .100000000; plot->ay->ticks.nminor = 1; plot->az->ticks.nmajorticks = 0; plot->az->ticks.nminorticks = 0; plot->az->ticks.values = NULL; plot->az->ticks.set_limits = FALSE; plot->az->ticks.begin = 0; plot->az->ticks.end = 0; plot->az->ticks.step = .100000000; plot->az->ticks.nminor = 1; plot->ax->ticks.min = 0.0; plot->ax->ticks.max = 1.0; plot->ax->labels_offset = 25; plot->ax->major_mask = GTK_PLOT_TICKS_OUT; plot->ax->minor_mask = GTK_PLOT_TICKS_OUT; plot->ax->ticks_length = 8; plot->ax->ticks_width = 1; plot->ax->orientation = GTK_PLOT_AXIS_X; plot->ax->ticks.scale = GTK_PLOT_SCALE_LINEAR; plot->ax->is_visible = TRUE; plot->ax->custom_labels = FALSE; plot->ay->ticks.min = 0.0; plot->ay->ticks.max = 1.0; plot->ay->major_mask = GTK_PLOT_TICKS_OUT; plot->ay->minor_mask = GTK_PLOT_TICKS_OUT; plot->ay->ticks_length = 8; plot->ay->ticks_width = 1; plot->ay->labels_offset = 25; plot->ay->orientation = GTK_PLOT_AXIS_Y; plot->ay->ticks.scale = GTK_PLOT_SCALE_LINEAR; plot->ay->is_visible = TRUE; plot->ay->custom_labels = FALSE; plot->az->ticks.min = 0.0; plot->az->ticks.max = 1.0; plot->az->major_mask = GTK_PLOT_TICKS_OUT; plot->az->minor_mask = GTK_PLOT_TICKS_OUT; plot->az->ticks_length = 8; plot->az->ticks_width = 1; plot->az->labels_offset = 25; plot->az->orientation = GTK_PLOT_AXIS_Z; plot->az->ticks.scale = GTK_PLOT_SCALE_LINEAR; plot->az->is_visible = TRUE; plot->az->custom_labels = FALSE; plot->az->line.line_style = GTK_PLOT_LINE_SOLID; plot->az->line.line_width = 2; plot->az->line.color = widget->style->black; plot->az->labels_attr.text = NULL; plot->az->labels_attr.height = DEFAULT_FONT_HEIGHT; plot->az->labels_attr.fg = widget->style->black; plot->az->labels_attr.bg = widget->style->white; plot->az->labels_attr.transparent = TRUE; plot->az->labels_attr.justification = GTK_JUSTIFY_CENTER; plot->az->labels_attr.angle = 0; plot->az->label_mask = GTK_PLOT_LABEL_OUT; plot->az->label_style = GTK_PLOT_LABEL_FLOAT; plot->az->label_precision = 1; plot->az->title.angle = 90; plot->az->title.justification = GTK_JUSTIFY_CENTER; plot->az->title.height = DEFAULT_FONT_HEIGHT; plot->az->title.fg = widget->style->black; plot->az->title.bg = widget->style->white; plot->az->title.transparent = TRUE; plot->az->title_visible = TRUE; plot->ax->line.line_style = GTK_PLOT_LINE_SOLID; plot->ax->line.line_width = 2; plot->ax->line.color = widget->style->black; plot->ax->labels_attr.text = NULL; plot->ax->labels_attr.height = DEFAULT_FONT_HEIGHT; plot->ax->labels_attr.fg = widget->style->black; plot->ax->labels_attr.bg = widget->style->white; plot->ax->labels_attr.transparent = TRUE; plot->ax->labels_attr.justification = GTK_JUSTIFY_CENTER; plot->ax->labels_attr.angle = 0; plot->ax->label_mask = GTK_PLOT_LABEL_OUT; plot->ax->label_style = GTK_PLOT_LABEL_FLOAT; plot->ax->label_precision = 1; plot->ax->title.angle = 0; plot->ax->title.justification = GTK_JUSTIFY_CENTER; plot->ax->title.height = DEFAULT_FONT_HEIGHT; plot->ax->title.fg = widget->style->black; plot->ax->title.bg = widget->style->white; plot->ax->title.transparent = TRUE; plot->ax->title_visible = TRUE; plot->ay->line.line_style = GTK_PLOT_LINE_SOLID; plot->ay->line.line_width = 2; plot->ay->line.color = widget->style->black; plot->ay->labels_attr.text = NULL; plot->ay->labels_attr.height = DEFAULT_FONT_HEIGHT; plot->ay->labels_attr.fg = widget->style->black; plot->ay->labels_attr.bg = widget->style->white; plot->ay->labels_attr.transparent = TRUE; plot->ay->labels_attr.angle = 0; plot->ay->label_mask = GTK_PLOT_LABEL_OUT; plot->ay->label_style = GTK_PLOT_LABEL_FLOAT; plot->ay->label_precision = 1; plot->ay->labels_attr.justification = GTK_JUSTIFY_CENTER; plot->ay->title.angle = 0; plot->ay->title.justification = GTK_JUSTIFY_CENTER; plot->ay->title.height = DEFAULT_FONT_HEIGHT; plot->ay->title.fg = widget->style->black; plot->ay->title.bg = widget->style->white; plot->ay->title.transparent = TRUE; plot->ay->title_visible = TRUE; gtk_plot_axis_set_title(GTK_PLOT(plot)->bottom, "X Title"); gtk_plot_axis_set_title(GTK_PLOT(plot)->left, "Y Title"); gtk_plot_axis_set_title(GTK_PLOT(plot)->top, "Z Title"); GTK_PLOT(plot)->xscale = GTK_PLOT_SCALE_LINEAR; GTK_PLOT(plot)->yscale = GTK_PLOT_SCALE_LINEAR; plot->zscale = GTK_PLOT_SCALE_LINEAR; plot->xy.major_mask = plot->ax->major_mask; plot->xy.minor_mask = plot->ax->minor_mask; plot->xy.label_mask = plot->ax->label_mask; plot->xz.major_mask = plot->ax->major_mask; plot->xz.minor_mask = plot->ax->minor_mask; plot->xz.label_mask = plot->ax->label_mask; plot->yx.major_mask = plot->ay->major_mask; plot->yx.minor_mask = plot->ay->minor_mask; plot->yx.label_mask = plot->ay->label_mask; plot->yz.major_mask = plot->ay->major_mask; plot->yz.minor_mask = plot->ay->minor_mask; plot->yz.label_mask = plot->ay->label_mask; plot->zx.major_mask = plot->az->major_mask; plot->zx.minor_mask = plot->az->minor_mask; plot->zx.label_mask = plot->az->label_mask; plot->zy.major_mask = plot->az->major_mask; plot->zy.minor_mask = plot->az->minor_mask; plot->zy.label_mask = plot->az->label_mask; plot->xy.title_visible = plot->ax->title_visible; plot->xz.title_visible = plot->ax->title_visible; plot->yx.title_visible = plot->ay->title_visible; plot->yz.title_visible = plot->ay->title_visible; plot->zx.title_visible = plot->az->title_visible; plot->zy.title_visible = plot->az->title_visible; plot->frame.color = widget->style->black; plot->frame.line_width = 1; plot->frame.line_style = GTK_PLOT_LINE_SOLID; plot->corner_visible = FALSE; plot->corner.line_style = GTK_PLOT_LINE_SOLID; plot->corner.line_width = 0; plot->corner.color = widget->style->black; plot->ax->direction = plot->e1; plot->ay->direction = plot->e2; plot->az->direction = plot->e3; gdk_color_parse("gray95", &color); gdk_color_alloc(gtk_widget_get_colormap(widget), &color); plot->color_xy = color; gdk_color_parse("gray80", &color); gdk_color_alloc(gtk_widget_get_colormap(widget), &color); plot->color_yz = color; gdk_color_parse("gray65", &color); gdk_color_alloc(gtk_widget_get_colormap(widget), &color); plot->color_zx = color; plot->titles_offset = 60; GTK_PLOT(plot)->legends_attr.transparent = FALSE; gtk_plot_axis_ticks_recalc(plot->ax); gtk_plot_axis_ticks_recalc(plot->ay); gtk_plot_axis_ticks_recalc(plot->az); GTK_PLOT(plot)->clip_data = TRUE; gtk_psfont_init(); } static void gtk_plot3d_destroy (GtkObject *object) { if ( GTK_OBJECT_CLASS (parent_class)->destroy ) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } static void gtk_plot3d_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GtkPlot3D *plot; plot = GTK_PLOT3D (object); switch(prop_id){ case PROP_CENTER: plot->center = *((GtkPlotVector *)g_value_get_pointer(value)); break; case PROP_ORIGIN: plot->origin = *((GtkPlotVector *)g_value_get_pointer(value)); break; case PROP_A1: plot->a1 = g_value_get_double(value); break; case PROP_A2: plot->a2 = g_value_get_double(value); break; case PROP_A3: plot->a3 = g_value_get_double(value); break; case PROP_XY_VISIBLE: plot->xy_visible = g_value_get_boolean(value); break; case PROP_YZ_VISIBLE: plot->yz_visible = g_value_get_boolean(value); break; case PROP_ZX_VISIBLE: plot->zx_visible = g_value_get_boolean(value); break; case PROP_COLOR_XY: plot->color_xy = *((GdkColor *)g_value_get_pointer(value)); break; case PROP_COLOR_YZ: plot->color_yz = *((GdkColor *)g_value_get_pointer(value)); break; case PROP_COLOR_ZX: plot->color_zx = *((GdkColor *)g_value_get_pointer(value)); break; case PROP_FRAME: plot->frame = *((GtkPlotLine *)g_value_get_pointer(value)); break; case PROP_CORNER: plot->corner = *((GtkPlotLine *)g_value_get_pointer(value)); break; case PROP_CORNER_VISIBLE: plot->corner_visible = g_value_get_boolean(value); break; case PROP_ZMIN: plot->zmin = g_value_get_double(value); break; case PROP_ZMAX: plot->zmax = g_value_get_double(value); break; case PROP_ZSCALE: plot->zscale = g_value_get_boolean(value); break; case PROP_TITLES_OFFSET: plot->titles_offset = g_value_get_int(value); break; case PROP_XFACTOR: plot->xfactor = g_value_get_double(value); break; case PROP_YFACTOR: plot->yfactor = g_value_get_double(value); break; case PROP_ZFACTOR: plot->zfactor = g_value_get_double(value); break; default: break; } } static void gtk_plot3d_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GtkPlot3D *plot; plot = GTK_PLOT3D (object); switch(prop_id){ case PROP_CENTER: g_value_set_pointer(value, &plot->center); break; case PROP_ORIGIN: g_value_set_pointer(value, &plot->origin); break; case PROP_A1: g_value_set_double(value, plot->a1); break; case PROP_A2: g_value_set_double(value, plot->a2); break; case PROP_A3: g_value_set_double(value, plot->a3); break; case PROP_XY_VISIBLE: g_value_set_boolean(value, plot->xy_visible); break; case PROP_YZ_VISIBLE: g_value_set_boolean(value, plot->yz_visible); break; case PROP_ZX_VISIBLE: g_value_set_boolean(value, plot->zx_visible); break; case PROP_COLOR_XY: g_value_set_pointer(value, &plot->color_xy); break; case PROP_COLOR_YZ: g_value_set_pointer(value, &plot->color_yz); break; case PROP_COLOR_ZX: g_value_set_pointer(value, &plot->color_zx); break; case PROP_FRAME: g_value_set_pointer(value, &plot->frame); break; case PROP_CORNER: g_value_set_pointer(value, &plot->corner); break; case PROP_CORNER_VISIBLE: g_value_set_boolean(value, plot->corner_visible); break; case PROP_ZMIN: g_value_set_double(value, plot->zmin); break; case PROP_ZMAX: g_value_set_double(value, plot->zmax); break; case PROP_ZSCALE: g_value_set_boolean(value, plot->zscale); break; case PROP_TITLES_OFFSET: g_value_set_int(value, plot->titles_offset); break; case PROP_XFACTOR: g_value_set_double(value, plot->xfactor); break; case PROP_YFACTOR: g_value_set_double(value, plot->yfactor); break; case PROP_ZFACTOR: g_value_set_double(value, plot->zfactor); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void gtk_plot3d_real_paint (GtkWidget *widget) { GtkPlot3D *plot; GtkPlotText *child_text; GdkPixmap *pixmap; GtkPlotPC *pc; GList *datasets; GList *text; gint width, height, size; gint xoffset, yoffset, xp, yp; gint origin; gdouble pz; GtkPlotVector e[8], o, v[8]; GtkPlotVector vx, vy, vz; gint i; if(!GTK_WIDGET_VISIBLE(widget)) return; plot = GTK_PLOT3D(widget); xoffset = GTK_PLOT(plot)->internal_allocation.x; yoffset = GTK_PLOT(plot)->internal_allocation.y; width = GTK_PLOT(plot)->internal_allocation.width; height = GTK_PLOT(plot)->internal_allocation.height; pixmap = GTK_PLOT(plot)->drawable; pc = GTK_PLOT(plot)->pc; gtk_plot_pc_gsave(pc); gtk_plot_pc_set_color(pc, >K_PLOT(plot)->background); if(!gtk_plot_is_transparent(GTK_PLOT(plot))) gtk_plot_pc_draw_rectangle (pc, TRUE, xoffset, yoffset, width , height); /* draw frame to guide the eyes*/ /* gdk_draw_rectangle (pixmap, widget->style->black_gc, FALSE, xoffset, yoffset, width , height); */ /* find origin */ xp = GTK_PLOT(plot)->internal_allocation.x; yp = GTK_PLOT(plot)->internal_allocation.y; size = MIN(width, height) / SQRT2; /* 8 vertices of the cube */ e[0].x = 0; e[0].y = 0; e[0].z = 0; e[1].x = 1; e[1].y = 0; e[1].z = 0; e[2].x = 1; e[2].y = 1; e[2].z = 0; e[3].x = 0; e[3].y = 1; e[3].z = 0; e[4].x = 0; e[4].y = 0; e[4].z = 1; e[5].x = 1; e[5].y = 0; e[5].z = 1; e[6].x = 1; e[6].y = 1; e[6].z = 1; e[7].x = 0; e[7].y = 1; e[7].z = 1; for(i = 0; i < 8; i++){ v[i].x = (1.0 - e[i].x) * plot->ax->ticks.min + e[i].x * plot->ax->ticks.max; v[i].y = (1.0 - e[i].y) * plot->ay->ticks.min + e[i].y * plot->ay->ticks.max; v[i].z = (1.0 - e[i].z) * plot->az->ticks.min + e[i].z * plot->az->ticks.max; } /* Origin for drawing the planes */ origin = 0; o.x = 0.0; o.y = 0.0; o.z = 0.0; for(i = 1; i < 8; i++){ pz = e[i].x * plot->e1.z + e[i].y * plot->e2.z + e[i].z * plot->e3.z ; if(pz > o.z){ o.z = pz; origin = i; } } plot->origin = v[origin]; plot->ax->direction.x = 1.0; plot->ax->direction.y = 0.0; plot->ax->direction.z = 0.0; plot->ay->direction.x = 0.0; plot->ay->direction.y = 1.0; plot->ay->direction.z = 0.0; plot->az->direction.x = 0.0; plot->az->direction.y = 0.0; plot->az->direction.z = 1.0; plot->ax->origin.x = 0.0; plot->ax->origin.y = v[origin].y; plot->ax->origin.z = v[origin].z; plot->ay->origin.y = 0.0; plot->ay->origin.x = v[origin].x; plot->ay->origin.z = v[origin].z; plot->az->origin.z = 0.0; plot->az->origin.x = v[origin].x; plot->az->origin.y = v[origin].y; /* Tick directions */ vx.x = plot->e1.x * (1. - 2. * e[origin].x); vx.y = plot->e1.y * (1. - 2. * e[origin].x); vx.z = plot->e1.z * (1. - 2. * e[origin].x); vy.x = plot->e2.x * (1. - 2. * e[origin].y); vy.y = plot->e2.y * (1. - 2. * e[origin].y); vy.z = plot->e2.z * (1. - 2. * e[origin].y); vz.x = plot->e3.x * (1. - 2. * e[origin].z); vz.y = plot->e3.y * (1. - 2. * e[origin].z); vz.z = plot->e3.z * (1. - 2. * e[origin].z); /* draw planes, ticks & grid lines */ gtk_plot_axis_ticks_recalc(plot->ax); gtk_plot_axis_ticks_recalc(plot->ay); gtk_plot_axis_ticks_recalc(plot->az); if(plot->xy_visible) { /* PLANES */ if(origin == 0 || origin == 1 || origin == 2 || origin == 3) gtk_plot3d_draw_plane(plot, v[0], v[1], v[2], v[3], plot->color_xy); if(origin == 4 || origin == 5 || origin == 6 || origin == 7) gtk_plot3d_draw_plane(plot, v[4], v[5], v[6], v[7], plot->color_xy); /* X AXIS */ plot->ax->major_mask = plot->xy.major_mask; plot->ax->minor_mask = plot->xy.minor_mask; plot->ax->label_mask = plot->xy.label_mask; plot->ax->title_visible = plot->xy.title_visible; o.x = 0.0; o.y = (1.0 - e[origin].y) * plot->ay->ticks.max + e[origin].y * plot->ay->ticks.min - plot->ax->origin.y; o.z = 0.0; gtk_plot3d_draw_grids(plot, plot->ax, o); gtk_plot3d_draw_axis(plot, plot->ax, vy, o); gtk_plot3d_draw_labels(plot, plot->ax, o); /* Y AXIS */ plot->ay->major_mask = plot->yx.major_mask; plot->ay->minor_mask = plot->yx.minor_mask; plot->ay->label_mask = plot->yx.label_mask; plot->ay->title_visible = plot->yx.title_visible; o.x = (1.0 - e[origin].x) * plot->ax->ticks.max + e[origin].x * plot->ax->ticks.min - plot->ay->origin.x; o.y = 0.0; o.z = 0.0; gtk_plot3d_draw_grids(plot, plot->ay, o); gtk_plot3d_draw_axis(plot, plot->ay, vx, o); gtk_plot3d_draw_labels(plot, plot->ay, o); } if(plot->yz_visible) { /* PLANES */ if(origin == 0 || origin == 3 || origin == 7 || origin == 4) gtk_plot3d_draw_plane(plot, v[0], v[3], v[7], v[4], plot->color_yz); if(origin == 1 || origin == 2 || origin == 6 || origin == 5) gtk_plot3d_draw_plane(plot, v[1], v[2], v[6], v[5], plot->color_yz); /* Y AXIS */ plot->ay->major_mask = plot->yz.major_mask; plot->ay->minor_mask = plot->yz.minor_mask; plot->ay->label_mask = plot->yz.label_mask; plot->ay->title_visible = plot->yz.title_visible; o.x = 0.0; o.y = 0.0; o.z = (1.0 - e[origin].z) * plot->az->ticks.max + e[origin].z * plot->az->ticks.min - plot->ay->origin.z; gtk_plot3d_draw_grids(plot, plot->ay, o); gtk_plot3d_draw_axis(plot, plot->ay, vz, o); gtk_plot3d_draw_labels(plot, plot->ay, o); /* Z AXIS */ plot->az->major_mask = plot->zy.major_mask; plot->az->minor_mask = plot->zy.minor_mask; plot->az->label_mask = plot->zy.label_mask; plot->az->title_visible = plot->zy.title_visible; o.x = 0.0; o.y = (1.0 - e[origin].y) * plot->ay->ticks.max + e[origin].y * plot->ay->ticks.min - plot->az->origin.y; o.z = 0.0; gtk_plot3d_draw_grids(plot, plot->az, o); gtk_plot3d_draw_axis(plot, plot->az, vy, o); gtk_plot3d_draw_labels(plot, plot->az, o); } if(plot->zx_visible) { /* PLANES */ if(origin == 0 || origin == 4 || origin == 5 || origin == 1) gtk_plot3d_draw_plane(plot, v[0], v[4], v[5], v[1], plot->color_zx); if(origin == 3 || origin == 7 || origin == 6 || origin == 2) gtk_plot3d_draw_plane(plot, v[3], v[7], v[6], v[2], plot->color_zx); /* Z AXIS */ plot->az->major_mask = plot->zx.major_mask; plot->az->minor_mask = plot->zx.minor_mask; plot->az->label_mask = plot->zx.label_mask; plot->az->title_visible = plot->zx.title_visible; o.x = (1.0 - e[origin].x) * plot->ax->ticks.max + e[origin].x * plot->ax->ticks.min - plot->az->origin.x; o.y = 0.0; o.z = 0.0; gtk_plot3d_draw_grids(plot, plot->az, o); gtk_plot3d_draw_axis(plot, plot->az, vx, o); gtk_plot3d_draw_labels(plot, plot->az, o); /* X AXIS */ plot->ax->major_mask = plot->xz.major_mask; plot->ax->minor_mask = plot->xz.minor_mask; plot->ax->label_mask = plot->xz.label_mask; plot->ax->title_visible = plot->xz.title_visible; o.x = 0.0; o.y = 0.0; o.z = (1.0 - e[origin].z) * plot->az->ticks.max + e[origin].z * plot->az->ticks.min - plot->ax->origin.z; gtk_plot3d_draw_grids(plot, plot->ax, o); gtk_plot3d_draw_axis(plot, plot->ax, vz, o); gtk_plot3d_draw_labels(plot, plot->ax, o); } datasets = GTK_PLOT(plot)->data_sets; while(datasets) { GtkPlotData *dataset; dataset = GTK_PLOT_DATA(datasets->data); gtk_plot_data_paint(dataset); datasets = datasets->next; } if(plot->corner_visible){ gdouble px0, py0, pz0; gdouble px, py, pz; gint corner; gint end[3]; corner = origin + 2; if(corner > 3) corner -= 4; end[0] = corner; corner += 4; if(corner > 7) corner -= 8; end[1] = corner + 1; if(end[1] == 8 || end[1] == 4) end[1] -= 4; end[2] = corner - 1; if(end[2] == -1 || end[2] == 3) end[2] += 4; gtk_plot3d_get_pixel(plot, v[corner].x, v[corner].y, v[corner].z, &px0, &py0, &pz0); for (i = 0; i < 3; i++){ gtk_plot3d_get_pixel(plot, v[end[i]].x, v[end[i]].y, v[end[i]].z, &px, &py, &pz); gtk_plot_draw_line(GTK_PLOT(plot), plot->corner, px0, py0, px, py); } } text = GTK_PLOT(plot)->text; while(text) { child_text = (GtkPlotText *) text->data; gtk_plot_draw_text(GTK_PLOT(plot), *child_text); text = text->next; } GTK_PLOT_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(plot)))->draw_legends(GTK_WIDGET(plot)); gtk_plot_pc_grestore(pc); } GtkWidget* gtk_plot3d_new (GdkDrawable *drawable) { GtkPlot3D *plot; plot = gtk_type_new (gtk_plot3d_get_type ()); gtk_plot3d_construct(GTK_PLOT3D(plot), drawable); return GTK_WIDGET (plot); } void gtk_plot3d_construct(GtkPlot3D *plot, GdkDrawable *drawable) { GTK_PLOT(plot)->drawable = drawable; } GtkWidget* gtk_plot3d_new_with_size (GdkDrawable *drawable, gdouble width, gdouble height) { GtkWidget *plot; plot = gtk_type_new (gtk_plot3d_get_type ()); gtk_plot3d_construct_with_size(GTK_PLOT3D(plot), drawable, width, height); return(plot); } void gtk_plot3d_construct_with_size(GtkPlot3D *plot, GdkDrawable *drawable, gdouble width, gdouble height) { gtk_plot3d_construct(plot, drawable); gtk_plot_resize (GTK_PLOT(plot), width, height); } static void gtk_plot3d_draw_plane(GtkPlot3D *plot, GtkPlotVector v1, GtkPlotVector v2, GtkPlotVector v3, GtkPlotVector v4, GdkColor background) { GtkWidget *widget; GdkPixmap *pixmap; GtkPlotPC *pc; GtkPlotVector v[4]; GtkPlotPoint p[4]; gdouble px, py, pz; gint i; widget = GTK_WIDGET(plot); if(!GTK_WIDGET_VISIBLE(plot)) return; pixmap = GTK_PLOT(plot)->drawable; pc = GTK_PLOT(plot)->pc; gtk_plot_pc_set_color(pc, &background); v[0] = v1; v[1] = v2; v[2] = v3; v[3] = v4; for(i = 0; i < 4; i++){ gtk_plot3d_get_pixel(plot, v[i].x, v[i].y, v[i].z, &px, &py, &pz); p[i].x = px; p[i].y = py; } gtk_plot_pc_draw_polygon(pc, TRUE, p, 4); gtk_plot_pc_set_color(pc, &plot->frame.color); gtk_plot_pc_set_lineattr(pc, plot->frame.line_width, plot->frame.line_style == GTK_PLOT_LINE_SOLID ? GDK_LINE_SOLID : GDK_LINE_ON_OFF_DASH, 0, 0); if(plot->frame.line_style != GTK_PLOT_LINE_NONE) gtk_plot_pc_draw_polygon(pc, FALSE, p, 4); } static void gtk_plot3d_draw_grids(GtkPlot3D *plot, GtkPlotAxis *axis, GtkPlotVector delta) { GtkWidget *widget; GtkPlotLine major_grid, minor_grid; gdouble xx; gdouble x1, x2, y1, y2; gint size, width, height; gdouble xp, yp, oz; gint ntick; widget = GTK_WIDGET(plot); xp = GTK_PLOT(plot)->internal_allocation.x; yp = GTK_PLOT(plot)->internal_allocation.y; width = GTK_PLOT(plot)->internal_allocation.width; height = GTK_PLOT(plot)->internal_allocation.height; size = MIN(width, height) / SQRT2; switch(axis->orientation){ case GTK_PLOT_AXIS_X: major_grid = GTK_PLOT(plot)->left->major_grid; minor_grid = GTK_PLOT(plot)->left->minor_grid; break; case GTK_PLOT_AXIS_Y: major_grid = GTK_PLOT(plot)->bottom->major_grid; minor_grid = GTK_PLOT(plot)->bottom->minor_grid; break; case GTK_PLOT_AXIS_Z: major_grid = GTK_PLOT(plot)->top->major_grid; minor_grid = GTK_PLOT(plot)->top->minor_grid; break; } if(axis->show_minor_grid) { for(ntick = 0; ntick < axis->ticks.nticks; ntick++){ if(!axis->ticks.values[ntick].minor) continue; if(axis->ticks.values[ntick].value >= axis->ticks.min){ xx = axis->ticks.values[ntick].value; gtk_plot3d_get_pixel(plot, axis->origin.x + axis->direction.x * xx, axis->origin.y + axis->direction.y * xx, axis->origin.z + axis->direction.z * xx, &x1, &y1, &oz); gtk_plot3d_get_pixel(plot, axis->origin.x + axis->direction.x * xx + delta.x, axis->origin.y + axis->direction.y * xx + delta.y, axis->origin.z + axis->direction.z * xx + delta.z, &x2, &y2, &oz); gtk_plot_draw_line(GTK_PLOT(plot), minor_grid, x1, y1, x2, y2); } } } if(axis->show_major_grid) { for(ntick = 0; ntick < axis->ticks.nticks; ntick++){ if(axis->ticks.values[ntick].minor) continue; if(axis->ticks.values[ntick].value > axis->ticks.min && axis->ticks.values[ntick].value < axis->ticks.max){ xx = axis->ticks.values[ntick].value; gtk_plot3d_get_pixel(plot, axis->origin.x + axis->direction.x * xx, axis->origin.y + axis->direction.y * xx, axis->origin.z + axis->direction.z * xx, &x1, &y1, &oz); gtk_plot3d_get_pixel(plot, axis->origin.x + axis->direction.x * xx + delta.x, axis->origin.y + axis->direction.y * xx + delta.y, axis->origin.z + axis->direction.z * xx + delta.z, &x2, &y2, &oz); gtk_plot_draw_line(GTK_PLOT(plot), major_grid, x1, y1, x2, y2); } } } } static void gtk_plot3d_draw_axis(GtkPlot3D *plot, GtkPlotAxis *axis, GtkPlotVector tick, GtkPlotVector delta) { GtkWidget *widget; GtkPlotPC *pc; gdouble xx; gint line_width; gint xp, yp, width, height; gint ntick; gdouble m; gdouble oz; gdouble x1, x2, y1, y2; gint size; gint ticks_length; widget = GTK_WIDGET(plot); pc = GTK_PLOT(plot)->pc; xp = GTK_PLOT(plot)->internal_allocation.x; yp = GTK_PLOT(plot)->internal_allocation.y; width = GTK_PLOT(plot)->internal_allocation.width; height = GTK_PLOT(plot)->internal_allocation.height; m = GTK_PLOT(plot)->magnification; size = MIN(width, height) / SQRT2; line_width = plot->frame.line_width; gtk_plot_pc_set_color(pc, &plot->frame.color); gtk_plot_pc_set_lineattr(pc, line_width, 0, 3, 0); /* gtk_plot_pc_draw_line(pc, x1, y1, x2, y2); */ gtk_plot_pc_set_lineattr(pc, axis->ticks_width, 0, 1, 0); for(ntick = 0; ntick < axis->ticks.nticks; ntick++){ xx = axis->ticks.values[ntick].value; if(!axis->ticks.values[ntick].minor){ ticks_length = axis->ticks_length; gtk_plot3d_get_pixel(plot, axis->origin.x + axis->direction.x * xx + delta.x, axis->origin.y + axis->direction.y * xx + delta.y, axis->origin.z + axis->direction.z * xx + delta.z, &x1, &y1, &oz); if(xx >= axis->ticks.min){ x2 = x1 + m * ticks_length * tick.x; y2 = y1 + m * ticks_length * tick.y; if(axis->major_mask == GTK_PLOT_TICKS_OUT) gtk_plot_pc_draw_line(pc, x1, y1, x2, y2); x2 = x1 - m * axis->ticks_length * tick.x; y2 = y1 - m * axis->ticks_length * tick.y; if(axis->major_mask == GTK_PLOT_TICKS_IN) gtk_plot_pc_draw_line(pc, x1, y1, x2, y2); } } else { ticks_length = axis->ticks_length / 2.; gtk_plot3d_get_pixel(plot, axis->origin.x + axis->direction.x * xx + delta.x, axis->origin.y + axis->direction.y * xx + delta.y, axis->origin.z + axis->direction.z * xx + delta.z, &x1, &y1, &oz); if(xx >= axis->ticks.min){ x2 = x1 + m * ticks_length * tick.x; y2 = y1 + m * ticks_length * tick.y; if(axis->minor_mask == GTK_PLOT_TICKS_OUT) gtk_plot_pc_draw_line(pc, x1, y1, x2, y2); x2 = x1 - m * axis->ticks_length * tick.x; y2 = y1 - m * axis->ticks_length * tick.y; if(axis->minor_mask == GTK_PLOT_TICKS_IN) gtk_plot_pc_draw_line(pc, x1, y1, x2, y2); } } } } static void gtk_plot3d_draw_labels(GtkPlot3D *plot, GtkPlotAxis *axis, GtkPlotVector delta) { GtkWidget *widget; GtkPlotPC *pc; GtkPlotText title, tick; gchar label[100]; gdouble tick_value; gdouble xx; gint text_height, text_width, ascent, descent; gint xp, yp, width, height; gint ntick; gdouble m; gdouble size, ox, oy, oz; gdouble y; GtkPlotVector ticks_direction, center, aux; gdouble proj; gboolean veto = FALSE; widget = GTK_WIDGET(plot); pc = GTK_PLOT(plot)->pc; xp = GTK_PLOT(plot)->internal_allocation.x; yp = GTK_PLOT(plot)->internal_allocation.y; width = GTK_PLOT(plot)->internal_allocation.width; height = GTK_PLOT(plot)->internal_allocation.height; size = MIN(width, height) / SQRT2; m = GTK_PLOT(plot)->magnification; gtk_plot_pc_set_color (pc, &axis->labels_attr.fg); gtk_plot_text_get_size("0", 0, axis->labels_attr.font, roundint(axis->labels_attr.height * m), &text_width, &text_height, &ascent, &descent); switch(axis->labels_attr.angle){ case 0: y += text_height / 2.; break; case 90: break; case 180: y -= text_height / 2.; break; case 270: break; } tick = axis->labels_attr; center.x = (plot->ax->ticks.max + plot->ax->ticks.min) / 2.0; center.y = (plot->ay->ticks.max + plot->ay->ticks.min) / 2.0; center.z = (plot->az->ticks.max + plot->az->ticks.min) / 2.0; ticks_direction.x = axis->origin.x + delta.x - center.x; ticks_direction.y = axis->origin.y + delta.y - center.y; ticks_direction.z = axis->origin.z + delta.z - center.z; proj = ticks_direction.x * axis->direction.x + ticks_direction.y * axis->direction.y + ticks_direction.z * axis->direction.z; ticks_direction.x -= proj * axis->direction.x; ticks_direction.y -= proj * axis->direction.y; ticks_direction.z -= proj * axis->direction.z; proj = sqrt(ticks_direction.x * ticks_direction.x + ticks_direction.y * ticks_direction.y + ticks_direction.z * ticks_direction.z); ticks_direction.x /= proj; ticks_direction.y /= proj; ticks_direction.z /= proj; aux = ticks_direction; ticks_direction.x = aux.x*plot->e1.x + aux.y*plot->e2.x + aux.z*plot->e3.x; ticks_direction.y = aux.x*plot->e1.y + aux.y*plot->e2.y + aux.z*plot->e3.y; ticks_direction.z = aux.x*plot->e1.z + aux.y*plot->e2.z + aux.z*plot->e3.z; for(ntick = 0; ntick < axis->ticks.nticks; ntick++){ if(axis->ticks.values[ntick].minor) continue; xx = axis->ticks.values[ntick].value; gtk_plot3d_get_pixel(plot, axis->origin.x + axis->direction.x * xx + delta.x, axis->origin.y + axis->direction.y * xx + delta.y, axis->origin.z + axis->direction.z * xx + delta.z, &ox, &oy, &oz); tick.x = ox + axis->labels_offset * ticks_direction.x; tick.y = oy + axis->labels_offset * ticks_direction.y; tick_value = axis->ticks.values[ntick].value; if(tick_value >= axis->ticks.min-1.e-9){ if(!axis->custom_labels){ gtk_plot_axis_parse_label(axis, tick_value, axis->label_precision, axis->label_style, label); } else { gtk_signal_emit_by_name(GTK_OBJECT(axis), "tick_label", &tick_value, label, &veto); if(!veto) gtk_plot_axis_parse_label(axis, tick_value, axis->label_precision, axis->label_style, label); } tick.text = label; if(axis->label_mask == GTK_PLOT_LABEL_OUT){ tick.x = (gdouble)tick.x / (gdouble)widget->allocation.width; tick.y = (gdouble)tick.y / (gdouble)widget->allocation.height; gtk_plot_draw_text(GTK_PLOT(plot), tick); } } } if(axis->title_visible && axis->title.text) { title = axis->title; gtk_plot3d_get_pixel(plot, axis->origin.x + center.x * axis->direction.x + delta.x, axis->origin.y + center.y * axis->direction.y + delta.y, axis->origin.z + center.z * axis->direction.z + delta.z, &ox, &oy, &oz); title.x = ox + plot->titles_offset * ticks_direction.x; title.y = oy + plot->titles_offset * ticks_direction.y; title.x = title.x / (gdouble)widget->allocation.width; title.y = title.y / (gdouble)widget->allocation.height; gtk_plot_draw_text(GTK_PLOT(plot), title); } } gdouble get_clean_tick_size(gdouble delta) { gint magnitude; delta/= 5.0; if (delta<0.0) delta*= -1.0; magnitude= (gint)(floor(log10(delta))); return ceil(delta/pow(10,magnitude))*pow(10,magnitude); } /****************************************** ******************************************/ void gtk_plot3d_autoscale(GtkPlot3D *plot) { GList *datasets; gdouble xmin, xmax, ymin, ymax, zmin, zmax; gint px, py, pz; gint first=1; if(!GTK_PLOT(plot)->data_sets) return; xmin = GTK_PLOT(plot)->bottom->ticks.max; xmax = GTK_PLOT(plot)->bottom->ticks.min; ymin = GTK_PLOT(plot)->left->ticks.max; ymax = GTK_PLOT(plot)->left->ticks.min; zmin = GTK_PLOT(plot)->top->ticks.max; zmax = GTK_PLOT(plot)->top->ticks.min; datasets = GTK_PLOT(plot)->data_sets; while(datasets){ GtkPlotData *data; gint i; data = GTK_PLOT_DATA(datasets->data); if(!data->is_function){ if(GTK_IS_PLOT_SURFACE(data)) if(GTK_PLOT_SURFACE(data)->use_amplitud) gtk_plot_data_gradient_autoscale_a(data); else gtk_plot_data_gradient_autoscale_z(data); else gtk_plot_data_gradient_autoscale_a(data); for (i = 0; i < data->num_points; i++){ gdouble x, y, z, a, dx, dy, dz, da; gchar *label; gboolean error; gtk_plot_data_get_point(data, i, &x, &y, &z, &a, &dx, &dy, &dz, &da, &label, &error); if (first) { first = 0; xmin = xmax = x; ymin = ymax = y; zmin = zmax = z; } else { xmin = MIN(xmin, x); xmax = MAX(xmax, x); ymin = MIN(ymin, y); ymax = MAX(ymax, y); zmin = MIN(zmin, z); zmax = MAX(zmax, z); } } } datasets = datasets->next; } gtk_plot_axis_ticks_autoscale(plot->ax, xmin, xmax, &px); gtk_plot_axis_ticks_autoscale(plot->ay, ymin, ymax, &py); gtk_plot_axis_ticks_autoscale(plot->az, zmin, zmax, &pz); plot->ax->label_precision = px; plot->ay->label_precision = py; plot->az->label_precision = pz; GTK_PLOT(plot)->xmin = plot->ax->ticks.min; GTK_PLOT(plot)->xmax = plot->ax->ticks.max; GTK_PLOT(plot)->ymin = plot->ay->ticks.min; GTK_PLOT(plot)->ymax = plot->ay->ticks.max; plot->zmin = plot->az->ticks.min; plot->zmax = plot->az->ticks.max; gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", TRUE); gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed"); } void gtk_plot3d_rotate(GtkPlot3D *plot, gdouble a1, gdouble a2, gdouble a3) { gtk_plot3d_rotate_vector(plot, &plot->e1, a1, a2, a3); gtk_plot3d_rotate_vector(plot, &plot->e2, a1, a2, a3); gtk_plot3d_rotate_vector(plot, &plot->e3, a1, a2, a3); gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE); gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed"); } void gtk_plot3d_rotate_vector(GtkPlot3D *plot, GtkPlotVector *vector, gdouble a1, gdouble a2, gdouble a3) { GtkPlotVector v; gdouble cos1, sin1; gdouble cos2, sin2; gdouble cos3, sin3; if(a1 < 0) a1 = 360 + a1; if(a2 < 0) a2 = 360 + a2; if(a3 < 0) a3 = 360 + a3; cos1 = plot->ncos[(int)a1]; sin1 = plot->nsin[(int)a1]; cos2 = plot->ncos[(int)a2]; sin2 = plot->nsin[(int)a2]; cos3 = plot->ncos[(int)a3]; sin3 = plot->nsin[(int)a3]; v.y = vector->y*cos1 - vector->z*sin1; v.z = vector->z*cos1 + vector->y*sin1; vector->y = v.y; vector->z = v.z; v.z = vector->z*cos2 - vector->x*sin2; v.x = vector->x*cos2 + vector->z*sin2; vector->x = v.x; vector->z = v.z; v.x = vector->x*cos3 - vector->y*sin3; v.y = vector->y*cos3 + vector->x*sin3; vector->x = v.x; vector->y = v.y; } void gtk_plot3d_get_pixel(GtkPlot3D *plot, gdouble x, gdouble y, gdouble z, gdouble *px, gdouble *py, gdouble *pz) { GTK_PLOT3D_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(plot)))->get_pixel(GTK_WIDGET(plot), x, y, z, px, py, pz); } static void gtk_plot3d_real_get_pixel(GtkWidget *widget, gdouble x, gdouble y, gdouble z, gdouble *px, gdouble *py, gdouble *pz) { GtkPlot3D *plot; GtkPlotVector e1, e2, e3, center; gint xp, yp, width, height, size; gdouble rx, ry, rz; gdouble cx, cy, cz; plot = GTK_PLOT3D(widget); xp = GTK_PLOT(plot)->internal_allocation.x; yp = GTK_PLOT(plot)->internal_allocation.y; width = GTK_PLOT(plot)->internal_allocation.width; height =GTK_PLOT(plot)->internal_allocation.height; size = MIN(width, height) / SQRT2; e1 = plot->e1; e2 = plot->e2; e3 = plot->e3; ry = gtk_plot_axis_ticks_transform(plot->ay, y); rx = gtk_plot_axis_ticks_transform(plot->ax, x); rz = gtk_plot_axis_ticks_transform(plot->az, z); center = plot->center; cx = -(center.x * e1.x + center.y * e2.x + center.z * e3.x); cy = -(center.x * e1.y + center.y * e2.y + center.z * e3.y); cz = -(center.x * e1.z + center.y * e2.z + center.z * e3.z); *px = xp + width / 2.; *py = yp + height / 2.; *pz = 0.0; *px += (cx + rx * e1.x + ry * e2.x + rz * e3.x) * size; *py += (cy + rx * e1.y + ry * e2.y + rz * e3.y) * size; *pz += (cz + rx * e1.z + ry * e2.z + rz * e3.z) * size; } /***********************************************************/ /*********************************************************** * gtk_plot3d_set_xrange * gtk_plot3d_set_yrange * gtk_plot3d_set_zrange * gtk_plot3d_set_xfactor * gtk_plot3d_set_yfactor * gtk_plot3d_set_zfactor * gtk_plot3d_get_xfactor * gtk_plot3d_get_yfactor * gtk_plot3d_get_zfactor ***********************************************************/ void gtk_plot3d_set_xrange(GtkPlot3D *plot, gdouble min, gdouble max) { if(min > max) return; GTK_PLOT(plot)->xmin = min; GTK_PLOT(plot)->xmax = max; plot->ax->ticks.min = min; plot->ax->ticks.max = max; gtk_plot_axis_ticks_recalc(plot->ax); gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", TRUE); gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed"); } void gtk_plot3d_set_yrange(GtkPlot3D *plot, gdouble min, gdouble max) { if(min > max) return; GTK_PLOT(plot)->ymin = min; GTK_PLOT(plot)->ymax = max; plot->ay->ticks.min = min; plot->ay->ticks.max = max; gtk_plot_axis_ticks_recalc(plot->ay); gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", TRUE); gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed"); } void gtk_plot3d_set_zrange(GtkPlot3D *plot, gdouble min, gdouble max) { if(min > max) return; plot->zmin = min; plot->zmax = max; plot->az->ticks.min = min; plot->az->ticks.max = max; gtk_plot_axis_ticks_recalc(plot->az); gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", TRUE); gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed"); } void gtk_plot3d_set_xfactor(GtkPlot3D *plot, gdouble xfactor) { if(xfactor <= 0.0) return; plot->e1.x /= plot->xfactor; plot->e1.y /= plot->xfactor; plot->e1.z /= plot->xfactor; plot->xfactor = xfactor; plot->e1.x *= plot->xfactor; plot->e1.y *= plot->xfactor; plot->e1.z *= plot->xfactor; plot->ax->direction = plot->e1; gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE); gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed"); } void gtk_plot3d_set_yfactor(GtkPlot3D *plot, gdouble yfactor) { if(yfactor <= 0.0) return; plot->e2.x /= plot->yfactor; plot->e2.y /= plot->yfactor; plot->e2.z /= plot->yfactor; plot->yfactor = yfactor; plot->e2.x *= plot->yfactor; plot->e2.y *= plot->yfactor; plot->e2.z *= plot->yfactor; plot->ay->direction = plot->e1; gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE); gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed"); } void gtk_plot3d_set_zfactor(GtkPlot3D *plot, gdouble zfactor) { if(zfactor <= 0.0) return; plot->e3.x /= plot->zfactor; plot->e3.y /= plot->zfactor; plot->e3.z /= plot->zfactor; plot->zfactor = zfactor; plot->e3.x *= plot->zfactor; plot->e3.y *= plot->zfactor; plot->e3.z *= plot->zfactor; plot->az->direction = plot->e1; gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE); gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed"); } gdouble gtk_plot3d_get_xfactor(GtkPlot3D *plot) { return (plot->xfactor); } gdouble gtk_plot3d_get_yfactor(GtkPlot3D *plot) { return (plot->yfactor); } gdouble gtk_plot3d_get_zfactor(GtkPlot3D *plot) { return (plot->zfactor); } /*********************************************************** * gtk_plot3d_plane_set_color * gtk_plot3d_plane_set_visible * gtk_plot3d_plane_visible ***********************************************************/ void gtk_plot3d_plane_set_color (GtkPlot3D *plot, GtkPlotPlane plane, const GdkColor *color) { switch(plane){ case GTK_PLOT_PLANE_XY: plot->color_xy = *color; break; case GTK_PLOT_PLANE_YZ: plot->color_yz = *color; break; case GTK_PLOT_PLANE_ZX: plot->color_zx = *color; break; default: break; } } void gtk_plot3d_plane_set_visible (GtkPlot3D *plot, GtkPlotPlane plane, gboolean visible) { switch(plane){ case GTK_PLOT_PLANE_XY: plot->xy_visible = visible; break; case GTK_PLOT_PLANE_YZ: plot->yz_visible = visible; break; case GTK_PLOT_PLANE_ZX: plot->zx_visible = visible; break; default: break; } } gboolean gtk_plot3d_plane_visible (GtkPlot3D *plot, GtkPlotPlane plane) { gboolean visible = FALSE; switch(plane){ case GTK_PLOT_PLANE_XY: visible = plot->xy_visible; break; case GTK_PLOT_PLANE_YZ: visible = plot->yz_visible; break; case GTK_PLOT_PLANE_ZX: visible = plot->zx_visible; break; default: break; } return visible; } /*********************************************************** * gtk_plot3d_corner_set_visible * gtk_plot3d_corner_visible * gtk_plot3d_corner_set_attributes * gtk_plot3d_corner_get_attributes * gtk_plot3d_frame_set_attributes * gtk_plot3d_frame_get_attributes * gtk_plot3d_show_labels * gtk_plot3d_show_title * gtk_plot3d_hide_title * gtk_plot3d_show_major_ticks * gtk_plot3d_show_minor_ticks * gtk_plot3d_set_ticks * gtk_plot3d_set_major_ticks * gtk_plot3d_set_minor_ticks * gtk_plot3d_set_ticks_length * gtk_plot3d_set_ticks_width * gtk_plot3d_show_ticks * gtk_plot3d_set_titles_offset * gtk_plot3d_get_titles_offset ***********************************************************/ void gtk_plot3d_corner_set_visible(GtkPlot3D *plot, gboolean visible) { plot->corner_visible = visible; } gboolean gtk_plot3d_corner_visible(GtkPlot3D *plot) { return (plot->corner_visible); } void gtk_plot3d_corner_set_attributes (GtkPlot3D *plot, GtkPlotLineStyle style, gfloat width, const GdkColor *color) { plot->corner.line_style = style; plot->corner.line_width = width; if(color) plot->corner.color = *color; } void gtk_plot3d_corner_get_attributes (GtkPlot3D *plot, GtkPlotLineStyle *style, gfloat *width, GdkColor *color) { *style = plot->corner.line_style; *width = plot->corner.line_width; *color = plot->corner.color; } void gtk_plot3d_frame_set_attributes (GtkPlot3D *plot, GtkPlotLineStyle style, gfloat width, const GdkColor *color) { plot->frame.line_style = style; plot->frame.line_width = width; if(color) plot->frame.color = *color; } void gtk_plot3d_frame_get_attributes (GtkPlot3D *plot, GtkPlotLineStyle *style, gfloat *width, GdkColor *color) { *style = plot->frame.line_style; *width = plot->frame.line_width; *color = plot->frame.color; } GtkPlotAxis * gtk_plot3d_get_axis(GtkPlot3D *plot, GtkPlotOrientation orientation) { GtkPlotAxis *axis = NULL; switch(orientation){ case GTK_PLOT_AXIS_X: axis = plot->ax; break; case GTK_PLOT_AXIS_Y: axis = plot->ay; break; case GTK_PLOT_AXIS_Z: axis = plot->az; break; default: axis = NULL; break; } return axis; } GtkPlotAxis * gtk_plot3d_get_side(GtkPlot3D *plot, GtkPlotSide side) { GtkPlotAxis *axis = NULL; switch(side){ case GTK_PLOT_SIDE_XY: axis = &plot->xy; break; case GTK_PLOT_SIDE_XZ: axis = &plot->xz; break; case GTK_PLOT_SIDE_YX: axis = &plot->yx; break; case GTK_PLOT_SIDE_YZ: axis = &plot->yz; break; case GTK_PLOT_SIDE_ZX: axis = &plot->zx; break; case GTK_PLOT_SIDE_ZY: axis = &plot->zy; break; default: axis = NULL; } return axis; } void gtk_plot3d_show_labels (GtkPlot3D *plot, GtkPlotSide side, gint label_mask) { GtkPlotAxis *axis; axis = gtk_plot3d_get_side(plot, side); axis->label_mask = label_mask; } void gtk_plot3d_show_title (GtkPlot3D *plot, GtkPlotSide side) { GtkPlotAxis *axis; axis = gtk_plot3d_get_side(plot, side); axis->title_visible = TRUE; } void gtk_plot3d_hide_title (GtkPlot3D *plot, GtkPlotSide side) { GtkPlotAxis *axis; axis = gtk_plot3d_get_side(plot, side); axis->title_visible = FALSE; } void gtk_plot3d_show_major_ticks (GtkPlot3D *plot, GtkPlotSide side, gint ticks_mask) { GtkPlotAxis *axis; axis = gtk_plot3d_get_side(plot, side); axis->major_mask = ticks_mask; } void gtk_plot3d_show_minor_ticks(GtkPlot3D *plot, GtkPlotSide side, gint ticks_mask) { GtkPlotAxis *axis; axis = gtk_plot3d_get_side(plot, side); axis->minor_mask = ticks_mask; } void gtk_plot3d_set_ticks (GtkPlot3D *plot, GtkPlotOrientation direction, gdouble major_step, gint nminor) { GtkPlotAxis *axis; axis = gtk_plot3d_get_axis(plot, direction); axis->ticks.step = major_step; axis->ticks.nminor = nminor; } void gtk_plot3d_set_major_ticks (GtkPlot3D *plot, GtkPlotOrientation direction, gdouble major_step) { GtkPlotAxis *axis; axis = gtk_plot3d_get_axis(plot, direction); axis->ticks.step = major_step; } void gtk_plot3d_set_minor_ticks (GtkPlot3D *plot, GtkPlotOrientation direction, gint nminor) { GtkPlotAxis *axis; axis = gtk_plot3d_get_axis(plot, direction); axis->ticks.nminor = nminor; } void gtk_plot3d_set_ticks_length (GtkPlot3D *plot, GtkPlotOrientation direction, gint length) { GtkPlotAxis *axis; axis = gtk_plot3d_get_axis(plot, direction); axis->ticks_length = length; } void gtk_plot3d_set_ticks_width (GtkPlot3D *plot, GtkPlotOrientation direction, gfloat width) { GtkPlotAxis *axis; axis = gtk_plot3d_get_axis(plot, direction); axis->ticks_width = width; } void gtk_plot3d_show_ticks (GtkPlot3D *plot, GtkPlotSide side, gint major_mask, gint minor_mask) { GtkPlotAxis *axis; axis = gtk_plot3d_get_side(plot, side); axis->major_mask = major_mask; axis->minor_mask = minor_mask; } void gtk_plot3d_set_titles_offset (GtkPlot3D *plot, gint offset) { plot->titles_offset = offset; } gint gtk_plot3d_get_titles_offset (GtkPlot3D *plot) { return (plot->titles_offset); } /*********************************************************** * gtk_plot3d_major_grids_set_visible * gtk_plot3d_major_grids_visible * gtk_plot3d_minor_grids_set_visible * gtk_plot3d_minor_grids_visible * gtk_plot3d_major_grids_set_attributes * gtk_plot3d_minor_grids_set_attributes * gtk_plot3d_major_grids_get_attributes * gtk_plot3d_minor_grids_get_attributes ***********************************************************/ void gtk_plot3d_major_grids_set_visible (GtkPlot3D *plot, gboolean x, gboolean y, gboolean z) { plot->ax->show_major_grid = x; plot->ay->show_major_grid = y; plot->az->show_major_grid = z; } void gtk_plot3d_minor_grids_set_visible (GtkPlot3D *plot, gboolean x, gboolean y, gboolean z) { plot->ax->show_minor_grid = x; plot->ay->show_minor_grid = y; plot->az->show_minor_grid = z; } void gtk_plot3d_major_grids_visible (GtkPlot3D *plot, gboolean *x, gboolean *y, gboolean *z) { *x = plot->ax->show_major_grid; *y = plot->ay->show_major_grid; *z = plot->az->show_major_grid; } void gtk_plot3d_minor_grids_visible (GtkPlot3D *plot, gboolean *x, gboolean *y, gboolean *z) { *x = plot->ax->show_minor_grid; *y = plot->ay->show_minor_grid; *z = plot->az->show_minor_grid; } void gtk_plot3d_major_zgrid_set_attributes (GtkPlot3D *plot, GtkPlotLineStyle style, gfloat width, const GdkColor *color) { plot->az->major_grid.line_style = style; plot->az->major_grid.line_width = width; if(color) plot->az->major_grid.color = *color; } void gtk_plot3d_minor_zgrid_set_attributes (GtkPlot3D *plot, GtkPlotLineStyle style, gfloat width, const GdkColor *color) { plot->az->minor_grid.line_style = style; plot->az->minor_grid.line_width = width; if(color) plot->az->minor_grid.color = *color; } void gtk_plot3d_major_zgrid_get_attributes (GtkPlot3D *plot, GtkPlotLineStyle *style, gfloat *width, GdkColor *color) { *style = plot->az->major_grid.line_style; *width = plot->az->major_grid.line_width; *color = plot->az->major_grid.color; } void gtk_plot3d_minor_zgrid_get_attributes (GtkPlot3D *plot, GtkPlotLineStyle *style, gfloat *width, GdkColor *color) { *style = plot->az->minor_grid.line_style; *width = plot->az->minor_grid.line_width; *color = plot->az->minor_grid.color; } /******************************************* * gtk_plot3d_reset_angles * gtk_plot3d_rotate_x * gtk_plot3d_rotate_y * gtk_plot3d_rotate_z *******************************************/ void gtk_plot3d_reset_angles(GtkPlot3D *plot) { plot->e1.x = plot->xfactor; plot->e1.y = 0.; plot->e1.z = 0.; plot->e2.x = 0.; plot->e2.y = -plot->yfactor; plot->e2.z = 0.; plot->e3.x = 0.; plot->e3.y = 0.; plot->e3.z = -plot->zfactor; gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE); gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed"); } void gtk_plot3d_rotate_x(GtkPlot3D *plot, gdouble angle) { GtkPlotVector vector, aux, e1, e2, e3; gdouble c, s; angle = 360 - angle; c = plot->ncos[(int)angle]; s = plot->nsin[(int)angle]; e1 = plot->e1; e2 = plot->e2; e3 = plot->e3; vector.x = 0.0; vector.y = 1.0; vector.z = 0.0; aux = vector; aux.y = vector.y*c - vector.z*s; aux.z = vector.z*c + vector.y*s; plot->e2.x = aux.x * e1.x / plot->xfactor + aux.y * e2.x / plot->yfactor + aux.z * e3.x / plot->zfactor ; plot->e2.y = aux.x * e1.y / plot->xfactor + aux.y * e2.y / plot->yfactor + aux.z * e3.y / plot->zfactor ; plot->e2.z = aux.x * e1.z / plot->xfactor + aux.y * e2.z / plot->yfactor + aux.z * e3.z / plot->zfactor ; vector.x = 0.0; vector.y = 0.0; vector.z = 1.0; aux = vector; aux.y = vector.y*c - vector.z*s; aux.z = vector.z*c + vector.y*s; plot->e3.x = aux.x * e1.x / plot->xfactor + aux.y * e2.x / plot->yfactor + aux.z * e3.x / plot->zfactor ; plot->e3.y = aux.x * e1.y / plot->xfactor + aux.y * e2.y / plot->yfactor + aux.z * e3.y / plot->zfactor ; plot->e3.z = aux.x * e1.z / plot->xfactor + aux.y * e2.z / plot->yfactor + aux.z * e3.z / plot->zfactor ; plot->e1.x *= plot->xfactor; plot->e1.y *= plot->xfactor; plot->e1.z *= plot->xfactor; plot->e2.x *= plot->yfactor; plot->e2.y *= plot->yfactor; plot->e2.z *= plot->yfactor; plot->e3.x *= plot->zfactor; plot->e3.y *= plot->zfactor; plot->e3.z *= plot->zfactor; gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE); gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed"); } void gtk_plot3d_rotate_y(GtkPlot3D *plot, gdouble angle) { GtkPlotVector vector, aux, e1, e2, e3; gdouble c, s; angle = 360 - angle; c = plot->ncos[(int)angle]; s = plot->nsin[(int)angle]; e1 = plot->e1; e2 = plot->e2; e3 = plot->e3; vector.x = 1.0; vector.y = 0.0; vector.z = 0.0; aux = vector; aux.z = vector.z*c - vector.x*s; aux.x = vector.x*c + vector.z*s; plot->e1.x = aux.x * e1.x / plot->xfactor + aux.y * e2.x / plot->yfactor + aux.z * e3.x / plot->zfactor ; plot->e1.y = aux.x * e1.y / plot->xfactor + aux.y * e2.y / plot->yfactor + aux.z * e3.y / plot->zfactor ; plot->e1.z = aux.x * e1.z / plot->xfactor + aux.y * e2.z / plot->yfactor + aux.z * e3.z / plot->zfactor ; vector.x = 0.0; vector.y = 0.0; vector.z = 1.0; aux = vector; aux.z = vector.z*c - vector.x*s; aux.x = vector.x*c + vector.z*s; plot->e3.x = aux.x * e1.x / plot->xfactor + aux.y * e2.x / plot->yfactor + aux.z * e3.x / plot->zfactor ; plot->e3.y = aux.x * e1.y / plot->xfactor + aux.y * e2.y / plot->yfactor + aux.z * e3.y / plot->zfactor ; plot->e3.z = aux.x * e1.z / plot->xfactor + aux.y * e2.z / plot->yfactor + aux.z * e3.z / plot->zfactor ; plot->e1.x *= plot->xfactor; plot->e1.y *= plot->xfactor; plot->e1.z *= plot->xfactor; plot->e2.x *= plot->yfactor; plot->e2.y *= plot->yfactor; plot->e2.z *= plot->yfactor; plot->e3.x *= plot->zfactor; plot->e3.y *= plot->zfactor; plot->e3.z *= plot->zfactor; gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE); gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed"); } void gtk_plot3d_rotate_z(GtkPlot3D *plot, gdouble angle) { GtkPlotVector vector, aux, e1, e2, e3; gdouble c, s; angle = 360 - angle; c = plot->ncos[(int)angle]; s = plot->nsin[(int)angle]; e1 = plot->e1; e2 = plot->e2; e3 = plot->e3; vector.x = 1.0; vector.y = 0.0; vector.z = 0.0; aux = vector; aux.x = vector.x*c - vector.y*s; aux.y = vector.y*c + vector.x*s; plot->e1.x = aux.x * e1.x / plot->xfactor + aux.y * e2.x / plot->yfactor + aux.z * e3.x / plot->zfactor ; plot->e1.y = aux.x * e1.y / plot->xfactor + aux.y * e2.y / plot->yfactor + aux.z * e3.y / plot->zfactor ; plot->e1.z = aux.x * e1.z / plot->xfactor + aux.y * e2.z / plot->yfactor + aux.z * e3.z / plot->zfactor ; vector.x = 0.0; vector.y = 1.0; vector.z = 0.0; aux = vector; aux.x = vector.x*c - vector.y*s; aux.y = vector.y*c + vector.x*s; plot->e2.x = aux.x * e1.x / plot->xfactor + aux.y * e2.x / plot->yfactor + aux.z * e3.x / plot->zfactor ; plot->e2.y = aux.x * e1.y / plot->xfactor + aux.y * e2.y / plot->yfactor + aux.z * e3.y / plot->zfactor ; plot->e2.z = aux.x * e1.z / plot->xfactor + aux.y * e2.z / plot->yfactor + aux.z * e3.z / plot->zfactor ; plot->e1.x *= plot->xfactor; plot->e1.y *= plot->xfactor; plot->e1.z *= plot->xfactor; plot->e2.x *= plot->yfactor; plot->e2.y *= plot->yfactor; plot->e2.z *= plot->yfactor; plot->e3.x *= plot->zfactor; plot->e3.y *= plot->zfactor; plot->e3.z *= plot->zfactor; gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE); gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed"); } void gtk_plot3d_set_scale (GtkPlot3D *plot, GtkPlotOrientation axis, GtkPlotScale scale) { GtkPlotAxis *ax; ax = gtk_plot3d_get_axis(plot, axis); ax->ticks.scale = scale; } GtkPlotScale gtk_plot3d_get_scale (GtkPlot3D *plot, GtkPlotOrientation axis) { GtkPlotAxis *ax; ax = gtk_plot3d_get_axis(plot, axis); return(ax->ticks.scale); }