1 /* gtkplot3d - 3d scientific plots widget for gtk+
2  * Copyright 1999-2001  Adrian E. Feiguin <feiguin@ifir.edu.ar>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <math.h>
24 #include <gtk/gtk.h>
25 #include "gtkplot.h"
26 #include "gtkplotdata.h"
27 #include "gtkplotsurface.h"
28 #include "gtkplot3d.h"
29 #include "gtkpsfont.h"
30 
31 #define DEFAULT_WIDTH 420
32 #define DEFAULT_HEIGHT 340
33 #define DEFAULT_FONT_HEIGHT 10
34 
35 #ifndef PI
36 #define PI 3.141592653589793238462643383279502884197
37 #endif
38 #ifndef SQRT2
39 #define SQRT2 1.41421356237309504880168872420969807856967
40 #endif
41 
42 #define P_(string) string
43 
44 enum
45 {
46   PROP_0,
47   PROP_CENTER,
48   PROP_ORIGIN,
49   PROP_A1,
50   PROP_A2,
51   PROP_A3,
52   PROP_XY_VISIBLE,
53   PROP_YZ_VISIBLE,
54   PROP_ZX_VISIBLE,
55   PROP_COLOR_XY,
56   PROP_COLOR_YZ,
57   PROP_COLOR_ZX,
58   PROP_FRAME,
59   PROP_CORNER,
60   PROP_CORNER_VISIBLE,
61   PROP_ZMIN,
62   PROP_ZMAX,
63   PROP_ZSCALE,
64   PROP_TITLES_OFFSET,
65   PROP_XFACTOR,
66   PROP_YFACTOR,
67   PROP_ZFACTOR,
68 };
69 
70 static void gtk_plot3d_class_init 		(GtkPlot3DClass *klass);
71 static void gtk_plot3d_init 			(GtkPlot3D *plot);
72 static void gtk_plot3d_destroy 			(GtkObject *object);
73 static void gtk_plot3d_set_property             (GObject *object,
74 			                         guint prop_id,
75 			                         const GValue *value,
76 			                         GParamSpec *pspec);
77 static void gtk_plot3d_get_property             (GObject *object,
78 			                         guint prop_id,
79 			                         GValue *value,
80 			                         GParamSpec *pspec);
81 static void gtk_plot3d_real_paint 		(GtkWidget *widget);
82 static void gtk_plot3d_draw_plane		(GtkPlot3D *plot,
83 						 GtkPlotVector v1,
84 						 GtkPlotVector v2,
85 						 GtkPlotVector v3,
86 						 GtkPlotVector v4,
87 						 GdkColor background);
88 static void gtk_plot3d_draw_grids               (GtkPlot3D *plot,
89                                                  GtkPlotAxis *axis,
90                                                  GtkPlotVector origin);
91 static void gtk_plot3d_draw_axis		(GtkPlot3D *plot,
92 					 	 GtkPlotAxis *axis,
93                                                  GtkPlotVector tick,
94                                                  GtkPlotVector delta);
95 static void gtk_plot3d_draw_labels		(GtkPlot3D *plot,
96 						 GtkPlotAxis *axis,
97                                                  GtkPlotVector delta);
98 static void gtk_plot3d_real_get_pixel		(GtkWidget *widget,
99                           			 gdouble x,
100 						 gdouble y,
101 						 gdouble z,
102                           			 gdouble *px,
103 						 gdouble *py,
104 						 gdouble *pz);
105 extern gint roundint			(gdouble x);
106 
107 static GtkPlotClass *parent_class = NULL;
108 
109 GtkType
gtk_plot3d_get_type(void)110 gtk_plot3d_get_type (void)
111 {
112   static GtkType plot_type = 0;
113 
114   if (!plot_type)
115     {
116       GtkTypeInfo plot_info =
117       {
118 	"GtkPlot3D",
119 	sizeof (GtkPlot3D),
120 	sizeof (GtkPlot3DClass),
121 	(GtkClassInitFunc) gtk_plot3d_class_init,
122 	(GtkObjectInitFunc) gtk_plot3d_init,
123 	/* reserved 1*/ NULL,
124         /* reserved 2 */ NULL,
125         (GtkClassInitFunc) NULL,
126       };
127 
128       plot_type = gtk_type_unique (gtk_plot_get_type(), &plot_info);
129     }
130   return plot_type;
131 }
132 
133 static void
gtk_plot3d_class_init(GtkPlot3DClass * klass)134 gtk_plot3d_class_init (GtkPlot3DClass *klass)
135 {
136   GtkObjectClass *object_class;
137   GtkWidgetClass *widget_class;
138   GtkPlotClass *plot_class;
139   GtkPlot3DClass *plot3d_class;
140   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
141 
142   parent_class = gtk_type_class (gtk_plot_get_type ());
143 
144   object_class = (GtkObjectClass *) klass;
145   widget_class = (GtkWidgetClass *) klass;
146   plot_class = (GtkPlotClass *) klass;
147   plot3d_class = (GtkPlot3DClass *) klass;
148 
149   object_class->destroy = gtk_plot3d_destroy;
150   gobject_class->set_property = gtk_plot3d_set_property;
151   gobject_class->get_property = gtk_plot3d_get_property;
152 
153   plot_class->plot_paint = gtk_plot3d_real_paint;
154   plot3d_class->get_pixel = gtk_plot3d_real_get_pixel;
155 
156   g_object_class_install_property(gobject_class,
157                            PROP_CENTER,
158   g_param_spec_pointer ("center_vector",
159                        P_("Center"),
160                        P_("Position of the center point"),
161                            G_PARAM_READABLE|G_PARAM_WRITABLE));
162   g_object_class_install_property(gobject_class,
163                            PROP_ORIGIN,
164   g_param_spec_pointer ("origin_vector",
165                        P_("Origin"),
166                        P_("Position of the origin"),
167                            G_PARAM_READABLE|G_PARAM_WRITABLE));
168   g_object_class_install_property(gobject_class,
169                            PROP_A1,
170   g_param_spec_double ("a1",
171                        P_("Angle 1"),
172                        P_("Angle 1"),
173                            -G_MAXDOUBLE, G_MAXDOUBLE,0.0,
174                            G_PARAM_READABLE|G_PARAM_WRITABLE));
175   g_object_class_install_property(gobject_class,
176                            PROP_A2,
177   g_param_spec_double ("a2",
178                        P_("Angle 2"),
179                        P_("Angle 2"),
180                            -G_MAXDOUBLE, G_MAXDOUBLE,0.0,
181                            G_PARAM_READABLE|G_PARAM_WRITABLE));
182   g_object_class_install_property(gobject_class,
183                            PROP_A3,
184   g_param_spec_double ("a3",
185                        P_("Angle 3"),
186                        P_("Angle 3"),
187                            -G_MAXDOUBLE, G_MAXDOUBLE,0.0,
188                            G_PARAM_READABLE|G_PARAM_WRITABLE));
189   g_object_class_install_property(gobject_class,
190                            PROP_XY_VISIBLE,
191   g_param_spec_boolean ("xy_visible",
192                        P_("XY Visible"),
193                        P_("XY Plane visible"),
194                            FALSE,
195                            G_PARAM_READABLE|G_PARAM_WRITABLE));
196   g_object_class_install_property(gobject_class,
197                            PROP_YZ_VISIBLE,
198   g_param_spec_boolean ("yz_visible",
199                        P_("YZ Visible"),
200                        P_("YZ Plane visible"),
201                            FALSE,
202                            G_PARAM_READABLE|G_PARAM_WRITABLE));
203   g_object_class_install_property(gobject_class,
204                            PROP_ZX_VISIBLE,
205   g_param_spec_boolean ("zx_visible",
206                        P_("ZX Visible"),
207                        P_("ZX Plane visible"),
208                            FALSE,
209                            G_PARAM_READABLE|G_PARAM_WRITABLE));
210   g_object_class_install_property(gobject_class,
211                            PROP_COLOR_XY,
212   g_param_spec_pointer ("color_xy",
213                        P_("XY Color"),
214                        P_("Color of XY Plane"),
215                            G_PARAM_READABLE|G_PARAM_WRITABLE));
216   g_object_class_install_property(gobject_class,
217                            PROP_COLOR_YZ,
218   g_param_spec_pointer ("color_yz",
219                        P_("YZ Color"),
220                        P_("Color of YZ Plane"),
221                            G_PARAM_READABLE|G_PARAM_WRITABLE));
222   g_object_class_install_property(gobject_class,
223                            PROP_COLOR_ZX,
224   g_param_spec_pointer ("color_zx",
225                        P_("ZX Color"),
226                        P_("Color of ZX Plane"),
227                            G_PARAM_READABLE|G_PARAM_WRITABLE));
228   g_object_class_install_property(gobject_class,
229                            PROP_FRAME,
230   g_param_spec_pointer ("frame_line",
231                        P_("Frame Line"),
232                        P_("Frame Line"),
233                            G_PARAM_READABLE|G_PARAM_WRITABLE));
234   g_object_class_install_property(gobject_class,
235                            PROP_CORNER,
236   g_param_spec_pointer ("corner_line",
237                        P_("Corner Line"),
238                        P_("Corner Line"),
239                            G_PARAM_READABLE|G_PARAM_WRITABLE));
240   g_object_class_install_property(gobject_class,
241                            PROP_CORNER_VISIBLE,
242   g_param_spec_boolean ("corner_visible",
243                        P_("Corner Visible"),
244                        P_("Draw the entire cube"),
245                            FALSE,
246                            G_PARAM_READABLE|G_PARAM_WRITABLE));
247   g_object_class_install_property(gobject_class,
248                            PROP_ZMIN,
249   g_param_spec_double ("zmin",
250                        P_("Z Min"),
251                        P_("Min value of the Z axis"),
252                            -G_MAXDOUBLE, G_MAXDOUBLE,0.0,
253                            G_PARAM_READABLE|G_PARAM_WRITABLE));
254   g_object_class_install_property(gobject_class,
255                            PROP_ZMAX,
256   g_param_spec_double ("zmax",
257                        P_("Z Max"),
258                        P_("Max value of the Z axis"),
259                            -G_MAXDOUBLE, G_MAXDOUBLE,0.0,
260                            G_PARAM_READABLE|G_PARAM_WRITABLE));
261   g_object_class_install_property(gobject_class,
262                            PROP_ZSCALE,
263   g_param_spec_int ("zscale",
264                        P_("Z Scale"),
265                        P_("Scale used for the Z axis"),
266                            0,G_MAXINT,0,
267                            G_PARAM_READABLE|G_PARAM_WRITABLE));
268   g_object_class_install_property(gobject_class,
269                            PROP_TITLES_OFFSET,
270   g_param_spec_int ("titles_offset",
271                        P_("Titles Offset"),
272                        P_("Titles distance from the axes"),
273                            -G_MAXINT,G_MAXINT,0,
274                            G_PARAM_READABLE|G_PARAM_WRITABLE));
275   g_object_class_install_property(gobject_class,
276                            PROP_XFACTOR,
277   g_param_spec_double ("xfactor",
278                        P_("X Factor"),
279                        P_("Relative size of the x axis"),
280                            0.0, G_MAXDOUBLE,0.0,
281                            G_PARAM_READABLE|G_PARAM_WRITABLE));
282   g_object_class_install_property(gobject_class,
283                            PROP_YFACTOR,
284   g_param_spec_double ("yfactor",
285                        P_("Y Factor"),
286                        P_("Relative size of the y axis"),
287                            0.0, G_MAXDOUBLE,0.0,
288                            G_PARAM_READABLE|G_PARAM_WRITABLE));
289   g_object_class_install_property(gobject_class,
290                            PROP_ZFACTOR,
291   g_param_spec_double ("zfactor",
292                        P_("Z Factor"),
293                        P_("Relative size of the z axis"),
294                            0.0, G_MAXDOUBLE,0.0,
295                            G_PARAM_READABLE|G_PARAM_WRITABLE));
296 }
297 
298 
299 static void
gtk_plot3d_init(GtkPlot3D * plot)300 gtk_plot3d_init (GtkPlot3D *plot)
301 {
302   GtkWidget *widget;
303   GdkColor color;
304   gint i;
305 
306   GTK_WIDGET_SET_FLAGS(plot, GTK_NO_WINDOW);
307 
308   for(i = 0; i < 360; i++){
309     plot->ncos[i] = cos(i*PI/180.);
310     plot->nsin[i] = sin(i*PI/180.);
311   }
312 
313   widget = GTK_WIDGET(plot);
314   gdk_color_black(gtk_widget_get_colormap(widget), &widget->style->black);
315   gdk_color_white(gtk_widget_get_colormap(widget), &widget->style->white);
316 
317   GTK_PLOT(plot)->legends_x = .8;
318 
319   plot->ax = GTK_PLOT(plot)->bottom;
320   plot->ay = GTK_PLOT(plot)->left;
321   plot->az = GTK_PLOT(plot)->top;
322 
323   plot->center.x = 0.5;
324   plot->center.y = 0.5;
325   plot->center.z = 0.5;
326 
327   plot->xfactor = 1.0;
328   plot->yfactor = 1.0;
329   plot->zfactor = 1.0;
330 
331   gtk_plot3d_reset_angles(plot);
332   gtk_plot3d_rotate_x(plot, 60.);
333   gtk_plot3d_rotate_z(plot, 30.);
334 
335   GTK_PLOT(plot)->xmin = 0.;
336   GTK_PLOT(plot)->xmax = 1.000000;
337   GTK_PLOT(plot)->ymin = 0.;
338   GTK_PLOT(plot)->ymax = 1.000000;
339   plot->zmin = 0.;
340   plot->zmax = 1.000000;
341 
342   plot->xy_visible = TRUE;
343   plot->yz_visible = TRUE;
344   plot->zx_visible = TRUE;
345 
346   plot->ax->show_major_grid = FALSE;
347   plot->ax->show_minor_grid = FALSE;
348   plot->ay->show_major_grid = FALSE;
349   plot->ay->show_minor_grid = FALSE;
350   plot->az->show_major_grid = FALSE;
351   plot->az->show_minor_grid = FALSE;
352 
353   plot->ax->show_major_grid = TRUE;
354   plot->ax->show_minor_grid = TRUE;
355   plot->ay->show_major_grid = TRUE;
356   plot->ay->show_minor_grid = TRUE;
357   plot->az->show_major_grid = TRUE;
358   plot->az->show_minor_grid = TRUE;
359 
360   plot->ax->ticks.nmajorticks = 0;
361   plot->ax->ticks.nminorticks = 0;
362   plot->ax->ticks.values = NULL;
363   plot->ax->ticks.set_limits = FALSE;
364   plot->ax->ticks.begin = 0;
365   plot->ax->ticks.end = 0;
366   plot->ax->ticks.step = .100000000;
367   plot->ax->ticks.nminor = 1;
368 
369   plot->ay->ticks.nmajorticks = 0;
370   plot->ay->ticks.nminorticks = 0;
371   plot->ay->ticks.values = NULL;
372   plot->ay->ticks.set_limits = FALSE;
373   plot->ay->ticks.begin = 0;
374   plot->ay->ticks.end = 0;
375   plot->ay->ticks.step = .100000000;
376   plot->ay->ticks.nminor = 1;
377 
378   plot->az->ticks.nmajorticks = 0;
379   plot->az->ticks.nminorticks = 0;
380   plot->az->ticks.values = NULL;
381   plot->az->ticks.set_limits = FALSE;
382   plot->az->ticks.begin = 0;
383   plot->az->ticks.end = 0;
384   plot->az->ticks.step = .100000000;
385   plot->az->ticks.nminor = 1;
386 
387   plot->ax->ticks.min = 0.0;
388   plot->ax->ticks.max = 1.0;
389   plot->ax->labels_offset = 25;
390   plot->ax->major_mask = GTK_PLOT_TICKS_OUT;
391   plot->ax->minor_mask = GTK_PLOT_TICKS_OUT;
392   plot->ax->ticks_length = 8;
393   plot->ax->ticks_width = 1;
394   plot->ax->orientation = GTK_PLOT_AXIS_X;
395   plot->ax->ticks.scale = GTK_PLOT_SCALE_LINEAR;
396   plot->ax->is_visible = TRUE;
397   plot->ax->custom_labels = FALSE;
398   plot->ay->ticks.min = 0.0;
399   plot->ay->ticks.max = 1.0;
400   plot->ay->major_mask = GTK_PLOT_TICKS_OUT;
401   plot->ay->minor_mask = GTK_PLOT_TICKS_OUT;
402   plot->ay->ticks_length = 8;
403   plot->ay->ticks_width = 1;
404   plot->ay->labels_offset = 25;
405   plot->ay->orientation = GTK_PLOT_AXIS_Y;
406   plot->ay->ticks.scale = GTK_PLOT_SCALE_LINEAR;
407   plot->ay->is_visible = TRUE;
408   plot->ay->custom_labels = FALSE;
409   plot->az->ticks.min = 0.0;
410   plot->az->ticks.max = 1.0;
411   plot->az->major_mask = GTK_PLOT_TICKS_OUT;
412   plot->az->minor_mask = GTK_PLOT_TICKS_OUT;
413   plot->az->ticks_length = 8;
414   plot->az->ticks_width = 1;
415   plot->az->labels_offset = 25;
416   plot->az->orientation = GTK_PLOT_AXIS_Z;
417   plot->az->ticks.scale = GTK_PLOT_SCALE_LINEAR;
418   plot->az->is_visible = TRUE;
419   plot->az->custom_labels = FALSE;
420 
421   plot->az->line.line_style = GTK_PLOT_LINE_SOLID;
422   plot->az->line.line_width = 2;
423   plot->az->line.color = widget->style->black;
424   plot->az->labels_attr.text = NULL;
425   plot->az->labels_attr.height = DEFAULT_FONT_HEIGHT;
426   plot->az->labels_attr.fg = widget->style->black;
427   plot->az->labels_attr.bg = widget->style->white;
428   plot->az->labels_attr.transparent = TRUE;
429   plot->az->labels_attr.justification = GTK_JUSTIFY_CENTER;
430   plot->az->labels_attr.angle = 0;
431   plot->az->label_mask = GTK_PLOT_LABEL_OUT;
432   plot->az->label_style = GTK_PLOT_LABEL_FLOAT;
433   plot->az->label_precision = 1;
434   plot->az->title.angle = 90;
435   plot->az->title.justification = GTK_JUSTIFY_CENTER;
436   plot->az->title.height = DEFAULT_FONT_HEIGHT;
437   plot->az->title.fg = widget->style->black;
438   plot->az->title.bg = widget->style->white;
439   plot->az->title.transparent = TRUE;
440   plot->az->title_visible = TRUE;
441 
442   plot->ax->line.line_style = GTK_PLOT_LINE_SOLID;
443   plot->ax->line.line_width = 2;
444   plot->ax->line.color = widget->style->black;
445   plot->ax->labels_attr.text = NULL;
446   plot->ax->labels_attr.height = DEFAULT_FONT_HEIGHT;
447   plot->ax->labels_attr.fg = widget->style->black;
448   plot->ax->labels_attr.bg = widget->style->white;
449   plot->ax->labels_attr.transparent = TRUE;
450   plot->ax->labels_attr.justification = GTK_JUSTIFY_CENTER;
451   plot->ax->labels_attr.angle = 0;
452   plot->ax->label_mask = GTK_PLOT_LABEL_OUT;
453   plot->ax->label_style = GTK_PLOT_LABEL_FLOAT;
454   plot->ax->label_precision = 1;
455   plot->ax->title.angle = 0;
456   plot->ax->title.justification = GTK_JUSTIFY_CENTER;
457   plot->ax->title.height = DEFAULT_FONT_HEIGHT;
458   plot->ax->title.fg = widget->style->black;
459   plot->ax->title.bg = widget->style->white;
460   plot->ax->title.transparent = TRUE;
461   plot->ax->title_visible = TRUE;
462 
463   plot->ay->line.line_style = GTK_PLOT_LINE_SOLID;
464   plot->ay->line.line_width = 2;
465   plot->ay->line.color = widget->style->black;
466   plot->ay->labels_attr.text = NULL;
467   plot->ay->labels_attr.height = DEFAULT_FONT_HEIGHT;
468   plot->ay->labels_attr.fg = widget->style->black;
469   plot->ay->labels_attr.bg = widget->style->white;
470   plot->ay->labels_attr.transparent = TRUE;
471   plot->ay->labels_attr.angle = 0;
472   plot->ay->label_mask = GTK_PLOT_LABEL_OUT;
473   plot->ay->label_style = GTK_PLOT_LABEL_FLOAT;
474   plot->ay->label_precision = 1;
475   plot->ay->labels_attr.justification = GTK_JUSTIFY_CENTER;
476   plot->ay->title.angle = 0;
477   plot->ay->title.justification = GTK_JUSTIFY_CENTER;
478   plot->ay->title.height = DEFAULT_FONT_HEIGHT;
479   plot->ay->title.fg = widget->style->black;
480   plot->ay->title.bg = widget->style->white;
481   plot->ay->title.transparent = TRUE;
482   plot->ay->title_visible = TRUE;
483 
484   gtk_plot_axis_set_title(GTK_PLOT(plot)->bottom, "X Title");
485   gtk_plot_axis_set_title(GTK_PLOT(plot)->left, "Y Title");
486   gtk_plot_axis_set_title(GTK_PLOT(plot)->top, "Z Title");
487 
488   GTK_PLOT(plot)->xscale = GTK_PLOT_SCALE_LINEAR;
489   GTK_PLOT(plot)->yscale = GTK_PLOT_SCALE_LINEAR;
490   plot->zscale = GTK_PLOT_SCALE_LINEAR;
491 
492   plot->xy.major_mask = plot->ax->major_mask;
493   plot->xy.minor_mask = plot->ax->minor_mask;
494   plot->xy.label_mask = plot->ax->label_mask;
495   plot->xz.major_mask = plot->ax->major_mask;
496   plot->xz.minor_mask = plot->ax->minor_mask;
497   plot->xz.label_mask = plot->ax->label_mask;
498   plot->yx.major_mask = plot->ay->major_mask;
499   plot->yx.minor_mask = plot->ay->minor_mask;
500   plot->yx.label_mask = plot->ay->label_mask;
501   plot->yz.major_mask = plot->ay->major_mask;
502   plot->yz.minor_mask = plot->ay->minor_mask;
503   plot->yz.label_mask = plot->ay->label_mask;
504   plot->zx.major_mask = plot->az->major_mask;
505   plot->zx.minor_mask = plot->az->minor_mask;
506   plot->zx.label_mask = plot->az->label_mask;
507   plot->zy.major_mask = plot->az->major_mask;
508   plot->zy.minor_mask = plot->az->minor_mask;
509   plot->zy.label_mask = plot->az->label_mask;
510 
511   plot->xy.title_visible = plot->ax->title_visible;
512   plot->xz.title_visible = plot->ax->title_visible;
513   plot->yx.title_visible = plot->ay->title_visible;
514   plot->yz.title_visible = plot->ay->title_visible;
515   plot->zx.title_visible = plot->az->title_visible;
516   plot->zy.title_visible = plot->az->title_visible;
517 
518   plot->frame.color = widget->style->black;
519   plot->frame.line_width = 1;
520   plot->frame.line_style = GTK_PLOT_LINE_SOLID;
521 
522   plot->corner_visible = FALSE;
523   plot->corner.line_style = GTK_PLOT_LINE_SOLID;
524   plot->corner.line_width = 0;
525   plot->corner.color = widget->style->black;
526 
527   plot->ax->direction = plot->e1;
528   plot->ay->direction = plot->e2;
529   plot->az->direction = plot->e3;
530 
531   gdk_color_parse("gray95", &color);
532   gdk_color_alloc(gtk_widget_get_colormap(widget), &color);
533   plot->color_xy = color;
534 
535   gdk_color_parse("gray80", &color);
536   gdk_color_alloc(gtk_widget_get_colormap(widget), &color);
537   plot->color_yz = color;
538 
539   gdk_color_parse("gray65", &color);
540   gdk_color_alloc(gtk_widget_get_colormap(widget), &color);
541   plot->color_zx = color;
542 
543   plot->titles_offset = 60;
544   GTK_PLOT(plot)->legends_attr.transparent = FALSE;
545 
546   gtk_plot_axis_ticks_recalc(plot->ax);
547   gtk_plot_axis_ticks_recalc(plot->ay);
548   gtk_plot_axis_ticks_recalc(plot->az);
549 
550   GTK_PLOT(plot)->clip_data = TRUE;
551 
552   gtk_psfont_init();
553 }
554 
555 static void
gtk_plot3d_destroy(GtkObject * object)556 gtk_plot3d_destroy (GtkObject *object)
557 {
558   if ( GTK_OBJECT_CLASS (parent_class)->destroy )
559     (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
560 }
561 
562 static void
gtk_plot3d_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)563 gtk_plot3d_set_property (GObject      *object,
564 			 guint prop_id,
565 			 const GValue *value,
566 			 GParamSpec *pspec)
567 {
568   GtkPlot3D *plot;
569 
570   plot = GTK_PLOT3D (object);
571 
572   switch(prop_id){
573     case PROP_CENTER:
574       plot->center = *((GtkPlotVector *)g_value_get_pointer(value));
575       break;
576     case PROP_ORIGIN:
577       plot->origin = *((GtkPlotVector *)g_value_get_pointer(value));
578       break;
579     case PROP_A1:
580       plot->a1 = g_value_get_double(value);
581       break;
582     case PROP_A2:
583       plot->a2 = g_value_get_double(value);
584       break;
585     case PROP_A3:
586       plot->a3 = g_value_get_double(value);
587       break;
588     case PROP_XY_VISIBLE:
589       plot->xy_visible = g_value_get_boolean(value);
590       break;
591     case PROP_YZ_VISIBLE:
592       plot->yz_visible = g_value_get_boolean(value);
593       break;
594     case PROP_ZX_VISIBLE:
595       plot->zx_visible = g_value_get_boolean(value);
596       break;
597     case PROP_COLOR_XY:
598       plot->color_xy = *((GdkColor *)g_value_get_pointer(value));
599       break;
600     case PROP_COLOR_YZ:
601       plot->color_yz = *((GdkColor *)g_value_get_pointer(value));
602       break;
603     case PROP_COLOR_ZX:
604       plot->color_zx = *((GdkColor *)g_value_get_pointer(value));
605       break;
606     case PROP_FRAME:
607       plot->frame = *((GtkPlotLine *)g_value_get_pointer(value));
608       break;
609     case PROP_CORNER:
610       plot->corner = *((GtkPlotLine *)g_value_get_pointer(value));
611       break;
612     case PROP_CORNER_VISIBLE:
613       plot->corner_visible = g_value_get_boolean(value);
614       break;
615     case PROP_ZMIN:
616       plot->zmin = g_value_get_double(value);
617       break;
618     case PROP_ZMAX:
619       plot->zmax = g_value_get_double(value);
620       break;
621     case PROP_ZSCALE:
622       plot->zscale = g_value_get_boolean(value);
623       break;
624     case PROP_TITLES_OFFSET:
625       plot->titles_offset = g_value_get_int(value);
626       break;
627     case PROP_XFACTOR:
628       plot->xfactor = g_value_get_double(value);
629       break;
630     case PROP_YFACTOR:
631       plot->yfactor = g_value_get_double(value);
632       break;
633     case PROP_ZFACTOR:
634       plot->zfactor = g_value_get_double(value);
635       break;
636     default:
637       break;
638   }
639 }
640 
641 static void
gtk_plot3d_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)642 gtk_plot3d_get_property (GObject      *object,
643                          guint            prop_id,
644                          GValue          *value,
645                          GParamSpec      *pspec)
646 
647 {
648   GtkPlot3D *plot;
649 
650   plot = GTK_PLOT3D (object);
651 
652   switch(prop_id){
653     case PROP_CENTER:
654       g_value_set_pointer(value, &plot->center);
655       break;
656     case PROP_ORIGIN:
657       g_value_set_pointer(value, &plot->origin);
658       break;
659     case PROP_A1:
660       g_value_set_double(value, plot->a1);
661       break;
662     case PROP_A2:
663       g_value_set_double(value, plot->a2);
664       break;
665     case PROP_A3:
666       g_value_set_double(value, plot->a3);
667       break;
668     case PROP_XY_VISIBLE:
669       g_value_set_boolean(value, plot->xy_visible);
670       break;
671     case PROP_YZ_VISIBLE:
672       g_value_set_boolean(value, plot->yz_visible);
673       break;
674     case PROP_ZX_VISIBLE:
675       g_value_set_boolean(value, plot->zx_visible);
676       break;
677     case PROP_COLOR_XY:
678       g_value_set_pointer(value, &plot->color_xy);
679       break;
680     case PROP_COLOR_YZ:
681       g_value_set_pointer(value, &plot->color_yz);
682       break;
683     case PROP_COLOR_ZX:
684       g_value_set_pointer(value, &plot->color_zx);
685       break;
686     case PROP_FRAME:
687       g_value_set_pointer(value, &plot->frame);
688       break;
689     case PROP_CORNER:
690       g_value_set_pointer(value, &plot->corner);
691       break;
692     case PROP_CORNER_VISIBLE:
693       g_value_set_boolean(value, plot->corner_visible);
694       break;
695     case PROP_ZMIN:
696       g_value_set_double(value, plot->zmin);
697       break;
698     case PROP_ZMAX:
699       g_value_set_double(value, plot->zmax);
700       break;
701     case PROP_ZSCALE:
702       g_value_set_boolean(value, plot->zscale);
703       break;
704     case PROP_TITLES_OFFSET:
705       g_value_set_int(value, plot->titles_offset);
706       break;
707     case PROP_XFACTOR:
708       g_value_set_double(value, plot->xfactor);
709       break;
710     case PROP_YFACTOR:
711       g_value_set_double(value, plot->yfactor);
712       break;
713     case PROP_ZFACTOR:
714       g_value_set_double(value, plot->zfactor);
715       break;
716     default:
717       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
718   }
719 }
720 
721 static void
gtk_plot3d_real_paint(GtkWidget * widget)722 gtk_plot3d_real_paint (GtkWidget *widget)
723 {
724   GtkPlot3D *plot;
725   GtkPlotText *child_text;
726   GdkPixmap *pixmap;
727   GtkPlotPC *pc;
728   GList *datasets;
729   GList *text;
730   gint width, height, size;
731   gint xoffset, yoffset, xp, yp;
732   gint origin;
733   gdouble pz;
734   GtkPlotVector e[8], o, v[8];
735   GtkPlotVector vx, vy, vz;
736   gint i;
737 
738   if(!GTK_WIDGET_VISIBLE(widget)) return;
739 
740   plot = GTK_PLOT3D(widget);
741 
742   xoffset = GTK_PLOT(plot)->internal_allocation.x;
743   yoffset = GTK_PLOT(plot)->internal_allocation.y;
744   width = GTK_PLOT(plot)->internal_allocation.width;
745   height = GTK_PLOT(plot)->internal_allocation.height;
746 
747   pixmap = GTK_PLOT(plot)->drawable;
748   pc = GTK_PLOT(plot)->pc;
749 
750   gtk_plot_pc_gsave(pc);
751   gtk_plot_pc_set_color(pc, &GTK_PLOT(plot)->background);
752 
753   if(!gtk_plot_is_transparent(GTK_PLOT(plot)))
754     gtk_plot_pc_draw_rectangle (pc, TRUE,
755   		        xoffset, yoffset,
756 		        width , height);
757 
758   /* draw frame to guide the eyes*/
759 /*
760   gdk_draw_rectangle (pixmap, widget->style->black_gc, FALSE,
761 		      xoffset, yoffset,
762 		      width , height);
763 */
764 
765   /* find origin */
766 
767   xp = GTK_PLOT(plot)->internal_allocation.x;
768   yp = GTK_PLOT(plot)->internal_allocation.y;
769 
770   size = MIN(width, height) / SQRT2;
771 
772   /* 8 vertices of the cube */
773 
774   e[0].x = 0;
775   e[0].y = 0;
776   e[0].z = 0;
777   e[1].x = 1;
778   e[1].y = 0;
779   e[1].z = 0;
780   e[2].x = 1;
781   e[2].y = 1;
782   e[2].z = 0;
783   e[3].x = 0;
784   e[3].y = 1;
785   e[3].z = 0;
786   e[4].x = 0;
787   e[4].y = 0;
788   e[4].z = 1;
789   e[5].x = 1;
790   e[5].y = 0;
791   e[5].z = 1;
792   e[6].x = 1;
793   e[6].y = 1;
794   e[6].z = 1;
795   e[7].x = 0;
796   e[7].y = 1;
797   e[7].z = 1;
798 
799   for(i = 0; i < 8; i++){
800     v[i].x = (1.0 - e[i].x) * plot->ax->ticks.min + e[i].x * plot->ax->ticks.max;
801     v[i].y = (1.0 - e[i].y) * plot->ay->ticks.min + e[i].y * plot->ay->ticks.max;
802     v[i].z = (1.0 - e[i].z) * plot->az->ticks.min + e[i].z * plot->az->ticks.max;
803   }
804 
805   /* Origin for drawing the planes */
806 
807   origin = 0;
808   o.x = 0.0;
809   o.y = 0.0;
810   o.z = 0.0;
811 
812   for(i = 1; i < 8; i++){
813      pz = e[i].x * plot->e1.z + e[i].y * plot->e2.z + e[i].z * plot->e3.z ;
814 
815      if(pz > o.z){
816        o.z = pz;
817        origin = i;
818      }
819   }
820 
821   plot->origin = v[origin];
822 
823   plot->ax->direction.x = 1.0;
824   plot->ax->direction.y = 0.0;
825   plot->ax->direction.z = 0.0;
826   plot->ay->direction.x = 0.0;
827   plot->ay->direction.y = 1.0;
828   plot->ay->direction.z = 0.0;
829   plot->az->direction.x = 0.0;
830   plot->az->direction.y = 0.0;
831   plot->az->direction.z = 1.0;
832 
833   plot->ax->origin.x = 0.0;
834   plot->ax->origin.y = v[origin].y;
835   plot->ax->origin.z = v[origin].z;
836 
837   plot->ay->origin.y = 0.0;
838   plot->ay->origin.x = v[origin].x;
839   plot->ay->origin.z = v[origin].z;
840 
841   plot->az->origin.z = 0.0;
842   plot->az->origin.x = v[origin].x;
843   plot->az->origin.y = v[origin].y;
844 
845   /* Tick directions */
846 
847   vx.x = plot->e1.x * (1. - 2. * e[origin].x);
848   vx.y = plot->e1.y * (1. - 2. * e[origin].x);
849   vx.z = plot->e1.z * (1. - 2. * e[origin].x);
850   vy.x = plot->e2.x * (1. - 2. * e[origin].y);
851   vy.y = plot->e2.y * (1. - 2. * e[origin].y);
852   vy.z = plot->e2.z * (1. - 2. * e[origin].y);
853   vz.x = plot->e3.x * (1. - 2. * e[origin].z);
854   vz.y = plot->e3.y * (1. - 2. * e[origin].z);
855   vz.z = plot->e3.z * (1. - 2. * e[origin].z);
856 
857   /* draw planes, ticks & grid lines */
858 
859   gtk_plot_axis_ticks_recalc(plot->ax);
860   gtk_plot_axis_ticks_recalc(plot->ay);
861   gtk_plot_axis_ticks_recalc(plot->az);
862 
863   if(plot->xy_visible)
864     {
865       /* PLANES */
866 
867       if(origin == 0 || origin == 1 || origin == 2 || origin == 3)
868         gtk_plot3d_draw_plane(plot, v[0], v[1], v[2], v[3], plot->color_xy);
869       if(origin == 4 || origin == 5 || origin == 6 || origin == 7)
870         gtk_plot3d_draw_plane(plot, v[4], v[5], v[6], v[7], plot->color_xy);
871 
872       /* X AXIS */
873 
874       plot->ax->major_mask = plot->xy.major_mask;
875       plot->ax->minor_mask = plot->xy.minor_mask;
876       plot->ax->label_mask = plot->xy.label_mask;
877       plot->ax->title_visible = plot->xy.title_visible;
878 
879       o.x = 0.0;
880       o.y = (1.0 - e[origin].y) * plot->ay->ticks.max + e[origin].y * plot->ay->ticks.min - plot->ax->origin.y;
881       o.z = 0.0;
882 
883       gtk_plot3d_draw_grids(plot, plot->ax, o);
884       gtk_plot3d_draw_axis(plot, plot->ax, vy, o);
885       gtk_plot3d_draw_labels(plot, plot->ax, o);
886 
887       /* Y AXIS */
888 
889       plot->ay->major_mask = plot->yx.major_mask;
890       plot->ay->minor_mask = plot->yx.minor_mask;
891       plot->ay->label_mask = plot->yx.label_mask;
892       plot->ay->title_visible = plot->yx.title_visible;
893 
894       o.x = (1.0 - e[origin].x) * plot->ax->ticks.max + e[origin].x * plot->ax->ticks.min - plot->ay->origin.x;
895       o.y = 0.0;
896       o.z = 0.0;
897 
898       gtk_plot3d_draw_grids(plot, plot->ay, o);
899       gtk_plot3d_draw_axis(plot, plot->ay, vx, o);
900       gtk_plot3d_draw_labels(plot, plot->ay, o);
901     }
902 
903   if(plot->yz_visible)
904     {
905       /* PLANES */
906 
907       if(origin == 0 || origin == 3 || origin == 7 || origin == 4)
908         gtk_plot3d_draw_plane(plot, v[0], v[3], v[7], v[4], plot->color_yz);
909       if(origin == 1 || origin == 2 || origin == 6 || origin == 5)
910         gtk_plot3d_draw_plane(plot, v[1], v[2], v[6], v[5], plot->color_yz);
911 
912       /* Y AXIS */
913 
914       plot->ay->major_mask = plot->yz.major_mask;
915       plot->ay->minor_mask = plot->yz.minor_mask;
916       plot->ay->label_mask = plot->yz.label_mask;
917       plot->ay->title_visible = plot->yz.title_visible;
918 
919       o.x = 0.0;
920       o.y = 0.0;
921       o.z = (1.0 - e[origin].z) * plot->az->ticks.max + e[origin].z * plot->az->ticks.min - plot->ay->origin.z;
922 
923       gtk_plot3d_draw_grids(plot, plot->ay, o);
924       gtk_plot3d_draw_axis(plot, plot->ay, vz, o);
925       gtk_plot3d_draw_labels(plot, plot->ay, o);
926 
927       /* Z AXIS */
928 
929       plot->az->major_mask = plot->zy.major_mask;
930       plot->az->minor_mask = plot->zy.minor_mask;
931       plot->az->label_mask = plot->zy.label_mask;
932       plot->az->title_visible = plot->zy.title_visible;
933 
934       o.x = 0.0;
935       o.y = (1.0 - e[origin].y) * plot->ay->ticks.max + e[origin].y * plot->ay->ticks.min - plot->az->origin.y;
936       o.z = 0.0;
937 
938       gtk_plot3d_draw_grids(plot, plot->az, o);
939       gtk_plot3d_draw_axis(plot, plot->az, vy, o);
940       gtk_plot3d_draw_labels(plot, plot->az, o);
941     }
942 
943   if(plot->zx_visible)
944     {
945       /* PLANES */
946 
947       if(origin == 0 || origin == 4 || origin == 5 || origin == 1)
948         gtk_plot3d_draw_plane(plot, v[0], v[4], v[5], v[1], plot->color_zx);
949       if(origin == 3 || origin == 7 || origin == 6 || origin == 2)
950         gtk_plot3d_draw_plane(plot, v[3], v[7], v[6], v[2], plot->color_zx);
951 
952       /* Z AXIS */
953 
954       plot->az->major_mask = plot->zx.major_mask;
955       plot->az->minor_mask = plot->zx.minor_mask;
956       plot->az->label_mask = plot->zx.label_mask;
957       plot->az->title_visible = plot->zx.title_visible;
958 
959       o.x = (1.0 - e[origin].x) * plot->ax->ticks.max + e[origin].x * plot->ax->ticks.min - plot->az->origin.x;
960       o.y = 0.0;
961       o.z = 0.0;
962 
963       gtk_plot3d_draw_grids(plot, plot->az, o);
964       gtk_plot3d_draw_axis(plot, plot->az, vx, o);
965       gtk_plot3d_draw_labels(plot, plot->az, o);
966 
967       /* X AXIS */
968 
969       plot->ax->major_mask = plot->xz.major_mask;
970       plot->ax->minor_mask = plot->xz.minor_mask;
971       plot->ax->label_mask = plot->xz.label_mask;
972       plot->ax->title_visible = plot->xz.title_visible;
973 
974       o.x = 0.0;
975       o.y = 0.0;
976       o.z = (1.0 - e[origin].z) * plot->az->ticks.max + e[origin].z * plot->az->ticks.min - plot->ax->origin.z;
977 
978       gtk_plot3d_draw_grids(plot, plot->ax, o);
979       gtk_plot3d_draw_axis(plot, plot->ax, vz, o);
980       gtk_plot3d_draw_labels(plot, plot->ax, o);
981     }
982 
983   datasets = GTK_PLOT(plot)->data_sets;
984   while(datasets)
985    {
986      GtkPlotData *dataset;
987 
988      dataset = GTK_PLOT_DATA(datasets->data);
989 
990      gtk_plot_data_paint(dataset);
991 
992      datasets = datasets->next;
993    }
994 
995   if(plot->corner_visible){
996     gdouble px0, py0, pz0;
997     gdouble px, py, pz;
998     gint corner;
999     gint end[3];
1000 
1001     corner = origin + 2;
1002     if(corner > 3) corner -= 4;
1003 
1004     end[0] = corner;
1005 
1006     corner += 4;
1007     if(corner > 7) corner -= 8;
1008 
1009     end[1] = corner + 1;
1010     if(end[1] == 8 || end[1] == 4) end[1] -= 4;
1011 
1012     end[2] = corner - 1;
1013     if(end[2] == -1 || end[2] == 3) end[2] += 4;
1014 
1015     gtk_plot3d_get_pixel(plot, v[corner].x, v[corner].y, v[corner].z,
1016                          &px0, &py0, &pz0);
1017 
1018     for (i = 0; i < 3; i++){
1019        gtk_plot3d_get_pixel(plot, v[end[i]].x, v[end[i]].y, v[end[i]].z,
1020                             &px, &py, &pz);
1021 
1022        gtk_plot_draw_line(GTK_PLOT(plot), plot->corner, px0, py0, px, py);
1023     }
1024 
1025   }
1026 
1027   text = GTK_PLOT(plot)->text;
1028   while(text)
1029    {
1030      child_text = (GtkPlotText *) text->data;
1031      gtk_plot_draw_text(GTK_PLOT(plot), *child_text);
1032      text = text->next;
1033    }
1034 
1035   GTK_PLOT_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(plot)))->draw_legends(GTK_WIDGET(plot));
1036 
1037   gtk_plot_pc_grestore(pc);
1038 }
1039 
1040 
1041 GtkWidget*
gtk_plot3d_new(GdkDrawable * drawable)1042 gtk_plot3d_new (GdkDrawable *drawable)
1043 {
1044   GtkPlot3D *plot;
1045 
1046   plot = gtk_type_new (gtk_plot3d_get_type ());
1047 
1048   gtk_plot3d_construct(GTK_PLOT3D(plot), drawable);
1049 
1050   return GTK_WIDGET (plot);
1051 }
1052 
1053 void
gtk_plot3d_construct(GtkPlot3D * plot,GdkDrawable * drawable)1054 gtk_plot3d_construct(GtkPlot3D *plot, GdkDrawable *drawable)
1055 {
1056   GTK_PLOT(plot)->drawable = drawable;
1057 }
1058 
1059 GtkWidget*
gtk_plot3d_new_with_size(GdkDrawable * drawable,gdouble width,gdouble height)1060 gtk_plot3d_new_with_size (GdkDrawable *drawable, gdouble width, gdouble height)
1061 {
1062   GtkWidget *plot;
1063 
1064   plot = gtk_type_new (gtk_plot3d_get_type ());
1065 
1066   gtk_plot3d_construct_with_size(GTK_PLOT3D(plot), drawable, width, height);
1067 
1068   return(plot);
1069 }
1070 
1071 void
gtk_plot3d_construct_with_size(GtkPlot3D * plot,GdkDrawable * drawable,gdouble width,gdouble height)1072 gtk_plot3d_construct_with_size(GtkPlot3D *plot, GdkDrawable *drawable,
1073 			       gdouble width, gdouble height)
1074 {
1075   gtk_plot3d_construct(plot, drawable);
1076 
1077   gtk_plot_resize (GTK_PLOT(plot), width, height);
1078 }
1079 
1080 static void
gtk_plot3d_draw_plane(GtkPlot3D * plot,GtkPlotVector v1,GtkPlotVector v2,GtkPlotVector v3,GtkPlotVector v4,GdkColor background)1081 gtk_plot3d_draw_plane(GtkPlot3D *plot,
1082                       GtkPlotVector v1,
1083                       GtkPlotVector v2,
1084                       GtkPlotVector v3,
1085                       GtkPlotVector v4,
1086                       GdkColor background)
1087 {
1088   GtkWidget *widget;
1089   GdkPixmap *pixmap;
1090   GtkPlotPC *pc;
1091   GtkPlotVector v[4];
1092   GtkPlotPoint p[4];
1093   gdouble px, py, pz;
1094   gint i;
1095 
1096   widget = GTK_WIDGET(plot);
1097   if(!GTK_WIDGET_VISIBLE(plot)) return;
1098 
1099   pixmap = GTK_PLOT(plot)->drawable;
1100   pc = GTK_PLOT(plot)->pc;
1101 
1102   gtk_plot_pc_set_color(pc, &background);
1103 
1104   v[0] = v1;
1105   v[1] = v2;
1106   v[2] = v3;
1107   v[3] = v4;
1108   for(i = 0; i < 4; i++){
1109     gtk_plot3d_get_pixel(plot, v[i].x, v[i].y, v[i].z, &px, &py, &pz);
1110     p[i].x = px;
1111     p[i].y = py;
1112   }
1113 
1114   gtk_plot_pc_draw_polygon(pc, TRUE, p, 4);
1115   gtk_plot_pc_set_color(pc, &plot->frame.color);
1116 
1117   gtk_plot_pc_set_lineattr(pc,
1118                            plot->frame.line_width,
1119                            plot->frame.line_style == GTK_PLOT_LINE_SOLID ? GDK_LINE_SOLID : GDK_LINE_ON_OFF_DASH,
1120                            0, 0);
1121 
1122   if(plot->frame.line_style != GTK_PLOT_LINE_NONE)
1123     gtk_plot_pc_draw_polygon(pc, FALSE, p, 4);
1124 
1125 }
1126 
1127 static void
gtk_plot3d_draw_grids(GtkPlot3D * plot,GtkPlotAxis * axis,GtkPlotVector delta)1128 gtk_plot3d_draw_grids(GtkPlot3D *plot, GtkPlotAxis *axis, GtkPlotVector delta)
1129 {
1130   GtkWidget *widget;
1131   GtkPlotLine major_grid, minor_grid;
1132   gdouble xx;
1133   gdouble x1, x2, y1, y2;
1134   gint size, width, height;
1135   gdouble xp, yp, oz;
1136   gint ntick;
1137 
1138   widget = GTK_WIDGET(plot);
1139 
1140   xp = GTK_PLOT(plot)->internal_allocation.x;
1141   yp = GTK_PLOT(plot)->internal_allocation.y;
1142   width = GTK_PLOT(plot)->internal_allocation.width;
1143   height = GTK_PLOT(plot)->internal_allocation.height;
1144 
1145   size = MIN(width, height) / SQRT2;
1146 
1147   switch(axis->orientation){
1148     case GTK_PLOT_AXIS_X:
1149       major_grid = GTK_PLOT(plot)->left->major_grid;
1150       minor_grid = GTK_PLOT(plot)->left->minor_grid;
1151       break;
1152     case GTK_PLOT_AXIS_Y:
1153       major_grid = GTK_PLOT(plot)->bottom->major_grid;
1154       minor_grid = GTK_PLOT(plot)->bottom->minor_grid;
1155       break;
1156     case GTK_PLOT_AXIS_Z:
1157       major_grid = GTK_PLOT(plot)->top->major_grid;
1158       minor_grid = GTK_PLOT(plot)->top->minor_grid;
1159       break;
1160   }
1161 
1162   if(axis->show_minor_grid)
1163     {
1164         for(ntick = 0; ntick < axis->ticks.nticks; ntick++){
1165           if(!axis->ticks.values[ntick].minor) continue;
1166           if(axis->ticks.values[ntick].value >= axis->ticks.min){
1167                xx = axis->ticks.values[ntick].value;
1168                gtk_plot3d_get_pixel(plot,
1169                              axis->origin.x + axis->direction.x * xx,
1170                              axis->origin.y + axis->direction.y * xx,
1171                              axis->origin.z + axis->direction.z * xx,
1172                              &x1, &y1, &oz);
1173                gtk_plot3d_get_pixel(plot,
1174                              axis->origin.x + axis->direction.x * xx + delta.x,
1175                              axis->origin.y + axis->direction.y * xx + delta.y,
1176                              axis->origin.z + axis->direction.z * xx + delta.z,
1177                              &x2, &y2, &oz);
1178                gtk_plot_draw_line(GTK_PLOT(plot),
1179                                   minor_grid,
1180                                   x1, y1, x2, y2);
1181           }
1182         }
1183     }
1184 
1185   if(axis->show_major_grid)
1186     {
1187         for(ntick = 0; ntick < axis->ticks.nticks; ntick++){
1188           if(axis->ticks.values[ntick].minor) continue;
1189           if(axis->ticks.values[ntick].value > axis->ticks.min &&
1190              axis->ticks.values[ntick].value < axis->ticks.max){
1191                xx = axis->ticks.values[ntick].value;
1192                gtk_plot3d_get_pixel(plot,
1193                              axis->origin.x + axis->direction.x * xx,
1194                              axis->origin.y + axis->direction.y * xx,
1195                              axis->origin.z + axis->direction.z * xx,
1196                              &x1, &y1, &oz);
1197                gtk_plot3d_get_pixel(plot,
1198                              axis->origin.x + axis->direction.x * xx + delta.x,
1199                              axis->origin.y + axis->direction.y * xx + delta.y,
1200                              axis->origin.z + axis->direction.z * xx + delta.z,
1201                              &x2, &y2, &oz);
1202                gtk_plot_draw_line(GTK_PLOT(plot),
1203                                   major_grid,
1204                                   x1, y1, x2, y2);
1205           }
1206         }
1207     }
1208 
1209 }
1210 
1211 static void
gtk_plot3d_draw_axis(GtkPlot3D * plot,GtkPlotAxis * axis,GtkPlotVector tick,GtkPlotVector delta)1212 gtk_plot3d_draw_axis(GtkPlot3D *plot,
1213                      GtkPlotAxis *axis,
1214                      GtkPlotVector tick,
1215                      GtkPlotVector delta)
1216 {
1217   GtkWidget *widget;
1218   GtkPlotPC *pc;
1219   gdouble xx;
1220   gint line_width;
1221   gint xp, yp, width, height;
1222   gint ntick;
1223   gdouble m;
1224   gdouble oz;
1225   gdouble x1, x2, y1, y2;
1226   gint size;
1227   gint ticks_length;
1228 
1229   widget = GTK_WIDGET(plot);
1230   pc = GTK_PLOT(plot)->pc;
1231 
1232   xp = GTK_PLOT(plot)->internal_allocation.x;
1233   yp = GTK_PLOT(plot)->internal_allocation.y;
1234   width = GTK_PLOT(plot)->internal_allocation.width;
1235   height = GTK_PLOT(plot)->internal_allocation.height;
1236 
1237   m = GTK_PLOT(plot)->magnification;
1238   size = MIN(width, height) / SQRT2;
1239 
1240   line_width = plot->frame.line_width;
1241   gtk_plot_pc_set_color(pc, &plot->frame.color);
1242   gtk_plot_pc_set_lineattr(pc, line_width, 0, 3, 0);
1243 
1244 /*
1245   gtk_plot_pc_draw_line(pc, x1, y1, x2, y2);
1246 */
1247 
1248   gtk_plot_pc_set_lineattr(pc, axis->ticks_width, 0, 1, 0);
1249 
1250   for(ntick = 0; ntick < axis->ticks.nticks; ntick++){
1251     xx = axis->ticks.values[ntick].value;
1252     if(!axis->ticks.values[ntick].minor){
1253          ticks_length = axis->ticks_length;
1254          gtk_plot3d_get_pixel(plot,
1255                         axis->origin.x + axis->direction.x * xx + delta.x,
1256                         axis->origin.y + axis->direction.y * xx + delta.y,
1257                         axis->origin.z + axis->direction.z * xx + delta.z,
1258                         &x1, &y1, &oz);
1259          if(xx >= axis->ticks.min){
1260            x2 = x1 + m * ticks_length * tick.x;
1261            y2 = y1 + m * ticks_length * tick.y;
1262            if(axis->major_mask == GTK_PLOT_TICKS_OUT)
1263               gtk_plot_pc_draw_line(pc, x1, y1, x2, y2);
1264            x2 = x1 - m * axis->ticks_length * tick.x;
1265            y2 = y1 - m * axis->ticks_length * tick.y;
1266            if(axis->major_mask == GTK_PLOT_TICKS_IN)
1267               gtk_plot_pc_draw_line(pc, x1, y1, x2, y2);
1268          }
1269     } else {
1270          ticks_length = axis->ticks_length / 2.;
1271          gtk_plot3d_get_pixel(plot,
1272                         axis->origin.x + axis->direction.x * xx + delta.x,
1273                         axis->origin.y + axis->direction.y * xx + delta.y,
1274                         axis->origin.z + axis->direction.z * xx + delta.z,
1275                         &x1, &y1, &oz);
1276          if(xx >= axis->ticks.min){
1277            x2 = x1 + m * ticks_length * tick.x;
1278            y2 = y1 + m * ticks_length * tick.y;
1279            if(axis->minor_mask == GTK_PLOT_TICKS_OUT)
1280               gtk_plot_pc_draw_line(pc, x1, y1, x2, y2);
1281 
1282            x2 = x1 - m * axis->ticks_length * tick.x;
1283            y2 = y1 - m * axis->ticks_length * tick.y;
1284            if(axis->minor_mask == GTK_PLOT_TICKS_IN)
1285               gtk_plot_pc_draw_line(pc, x1, y1, x2, y2);
1286          }
1287     }
1288   }
1289 
1290 }
1291 
1292 
1293 static void
gtk_plot3d_draw_labels(GtkPlot3D * plot,GtkPlotAxis * axis,GtkPlotVector delta)1294 gtk_plot3d_draw_labels(GtkPlot3D *plot,
1295                        GtkPlotAxis *axis,
1296                        GtkPlotVector delta)
1297 {
1298   GtkWidget *widget;
1299   GtkPlotPC *pc;
1300   GtkPlotText title, tick;
1301   gchar label[100];
1302   gdouble tick_value;
1303   gdouble xx;
1304   gint text_height, text_width, ascent, descent;
1305   gint xp, yp, width, height;
1306   gint ntick;
1307   gdouble m;
1308   gdouble size, ox, oy, oz;
1309   gdouble y;
1310   GtkPlotVector ticks_direction, center, aux;
1311   gdouble proj;
1312   gboolean veto = FALSE;
1313 
1314   widget = GTK_WIDGET(plot);
1315   pc = GTK_PLOT(plot)->pc;
1316 
1317   xp = GTK_PLOT(plot)->internal_allocation.x;
1318   yp = GTK_PLOT(plot)->internal_allocation.y;
1319   width = GTK_PLOT(plot)->internal_allocation.width;
1320   height = GTK_PLOT(plot)->internal_allocation.height;
1321 
1322   size = MIN(width, height) / SQRT2;
1323   m = GTK_PLOT(plot)->magnification;
1324 
1325   gtk_plot_pc_set_color (pc, &axis->labels_attr.fg);
1326 
1327   gtk_plot_text_get_size("0", 0, axis->labels_attr.font, roundint(axis->labels_attr.height * m), &text_width, &text_height, &ascent, &descent);
1328 
1329   switch(axis->labels_attr.angle){
1330     case 0:
1331            y += text_height / 2.;
1332            break;
1333     case 90:
1334            break;
1335     case 180:
1336            y -= text_height / 2.;
1337            break;
1338     case 270:
1339            break;
1340   }
1341 
1342   tick = axis->labels_attr;
1343 
1344   center.x = (plot->ax->ticks.max + plot->ax->ticks.min) / 2.0;
1345   center.y = (plot->ay->ticks.max + plot->ay->ticks.min) / 2.0;
1346   center.z = (plot->az->ticks.max + plot->az->ticks.min) / 2.0;
1347 
1348   ticks_direction.x = axis->origin.x + delta.x - center.x;
1349   ticks_direction.y = axis->origin.y + delta.y - center.y;
1350   ticks_direction.z = axis->origin.z + delta.z - center.z;
1351 
1352   proj = ticks_direction.x * axis->direction.x +
1353          ticks_direction.y * axis->direction.y +
1354          ticks_direction.z * axis->direction.z;
1355 
1356   ticks_direction.x -= proj * axis->direction.x;
1357   ticks_direction.y -= proj * axis->direction.y;
1358   ticks_direction.z -= proj * axis->direction.z;
1359 
1360   proj = sqrt(ticks_direction.x * ticks_direction.x +
1361               ticks_direction.y * ticks_direction.y +
1362               ticks_direction.z * ticks_direction.z);
1363 
1364   ticks_direction.x /= proj;
1365   ticks_direction.y /= proj;
1366   ticks_direction.z /= proj;
1367 
1368   aux = ticks_direction;
1369 
1370   ticks_direction.x = aux.x*plot->e1.x + aux.y*plot->e2.x + aux.z*plot->e3.x;
1371   ticks_direction.y = aux.x*plot->e1.y + aux.y*plot->e2.y + aux.z*plot->e3.y;
1372   ticks_direction.z = aux.x*plot->e1.z + aux.y*plot->e2.z + aux.z*plot->e3.z;
1373 
1374   for(ntick = 0; ntick < axis->ticks.nticks; ntick++){
1375     if(axis->ticks.values[ntick].minor) continue;
1376     xx = axis->ticks.values[ntick].value;
1377     gtk_plot3d_get_pixel(plot,
1378                          axis->origin.x + axis->direction.x * xx + delta.x,
1379                          axis->origin.y + axis->direction.y * xx + delta.y,
1380                          axis->origin.z + axis->direction.z * xx + delta.z,
1381                          &ox, &oy, &oz);
1382 
1383     tick.x = ox +  axis->labels_offset * ticks_direction.x;
1384     tick.y = oy +  axis->labels_offset * ticks_direction.y;
1385 
1386     tick_value = axis->ticks.values[ntick].value;
1387 
1388     if(tick_value >= axis->ticks.min-1.e-9){
1389       if(!axis->custom_labels){
1390         gtk_plot_axis_parse_label(axis, tick_value, axis->label_precision, axis->label_style, label);
1391       }
1392       else
1393       {
1394         gtk_signal_emit_by_name(GTK_OBJECT(axis), "tick_label",
1395                                 &tick_value, label, &veto);
1396         if(!veto)
1397           gtk_plot_axis_parse_label(axis, tick_value, axis->label_precision, axis->label_style, label);
1398       }
1399       tick.text = label;
1400 
1401       if(axis->label_mask == GTK_PLOT_LABEL_OUT){
1402          tick.x = (gdouble)tick.x / (gdouble)widget->allocation.width;
1403          tick.y = (gdouble)tick.y / (gdouble)widget->allocation.height;
1404          gtk_plot_draw_text(GTK_PLOT(plot), tick);
1405       }
1406     }
1407   }
1408 
1409   if(axis->title_visible && axis->title.text)
1410        {
1411          title = axis->title;
1412 
1413          gtk_plot3d_get_pixel(plot,
1414                        axis->origin.x + center.x * axis->direction.x + delta.x,
1415                        axis->origin.y + center.y * axis->direction.y + delta.y,
1416                        axis->origin.z + center.z * axis->direction.z + delta.z,
1417                        &ox, &oy, &oz);
1418 
1419          title.x = ox + plot->titles_offset * ticks_direction.x;
1420          title.y = oy + plot->titles_offset * ticks_direction.y;
1421 
1422          title.x = title.x / (gdouble)widget->allocation.width;
1423          title.y = title.y / (gdouble)widget->allocation.height;
1424 
1425          gtk_plot_draw_text(GTK_PLOT(plot), title);
1426        }
1427 }
1428 
1429 gdouble
get_clean_tick_size(gdouble delta)1430 get_clean_tick_size(gdouble delta)
1431 {
1432   gint magnitude;
1433   delta/= 5.0;
1434   if (delta<0.0) delta*= -1.0;
1435   magnitude= (gint)(floor(log10(delta)));
1436   return ceil(delta/pow(10,magnitude))*pow(10,magnitude);
1437 }
1438 
1439 
1440 /******************************************
1441  ******************************************/
1442 void
gtk_plot3d_autoscale(GtkPlot3D * plot)1443 gtk_plot3d_autoscale(GtkPlot3D *plot)
1444 {
1445   GList *datasets;
1446   gdouble xmin, xmax, ymin, ymax, zmin, zmax;
1447   gint px, py, pz;
1448   gint first=1;
1449 
1450   if(!GTK_PLOT(plot)->data_sets) return;
1451 
1452   xmin = GTK_PLOT(plot)->bottom->ticks.max;
1453   xmax = GTK_PLOT(plot)->bottom->ticks.min;
1454   ymin = GTK_PLOT(plot)->left->ticks.max;
1455   ymax = GTK_PLOT(plot)->left->ticks.min;
1456   zmin = GTK_PLOT(plot)->top->ticks.max;
1457   zmax = GTK_PLOT(plot)->top->ticks.min;
1458 
1459   datasets = GTK_PLOT(plot)->data_sets;
1460 
1461   while(datasets){
1462     GtkPlotData *data;
1463     gint i;
1464 
1465     data = GTK_PLOT_DATA(datasets->data);
1466 
1467     if(!data->is_function){
1468       if(GTK_IS_PLOT_SURFACE(data))
1469         if(GTK_PLOT_SURFACE(data)->use_amplitud)
1470           gtk_plot_data_gradient_autoscale_a(data);
1471         else
1472           gtk_plot_data_gradient_autoscale_z(data);
1473       else
1474         gtk_plot_data_gradient_autoscale_a(data);
1475 
1476       for (i = 0; i < data->num_points; i++){
1477         gdouble x, y, z, a, dx, dy, dz, da;
1478         gchar *label;
1479         gboolean error;
1480 
1481         gtk_plot_data_get_point(data, i,
1482                        &x, &y, &z, &a, &dx, &dy, &dz, &da, &label, &error);
1483 	if (first) {
1484 	  first = 0; xmin = xmax = x; ymin = ymax = y; zmin = zmax = z;
1485 	} else {
1486           xmin = MIN(xmin, x);
1487 	  xmax = MAX(xmax, x);
1488 	  ymin = MIN(ymin, y);
1489 	  ymax = MAX(ymax, y);
1490 	  zmin = MIN(zmin, z);
1491 	  zmax = MAX(zmax, z);
1492 	}
1493       }
1494     }
1495 
1496     datasets = datasets->next;
1497   }
1498 
1499   gtk_plot_axis_ticks_autoscale(plot->ax, xmin, xmax, &px);
1500   gtk_plot_axis_ticks_autoscale(plot->ay, ymin, ymax, &py);
1501   gtk_plot_axis_ticks_autoscale(plot->az, zmin, zmax, &pz);
1502 
1503   plot->ax->label_precision = px;
1504   plot->ay->label_precision = py;
1505   plot->az->label_precision = pz;
1506 
1507   GTK_PLOT(plot)->xmin = plot->ax->ticks.min;
1508   GTK_PLOT(plot)->xmax = plot->ax->ticks.max;
1509   GTK_PLOT(plot)->ymin = plot->ay->ticks.min;
1510   GTK_PLOT(plot)->ymax = plot->ay->ticks.max;
1511   plot->zmin = plot->az->ticks.min;
1512   plot->zmax = plot->az->ticks.max;
1513 
1514   gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", TRUE);
1515   gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed");
1516 }
1517 
1518 
1519 void
gtk_plot3d_rotate(GtkPlot3D * plot,gdouble a1,gdouble a2,gdouble a3)1520 gtk_plot3d_rotate(GtkPlot3D *plot, gdouble a1, gdouble a2, gdouble a3)
1521 {
1522   gtk_plot3d_rotate_vector(plot, &plot->e1, a1, a2, a3);
1523   gtk_plot3d_rotate_vector(plot, &plot->e2, a1, a2, a3);
1524   gtk_plot3d_rotate_vector(plot, &plot->e3, a1, a2, a3);
1525 
1526   gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE);
1527   gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed");
1528 }
1529 
1530 void
gtk_plot3d_rotate_vector(GtkPlot3D * plot,GtkPlotVector * vector,gdouble a1,gdouble a2,gdouble a3)1531 gtk_plot3d_rotate_vector(GtkPlot3D *plot,
1532                           GtkPlotVector *vector,
1533                           gdouble a1, gdouble a2, gdouble a3)
1534 {
1535   GtkPlotVector v;
1536   gdouble cos1, sin1;
1537   gdouble cos2, sin2;
1538   gdouble cos3, sin3;
1539 
1540   if(a1 < 0) a1 = 360 + a1;
1541   if(a2 < 0) a2 = 360 + a2;
1542   if(a3 < 0) a3 = 360 + a3;
1543 
1544   cos1 = plot->ncos[(int)a1];
1545   sin1 = plot->nsin[(int)a1];
1546   cos2 = plot->ncos[(int)a2];
1547   sin2 = plot->nsin[(int)a2];
1548   cos3 = plot->ncos[(int)a3];
1549   sin3 = plot->nsin[(int)a3];
1550 
1551   v.y = vector->y*cos1 - vector->z*sin1;
1552   v.z = vector->z*cos1 + vector->y*sin1;
1553 
1554   vector->y = v.y;
1555   vector->z = v.z;
1556 
1557   v.z = vector->z*cos2 - vector->x*sin2;
1558   v.x = vector->x*cos2 + vector->z*sin2;
1559 
1560   vector->x = v.x;
1561   vector->z = v.z;
1562 
1563   v.x = vector->x*cos3 - vector->y*sin3;
1564   v.y = vector->y*cos3 + vector->x*sin3;
1565 
1566   vector->x = v.x;
1567   vector->y = v.y;
1568 }
1569 
1570 void
gtk_plot3d_get_pixel(GtkPlot3D * plot,gdouble x,gdouble y,gdouble z,gdouble * px,gdouble * py,gdouble * pz)1571 gtk_plot3d_get_pixel(GtkPlot3D *plot,
1572                      gdouble x, gdouble y, gdouble z,
1573                      gdouble *px, gdouble *py, gdouble *pz)
1574 {
1575   GTK_PLOT3D_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(plot)))->get_pixel(GTK_WIDGET(plot), x, y, z, px, py, pz);
1576 }
1577 
1578 static void
gtk_plot3d_real_get_pixel(GtkWidget * widget,gdouble x,gdouble y,gdouble z,gdouble * px,gdouble * py,gdouble * pz)1579 gtk_plot3d_real_get_pixel(GtkWidget *widget,
1580                           gdouble x, gdouble y, gdouble z,
1581                           gdouble *px, gdouble *py, gdouble *pz)
1582 {
1583   GtkPlot3D *plot;
1584   GtkPlotVector e1, e2, e3, center;
1585   gint xp, yp, width, height, size;
1586   gdouble rx, ry, rz;
1587   gdouble cx, cy, cz;
1588 
1589   plot = GTK_PLOT3D(widget);
1590   xp = GTK_PLOT(plot)->internal_allocation.x;
1591   yp = GTK_PLOT(plot)->internal_allocation.y;
1592   width = GTK_PLOT(plot)->internal_allocation.width;
1593   height =GTK_PLOT(plot)->internal_allocation.height;
1594 
1595   size = MIN(width, height) / SQRT2;
1596   e1 = plot->e1;
1597   e2 = plot->e2;
1598   e3 = plot->e3;
1599 
1600   ry = gtk_plot_axis_ticks_transform(plot->ay, y);
1601   rx = gtk_plot_axis_ticks_transform(plot->ax, x);
1602   rz = gtk_plot_axis_ticks_transform(plot->az, z);
1603 
1604   center = plot->center;
1605 
1606   cx = -(center.x * e1.x + center.y * e2.x + center.z * e3.x);
1607   cy = -(center.x * e1.y + center.y * e2.y + center.z * e3.y);
1608   cz = -(center.x * e1.z + center.y * e2.z + center.z * e3.z);
1609 
1610   *px = xp + width / 2.;
1611   *py = yp + height / 2.;
1612   *pz = 0.0;
1613 
1614   *px += (cx + rx * e1.x + ry * e2.x + rz * e3.x) * size;
1615   *py += (cy + rx * e1.y + ry * e2.y + rz * e3.y) * size;
1616   *pz += (cz + rx * e1.z + ry * e2.z + rz * e3.z) * size;
1617 }
1618 
1619 /***********************************************************/
1620 
1621 
1622 /***********************************************************
1623  * gtk_plot3d_set_xrange
1624  * gtk_plot3d_set_yrange
1625  * gtk_plot3d_set_zrange
1626  * gtk_plot3d_set_xfactor
1627  * gtk_plot3d_set_yfactor
1628  * gtk_plot3d_set_zfactor
1629  * gtk_plot3d_get_xfactor
1630  * gtk_plot3d_get_yfactor
1631  * gtk_plot3d_get_zfactor
1632  ***********************************************************/
1633 void
gtk_plot3d_set_xrange(GtkPlot3D * plot,gdouble min,gdouble max)1634 gtk_plot3d_set_xrange(GtkPlot3D *plot, gdouble min, gdouble max)
1635 {
1636   if(min > max) return;
1637 
1638   GTK_PLOT(plot)->xmin = min;
1639   GTK_PLOT(plot)->xmax = max;
1640   plot->ax->ticks.min = min;
1641   plot->ax->ticks.max = max;
1642   gtk_plot_axis_ticks_recalc(plot->ax);
1643 
1644   gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", TRUE);
1645   gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed");
1646 }
1647 
1648 void
gtk_plot3d_set_yrange(GtkPlot3D * plot,gdouble min,gdouble max)1649 gtk_plot3d_set_yrange(GtkPlot3D *plot, gdouble min, gdouble max)
1650 {
1651   if(min > max) return;
1652 
1653   GTK_PLOT(plot)->ymin = min;
1654   GTK_PLOT(plot)->ymax = max;
1655   plot->ay->ticks.min = min;
1656   plot->ay->ticks.max = max;
1657   gtk_plot_axis_ticks_recalc(plot->ay);
1658 
1659   gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", TRUE);
1660   gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed");
1661 }
1662 
1663 void
gtk_plot3d_set_zrange(GtkPlot3D * plot,gdouble min,gdouble max)1664 gtk_plot3d_set_zrange(GtkPlot3D *plot, gdouble min, gdouble max)
1665 {
1666   if(min > max) return;
1667 
1668   plot->zmin = min;
1669   plot->zmax = max;
1670   plot->az->ticks.min = min;
1671   plot->az->ticks.max = max;
1672   gtk_plot_axis_ticks_recalc(plot->az);
1673 
1674   gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", TRUE);
1675   gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed");
1676 }
1677 
1678 void
gtk_plot3d_set_xfactor(GtkPlot3D * plot,gdouble xfactor)1679 gtk_plot3d_set_xfactor(GtkPlot3D *plot, gdouble xfactor)
1680 {
1681   if(xfactor <= 0.0) return;
1682 
1683   plot->e1.x /= plot->xfactor;
1684   plot->e1.y /= plot->xfactor;
1685   plot->e1.z /= plot->xfactor;
1686 
1687   plot->xfactor = xfactor;
1688 
1689   plot->e1.x *= plot->xfactor;
1690   plot->e1.y *= plot->xfactor;
1691   plot->e1.z *= plot->xfactor;
1692 
1693   plot->ax->direction = plot->e1;
1694 
1695   gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE);
1696   gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed");
1697 }
1698 
1699 void
gtk_plot3d_set_yfactor(GtkPlot3D * plot,gdouble yfactor)1700 gtk_plot3d_set_yfactor(GtkPlot3D *plot, gdouble yfactor)
1701 {
1702   if(yfactor <= 0.0) return;
1703 
1704   plot->e2.x /= plot->yfactor;
1705   plot->e2.y /= plot->yfactor;
1706   plot->e2.z /= plot->yfactor;
1707 
1708   plot->yfactor = yfactor;
1709 
1710   plot->e2.x *= plot->yfactor;
1711   plot->e2.y *= plot->yfactor;
1712   plot->e2.z *= plot->yfactor;
1713 
1714   plot->ay->direction = plot->e1;
1715 
1716   gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE);
1717   gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed");
1718 }
1719 
1720 void
gtk_plot3d_set_zfactor(GtkPlot3D * plot,gdouble zfactor)1721 gtk_plot3d_set_zfactor(GtkPlot3D *plot, gdouble zfactor)
1722 {
1723   if(zfactor <= 0.0) return;
1724 
1725   plot->e3.x /= plot->zfactor;
1726   plot->e3.y /= plot->zfactor;
1727   plot->e3.z /= plot->zfactor;
1728 
1729   plot->zfactor = zfactor;
1730 
1731   plot->e3.x *= plot->zfactor;
1732   plot->e3.y *= plot->zfactor;
1733   plot->e3.z *= plot->zfactor;
1734 
1735   plot->az->direction = plot->e1;
1736 
1737   gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE);
1738   gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed");
1739 }
1740 
1741 gdouble
gtk_plot3d_get_xfactor(GtkPlot3D * plot)1742 gtk_plot3d_get_xfactor(GtkPlot3D *plot)
1743 {
1744   return (plot->xfactor);
1745 }
1746 
1747 gdouble
gtk_plot3d_get_yfactor(GtkPlot3D * plot)1748 gtk_plot3d_get_yfactor(GtkPlot3D *plot)
1749 {
1750   return (plot->yfactor);
1751 }
1752 
1753 gdouble
gtk_plot3d_get_zfactor(GtkPlot3D * plot)1754 gtk_plot3d_get_zfactor(GtkPlot3D *plot)
1755 {
1756   return (plot->zfactor);
1757 }
1758 
1759 
1760 /***********************************************************
1761  * gtk_plot3d_plane_set_color
1762  * gtk_plot3d_plane_set_visible
1763  * gtk_plot3d_plane_visible
1764  ***********************************************************/
1765 
1766 void
gtk_plot3d_plane_set_color(GtkPlot3D * plot,GtkPlotPlane plane,const GdkColor * color)1767 gtk_plot3d_plane_set_color      (GtkPlot3D *plot,
1768                                  GtkPlotPlane plane,
1769                                  const GdkColor *color)
1770 {
1771 
1772   switch(plane){
1773     case GTK_PLOT_PLANE_XY:
1774       plot->color_xy = *color;
1775       break;
1776     case GTK_PLOT_PLANE_YZ:
1777       plot->color_yz = *color;
1778       break;
1779     case GTK_PLOT_PLANE_ZX:
1780       plot->color_zx = *color;
1781       break;
1782     default:
1783       break;
1784   }
1785 
1786 }
1787 
1788 void
gtk_plot3d_plane_set_visible(GtkPlot3D * plot,GtkPlotPlane plane,gboolean visible)1789 gtk_plot3d_plane_set_visible    (GtkPlot3D *plot,
1790                                  GtkPlotPlane plane,
1791                                  gboolean visible)
1792 {
1793 
1794   switch(plane){
1795     case GTK_PLOT_PLANE_XY:
1796       plot->xy_visible = visible;
1797       break;
1798     case GTK_PLOT_PLANE_YZ:
1799       plot->yz_visible = visible;
1800       break;
1801     case GTK_PLOT_PLANE_ZX:
1802       plot->zx_visible = visible;
1803       break;
1804     default:
1805       break;
1806   }
1807 
1808 }
1809 
1810 gboolean
gtk_plot3d_plane_visible(GtkPlot3D * plot,GtkPlotPlane plane)1811 gtk_plot3d_plane_visible    (GtkPlot3D *plot,
1812                                  GtkPlotPlane plane)
1813 {
1814   gboolean visible = FALSE;
1815 
1816   switch(plane){
1817     case GTK_PLOT_PLANE_XY:
1818       visible = plot->xy_visible;
1819       break;
1820     case GTK_PLOT_PLANE_YZ:
1821       visible = plot->yz_visible;
1822       break;
1823     case GTK_PLOT_PLANE_ZX:
1824       visible = plot->zx_visible;
1825       break;
1826     default:
1827       break;
1828   }
1829 
1830   return visible;
1831 }
1832 
1833 
1834 /***********************************************************
1835  * gtk_plot3d_corner_set_visible
1836  * gtk_plot3d_corner_visible
1837  * gtk_plot3d_corner_set_attributes
1838  * gtk_plot3d_corner_get_attributes
1839  * gtk_plot3d_frame_set_attributes
1840  * gtk_plot3d_frame_get_attributes
1841  * gtk_plot3d_show_labels
1842  * gtk_plot3d_show_title
1843  * gtk_plot3d_hide_title
1844  * gtk_plot3d_show_major_ticks
1845  * gtk_plot3d_show_minor_ticks
1846  * gtk_plot3d_set_ticks
1847  * gtk_plot3d_set_major_ticks
1848  * gtk_plot3d_set_minor_ticks
1849  * gtk_plot3d_set_ticks_length
1850  * gtk_plot3d_set_ticks_width
1851  * gtk_plot3d_show_ticks
1852  * gtk_plot3d_set_titles_offset
1853  * gtk_plot3d_get_titles_offset
1854  ***********************************************************/
1855 void
gtk_plot3d_corner_set_visible(GtkPlot3D * plot,gboolean visible)1856 gtk_plot3d_corner_set_visible(GtkPlot3D *plot, gboolean visible)
1857 {
1858   plot->corner_visible = visible;
1859 }
1860 
1861 gboolean
gtk_plot3d_corner_visible(GtkPlot3D * plot)1862 gtk_plot3d_corner_visible(GtkPlot3D *plot)
1863 {
1864   return (plot->corner_visible);
1865 }
1866 
1867 void
gtk_plot3d_corner_set_attributes(GtkPlot3D * plot,GtkPlotLineStyle style,gfloat width,const GdkColor * color)1868 gtk_plot3d_corner_set_attributes   (GtkPlot3D *plot,
1869                                     GtkPlotLineStyle style,
1870                                     gfloat width,
1871                                     const GdkColor *color)
1872 {
1873   plot->corner.line_style = style;
1874   plot->corner.line_width = width;
1875   if(color) plot->corner.color = *color;
1876 }
1877 
1878 
1879 void
gtk_plot3d_corner_get_attributes(GtkPlot3D * plot,GtkPlotLineStyle * style,gfloat * width,GdkColor * color)1880 gtk_plot3d_corner_get_attributes   (GtkPlot3D *plot,
1881                                     GtkPlotLineStyle *style,
1882                                     gfloat *width,
1883                                     GdkColor *color)
1884 {
1885   *style = plot->corner.line_style;
1886   *width = plot->corner.line_width;
1887   *color = plot->corner.color;
1888 }
1889 
1890 void
gtk_plot3d_frame_set_attributes(GtkPlot3D * plot,GtkPlotLineStyle style,gfloat width,const GdkColor * color)1891 gtk_plot3d_frame_set_attributes   (GtkPlot3D *plot,
1892                                    GtkPlotLineStyle style,
1893                                    gfloat width,
1894                                    const GdkColor *color)
1895 {
1896   plot->frame.line_style = style;
1897   plot->frame.line_width = width;
1898   if(color) plot->frame.color = *color;
1899 }
1900 
1901 void
gtk_plot3d_frame_get_attributes(GtkPlot3D * plot,GtkPlotLineStyle * style,gfloat * width,GdkColor * color)1902 gtk_plot3d_frame_get_attributes   (GtkPlot3D *plot,
1903                                    GtkPlotLineStyle *style,
1904                                    gfloat *width,
1905                                    GdkColor *color)
1906 {
1907   *style = plot->frame.line_style;
1908   *width = plot->frame.line_width;
1909   *color = plot->frame.color;
1910 }
1911 
1912 GtkPlotAxis *
gtk_plot3d_get_axis(GtkPlot3D * plot,GtkPlotOrientation orientation)1913 gtk_plot3d_get_axis(GtkPlot3D *plot, GtkPlotOrientation orientation)
1914 {
1915   GtkPlotAxis *axis = NULL;
1916 
1917   switch(orientation){
1918     case GTK_PLOT_AXIS_X:
1919       axis = plot->ax;
1920       break;
1921     case GTK_PLOT_AXIS_Y:
1922       axis = plot->ay;
1923       break;
1924     case GTK_PLOT_AXIS_Z:
1925       axis = plot->az;
1926       break;
1927     default:
1928       axis = NULL;
1929       break;
1930   }
1931 
1932   return axis;
1933 }
1934 
1935 GtkPlotAxis *
gtk_plot3d_get_side(GtkPlot3D * plot,GtkPlotSide side)1936 gtk_plot3d_get_side(GtkPlot3D *plot, GtkPlotSide side)
1937 {
1938   GtkPlotAxis *axis = NULL;
1939 
1940   switch(side){
1941     case GTK_PLOT_SIDE_XY:
1942       axis = &plot->xy;
1943       break;
1944     case GTK_PLOT_SIDE_XZ:
1945       axis = &plot->xz;
1946       break;
1947     case GTK_PLOT_SIDE_YX:
1948       axis = &plot->yx;
1949       break;
1950     case GTK_PLOT_SIDE_YZ:
1951       axis = &plot->yz;
1952       break;
1953     case GTK_PLOT_SIDE_ZX:
1954       axis = &plot->zx;
1955       break;
1956     case GTK_PLOT_SIDE_ZY:
1957       axis = &plot->zy;
1958       break;
1959     default:
1960       axis = NULL;
1961   }
1962 
1963   return axis;
1964 }
1965 
1966 void
gtk_plot3d_show_labels(GtkPlot3D * plot,GtkPlotSide side,gint label_mask)1967 gtk_plot3d_show_labels     (GtkPlot3D *plot,
1968 			    GtkPlotSide side,
1969                             gint label_mask)
1970 {
1971   GtkPlotAxis *axis;
1972 
1973   axis = gtk_plot3d_get_side(plot, side);
1974 
1975   axis->label_mask = label_mask;
1976 }
1977 
1978 void
gtk_plot3d_show_title(GtkPlot3D * plot,GtkPlotSide side)1979 gtk_plot3d_show_title     (GtkPlot3D *plot,
1980 			   GtkPlotSide side)
1981 {
1982   GtkPlotAxis *axis;
1983 
1984   axis = gtk_plot3d_get_side(plot, side);
1985 
1986   axis->title_visible = TRUE;
1987 }
1988 
1989 void
gtk_plot3d_hide_title(GtkPlot3D * plot,GtkPlotSide side)1990 gtk_plot3d_hide_title     (GtkPlot3D *plot,
1991 			   GtkPlotSide side)
1992 {
1993   GtkPlotAxis *axis;
1994 
1995   axis = gtk_plot3d_get_side(plot, side);
1996 
1997   axis->title_visible = FALSE;
1998 }
1999 
2000 
2001 void
gtk_plot3d_show_major_ticks(GtkPlot3D * plot,GtkPlotSide side,gint ticks_mask)2002 gtk_plot3d_show_major_ticks (GtkPlot3D *plot,
2003 			     GtkPlotSide side,
2004                              gint ticks_mask)
2005 {
2006   GtkPlotAxis *axis;
2007 
2008   axis = gtk_plot3d_get_side(plot, side);
2009 
2010   axis->major_mask = ticks_mask;
2011 }
2012 
2013 void
gtk_plot3d_show_minor_ticks(GtkPlot3D * plot,GtkPlotSide side,gint ticks_mask)2014 gtk_plot3d_show_minor_ticks(GtkPlot3D *plot,
2015 			    GtkPlotSide side,
2016                             gint ticks_mask)
2017 {
2018   GtkPlotAxis *axis;
2019 
2020   axis = gtk_plot3d_get_side(plot, side);
2021 
2022   axis->minor_mask = ticks_mask;
2023 }
2024 
2025 void
gtk_plot3d_set_ticks(GtkPlot3D * plot,GtkPlotOrientation direction,gdouble major_step,gint nminor)2026 gtk_plot3d_set_ticks        (GtkPlot3D *plot,
2027 			     GtkPlotOrientation direction,
2028                              gdouble major_step,
2029                              gint nminor)
2030 {
2031   GtkPlotAxis *axis;
2032 
2033   axis = gtk_plot3d_get_axis(plot, direction);
2034 
2035   axis->ticks.step = major_step;
2036 
2037   axis->ticks.nminor = nminor;
2038 }
2039 
2040 void
gtk_plot3d_set_major_ticks(GtkPlot3D * plot,GtkPlotOrientation direction,gdouble major_step)2041 gtk_plot3d_set_major_ticks  (GtkPlot3D *plot,
2042                              GtkPlotOrientation direction,
2043                              gdouble major_step)
2044 {
2045   GtkPlotAxis *axis;
2046 
2047   axis = gtk_plot3d_get_axis(plot, direction);
2048 
2049   axis->ticks.step = major_step;
2050 }
2051 
2052 void
gtk_plot3d_set_minor_ticks(GtkPlot3D * plot,GtkPlotOrientation direction,gint nminor)2053 gtk_plot3d_set_minor_ticks  (GtkPlot3D *plot,
2054                              GtkPlotOrientation direction,
2055                              gint nminor)
2056 {
2057   GtkPlotAxis *axis;
2058 
2059   axis = gtk_plot3d_get_axis(plot, direction);
2060 
2061   axis->ticks.nminor = nminor;
2062 }
2063 
2064 void
gtk_plot3d_set_ticks_length(GtkPlot3D * plot,GtkPlotOrientation direction,gint length)2065 gtk_plot3d_set_ticks_length  (GtkPlot3D *plot,
2066                               GtkPlotOrientation direction,
2067                               gint length)
2068 {
2069   GtkPlotAxis *axis;
2070 
2071   axis = gtk_plot3d_get_axis(plot, direction);
2072 
2073   axis->ticks_length = length;
2074 }
2075 
2076 void
gtk_plot3d_set_ticks_width(GtkPlot3D * plot,GtkPlotOrientation direction,gfloat width)2077 gtk_plot3d_set_ticks_width   (GtkPlot3D *plot,
2078                               GtkPlotOrientation direction,
2079                               gfloat width)
2080 {
2081   GtkPlotAxis *axis;
2082 
2083   axis = gtk_plot3d_get_axis(plot, direction);
2084 
2085   axis->ticks_width = width;
2086 }
2087 
2088 void
gtk_plot3d_show_ticks(GtkPlot3D * plot,GtkPlotSide side,gint major_mask,gint minor_mask)2089 gtk_plot3d_show_ticks        (GtkPlot3D *plot,
2090                               GtkPlotSide side,
2091                               gint major_mask,
2092                               gint minor_mask)
2093 {
2094   GtkPlotAxis *axis;
2095 
2096   axis = gtk_plot3d_get_side(plot, side);
2097 
2098   axis->major_mask = major_mask;
2099   axis->minor_mask = minor_mask;
2100 }
2101 
2102 
2103 void
gtk_plot3d_set_titles_offset(GtkPlot3D * plot,gint offset)2104 gtk_plot3d_set_titles_offset    (GtkPlot3D *plot,
2105                                  gint offset)
2106 {
2107   plot->titles_offset = offset;
2108 }
2109 
2110 gint
gtk_plot3d_get_titles_offset(GtkPlot3D * plot)2111 gtk_plot3d_get_titles_offset    (GtkPlot3D *plot)
2112 {
2113   return (plot->titles_offset);
2114 }
2115 
2116 /***********************************************************
2117  * gtk_plot3d_major_grids_set_visible
2118  * gtk_plot3d_major_grids_visible
2119  * gtk_plot3d_minor_grids_set_visible
2120  * gtk_plot3d_minor_grids_visible
2121  * gtk_plot3d_major_grids_set_attributes
2122  * gtk_plot3d_minor_grids_set_attributes
2123  * gtk_plot3d_major_grids_get_attributes
2124  * gtk_plot3d_minor_grids_get_attributes
2125  ***********************************************************/
2126 
2127 void
gtk_plot3d_major_grids_set_visible(GtkPlot3D * plot,gboolean x,gboolean y,gboolean z)2128 gtk_plot3d_major_grids_set_visible    (GtkPlot3D *plot,
2129                                        gboolean x,
2130                                        gboolean y,
2131                                        gboolean z)
2132 {
2133   plot->ax->show_major_grid = x;
2134   plot->ay->show_major_grid = y;
2135   plot->az->show_major_grid = z;
2136 }
2137 
2138 void
gtk_plot3d_minor_grids_set_visible(GtkPlot3D * plot,gboolean x,gboolean y,gboolean z)2139 gtk_plot3d_minor_grids_set_visible    (GtkPlot3D *plot,
2140                                        gboolean x,
2141                                        gboolean y,
2142                                        gboolean z)
2143 {
2144   plot->ax->show_minor_grid = x;
2145   plot->ay->show_minor_grid = y;
2146   plot->az->show_minor_grid = z;
2147 }
2148 
2149 void
gtk_plot3d_major_grids_visible(GtkPlot3D * plot,gboolean * x,gboolean * y,gboolean * z)2150 gtk_plot3d_major_grids_visible    (GtkPlot3D *plot,
2151                                        gboolean *x,
2152                                        gboolean *y,
2153                                        gboolean *z)
2154 {
2155   *x = plot->ax->show_major_grid;
2156   *y = plot->ay->show_major_grid;
2157   *z = plot->az->show_major_grid;
2158 }
2159 
2160 void
gtk_plot3d_minor_grids_visible(GtkPlot3D * plot,gboolean * x,gboolean * y,gboolean * z)2161 gtk_plot3d_minor_grids_visible    (GtkPlot3D *plot,
2162                                        gboolean *x,
2163                                        gboolean *y,
2164                                        gboolean *z)
2165 {
2166   *x = plot->ax->show_minor_grid;
2167   *y = plot->ay->show_minor_grid;
2168   *z = plot->az->show_minor_grid;
2169 }
2170 
2171 void
gtk_plot3d_major_zgrid_set_attributes(GtkPlot3D * plot,GtkPlotLineStyle style,gfloat width,const GdkColor * color)2172 gtk_plot3d_major_zgrid_set_attributes    (GtkPlot3D *plot,
2173                                          GtkPlotLineStyle style,
2174                                          gfloat width,
2175                                          const GdkColor *color)
2176 {
2177   plot->az->major_grid.line_style = style;
2178   plot->az->major_grid.line_width = width;
2179   if(color) plot->az->major_grid.color = *color;
2180 }
2181 
2182 void
gtk_plot3d_minor_zgrid_set_attributes(GtkPlot3D * plot,GtkPlotLineStyle style,gfloat width,const GdkColor * color)2183 gtk_plot3d_minor_zgrid_set_attributes    (GtkPlot3D *plot,
2184                                          GtkPlotLineStyle style,
2185                                          gfloat width,
2186                                          const GdkColor *color)
2187 {
2188   plot->az->minor_grid.line_style = style;
2189   plot->az->minor_grid.line_width = width;
2190   if(color) plot->az->minor_grid.color = *color;
2191 }
2192 
2193 void
gtk_plot3d_major_zgrid_get_attributes(GtkPlot3D * plot,GtkPlotLineStyle * style,gfloat * width,GdkColor * color)2194 gtk_plot3d_major_zgrid_get_attributes    (GtkPlot3D *plot,
2195                                          GtkPlotLineStyle *style,
2196                                          gfloat *width,
2197                                          GdkColor *color)
2198 {
2199   *style = plot->az->major_grid.line_style;
2200   *width = plot->az->major_grid.line_width;
2201   *color = plot->az->major_grid.color;
2202 }
2203 
2204 void
gtk_plot3d_minor_zgrid_get_attributes(GtkPlot3D * plot,GtkPlotLineStyle * style,gfloat * width,GdkColor * color)2205 gtk_plot3d_minor_zgrid_get_attributes    (GtkPlot3D *plot,
2206                                          GtkPlotLineStyle *style,
2207                                          gfloat *width,
2208                                          GdkColor *color)
2209 {
2210   *style = plot->az->minor_grid.line_style;
2211   *width = plot->az->minor_grid.line_width;
2212   *color = plot->az->minor_grid.color;
2213 }
2214 
2215 /*******************************************
2216  * gtk_plot3d_reset_angles
2217  * gtk_plot3d_rotate_x
2218  * gtk_plot3d_rotate_y
2219  * gtk_plot3d_rotate_z
2220  *******************************************/
2221 void
gtk_plot3d_reset_angles(GtkPlot3D * plot)2222 gtk_plot3d_reset_angles(GtkPlot3D *plot)
2223 {
2224   plot->e1.x = plot->xfactor;
2225   plot->e1.y = 0.;
2226   plot->e1.z = 0.;
2227   plot->e2.x = 0.;
2228   plot->e2.y = -plot->yfactor;
2229   plot->e2.z = 0.;
2230   plot->e3.x = 0.;
2231   plot->e3.y = 0.;
2232   plot->e3.z = -plot->zfactor;
2233 
2234   gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE);
2235   gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed");
2236 }
2237 
2238 void
gtk_plot3d_rotate_x(GtkPlot3D * plot,gdouble angle)2239 gtk_plot3d_rotate_x(GtkPlot3D *plot, gdouble angle)
2240 {
2241   GtkPlotVector vector, aux, e1, e2, e3;
2242   gdouble c, s;
2243 
2244   angle = 360 - angle;
2245   c = plot->ncos[(int)angle];
2246   s = plot->nsin[(int)angle];
2247 
2248   e1 = plot->e1;
2249   e2 = plot->e2;
2250   e3 = plot->e3;
2251 
2252   vector.x = 0.0;
2253   vector.y = 1.0;
2254   vector.z = 0.0;
2255   aux = vector;
2256   aux.y = vector.y*c - vector.z*s;
2257   aux.z = vector.z*c + vector.y*s;
2258 
2259   plot->e2.x = aux.x * e1.x / plot->xfactor + aux.y * e2.x / plot->yfactor + aux.z * e3.x / plot->zfactor ;
2260   plot->e2.y = aux.x * e1.y / plot->xfactor + aux.y * e2.y / plot->yfactor + aux.z * e3.y / plot->zfactor ;
2261   plot->e2.z = aux.x * e1.z / plot->xfactor + aux.y * e2.z / plot->yfactor + aux.z * e3.z / plot->zfactor ;
2262 
2263   vector.x = 0.0;
2264   vector.y = 0.0;
2265   vector.z = 1.0;
2266   aux = vector;
2267   aux.y = vector.y*c - vector.z*s;
2268   aux.z = vector.z*c + vector.y*s;
2269 
2270   plot->e3.x = aux.x * e1.x / plot->xfactor + aux.y * e2.x / plot->yfactor + aux.z * e3.x / plot->zfactor ;
2271   plot->e3.y = aux.x * e1.y / plot->xfactor + aux.y * e2.y / plot->yfactor + aux.z * e3.y / plot->zfactor ;
2272   plot->e3.z = aux.x * e1.z / plot->xfactor + aux.y * e2.z / plot->yfactor + aux.z * e3.z / plot->zfactor ;
2273 
2274   plot->e1.x *= plot->xfactor;
2275   plot->e1.y *= plot->xfactor;
2276   plot->e1.z *= plot->xfactor;
2277   plot->e2.x *= plot->yfactor;
2278   plot->e2.y *= plot->yfactor;
2279   plot->e2.z *= plot->yfactor;
2280   plot->e3.x *= plot->zfactor;
2281   plot->e3.y *= plot->zfactor;
2282   plot->e3.z *= plot->zfactor;
2283 
2284   gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE);
2285   gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed");
2286 }
2287 
2288 void
gtk_plot3d_rotate_y(GtkPlot3D * plot,gdouble angle)2289 gtk_plot3d_rotate_y(GtkPlot3D *plot, gdouble angle)
2290 {
2291   GtkPlotVector vector, aux, e1, e2, e3;
2292   gdouble  c, s;
2293 
2294   angle = 360 - angle;
2295   c = plot->ncos[(int)angle];
2296   s = plot->nsin[(int)angle];
2297 
2298   e1 = plot->e1;
2299   e2 = plot->e2;
2300   e3 = plot->e3;
2301 
2302   vector.x = 1.0;
2303   vector.y = 0.0;
2304   vector.z = 0.0;
2305   aux = vector;
2306   aux.z = vector.z*c - vector.x*s;
2307   aux.x = vector.x*c + vector.z*s;
2308 
2309   plot->e1.x = aux.x * e1.x / plot->xfactor + aux.y * e2.x / plot->yfactor + aux.z * e3.x / plot->zfactor ;
2310   plot->e1.y = aux.x * e1.y / plot->xfactor + aux.y * e2.y / plot->yfactor + aux.z * e3.y / plot->zfactor ;
2311   plot->e1.z = aux.x * e1.z / plot->xfactor + aux.y * e2.z / plot->yfactor + aux.z * e3.z / plot->zfactor ;
2312 
2313   vector.x = 0.0;
2314   vector.y = 0.0;
2315   vector.z = 1.0;
2316   aux = vector;
2317   aux.z = vector.z*c - vector.x*s;
2318   aux.x = vector.x*c + vector.z*s;
2319 
2320   plot->e3.x = aux.x * e1.x / plot->xfactor + aux.y * e2.x / plot->yfactor + aux.z * e3.x / plot->zfactor ;
2321   plot->e3.y = aux.x * e1.y / plot->xfactor + aux.y * e2.y / plot->yfactor + aux.z * e3.y / plot->zfactor ;
2322   plot->e3.z = aux.x * e1.z / plot->xfactor + aux.y * e2.z / plot->yfactor + aux.z * e3.z / plot->zfactor ;
2323 
2324   plot->e1.x *= plot->xfactor;
2325   plot->e1.y *= plot->xfactor;
2326   plot->e1.z *= plot->xfactor;
2327   plot->e2.x *= plot->yfactor;
2328   plot->e2.y *= plot->yfactor;
2329   plot->e2.z *= plot->yfactor;
2330   plot->e3.x *= plot->zfactor;
2331   plot->e3.y *= plot->zfactor;
2332   plot->e3.z *= plot->zfactor;
2333 
2334   gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE);
2335   gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed");
2336 }
2337 
2338 void
gtk_plot3d_rotate_z(GtkPlot3D * plot,gdouble angle)2339 gtk_plot3d_rotate_z(GtkPlot3D *plot, gdouble angle)
2340 {
2341   GtkPlotVector vector, aux, e1, e2, e3;
2342   gdouble c, s;
2343 
2344   angle = 360 - angle;
2345   c = plot->ncos[(int)angle];
2346   s = plot->nsin[(int)angle];
2347 
2348   e1 = plot->e1;
2349   e2 = plot->e2;
2350   e3 = plot->e3;
2351 
2352   vector.x = 1.0;
2353   vector.y = 0.0;
2354   vector.z = 0.0;
2355   aux = vector;
2356   aux.x = vector.x*c - vector.y*s;
2357   aux.y = vector.y*c + vector.x*s;
2358 
2359   plot->e1.x = aux.x * e1.x / plot->xfactor + aux.y * e2.x / plot->yfactor + aux.z * e3.x / plot->zfactor ;
2360   plot->e1.y = aux.x * e1.y / plot->xfactor + aux.y * e2.y / plot->yfactor + aux.z * e3.y / plot->zfactor ;
2361   plot->e1.z = aux.x * e1.z / plot->xfactor + aux.y * e2.z / plot->yfactor + aux.z * e3.z / plot->zfactor ;
2362 
2363   vector.x = 0.0;
2364   vector.y = 1.0;
2365   vector.z = 0.0;
2366   aux = vector;
2367   aux.x = vector.x*c - vector.y*s;
2368   aux.y = vector.y*c + vector.x*s;
2369 
2370   plot->e2.x = aux.x * e1.x / plot->xfactor + aux.y * e2.x / plot->yfactor + aux.z * e3.x / plot->zfactor ;
2371   plot->e2.y = aux.x * e1.y / plot->xfactor + aux.y * e2.y / plot->yfactor + aux.z * e3.y / plot->zfactor ;
2372   plot->e2.z = aux.x * e1.z / plot->xfactor + aux.y * e2.z / plot->yfactor + aux.z * e3.z / plot->zfactor ;
2373 
2374   plot->e1.x *= plot->xfactor;
2375   plot->e1.y *= plot->xfactor;
2376   plot->e1.z *= plot->xfactor;
2377   plot->e2.x *= plot->yfactor;
2378   plot->e2.y *= plot->yfactor;
2379   plot->e2.z *= plot->yfactor;
2380   plot->e3.x *= plot->zfactor;
2381   plot->e3.y *= plot->zfactor;
2382   plot->e3.z *= plot->zfactor;
2383 
2384   gtk_signal_emit_by_name(GTK_OBJECT(plot), "update", FALSE);
2385   gtk_signal_emit_by_name(GTK_OBJECT(plot), "changed");
2386 }
2387 
2388 void
gtk_plot3d_set_scale(GtkPlot3D * plot,GtkPlotOrientation axis,GtkPlotScale scale)2389 gtk_plot3d_set_scale       (GtkPlot3D *plot,
2390                             GtkPlotOrientation axis,
2391                             GtkPlotScale scale)
2392 {
2393   GtkPlotAxis *ax;
2394   ax = gtk_plot3d_get_axis(plot, axis);
2395   ax->ticks.scale = scale;
2396 }
2397 
2398 GtkPlotScale
gtk_plot3d_get_scale(GtkPlot3D * plot,GtkPlotOrientation axis)2399 gtk_plot3d_get_scale       (GtkPlot3D *plot,
2400                             GtkPlotOrientation axis)
2401 {
2402   GtkPlotAxis *ax;
2403   ax = gtk_plot3d_get_axis(plot, axis);
2404   return(ax->ticks.scale);
2405 }
2406