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, >K_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