goffice r2151 - in trunk: . goffice/graph goffice/gtk plugins/plot_surface
- From: jbrefort svn gnome org
- To: svn-commits-list gnome org
- Subject: goffice r2151 - in trunk: . goffice/graph goffice/gtk plugins/plot_surface
- Date: Mon, 14 Jul 2008 05:55:05 +0000 (UTC)
Author: jbrefort
Date: Mon Jul 14 05:55:04 2008
New Revision: 2151
URL: http://svn.gnome.org/viewvc/goffice?rev=2151&view=rev
Log:
2008-07-14 Mariusz Adamski <mariusz adamski gmail com>
* goffice/graph/gog-3d-box.c: display3D axes and limit FoV to 90.
* goffice/graph/gog-axis-line.c: ditto.
* goffice/graph/gog-chart-map-3d.c: ditto.
* goffice/graph/gog-chart-map-3d.h: ditto.
* goffice/gtk/go-3d-rotation-sel.glade: ditto.
* plugins/plot_surface/gog-xyz.c: ditto.
Modified:
trunk/ChangeLog
trunk/goffice/graph/gog-3d-box.c
trunk/goffice/graph/gog-axis-line.c
trunk/goffice/graph/gog-chart-map-3d.c
trunk/goffice/graph/gog-chart-map-3d.h
trunk/goffice/graph/gog-chart.c
trunk/goffice/gtk/go-3d-rotation-sel.glade
trunk/plugins/plot_surface/gog-xyz.c
Modified: trunk/goffice/graph/gog-3d-box.c
==============================================================================
--- trunk/goffice/graph/gog-3d-box.c (original)
+++ trunk/goffice/graph/gog-3d-box.c Mon Jul 14 05:55:04 2008
@@ -231,16 +231,16 @@
switch (param_id) {
case BOX3D_PROP_PSI:
- box->psi = g_value_get_double (value);
+ box->psi = g_value_get_int (value) * M_PI / 180.;
break;
case BOX3D_PROP_THETA:
- box->theta = g_value_get_double (value);
+ box->theta = g_value_get_int (value) * M_PI / 180.;
break;
case BOX3D_PROP_PHI:
- box->phi = g_value_get_double (value);
+ box->phi = g_value_get_int (value) * M_PI / 180.;
break;
case BOX3D_PROP_FOV:
- box->fov = g_value_get_double (value);
+ box->fov = g_value_get_int (value) * M_PI / 180.;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
@@ -257,16 +257,16 @@
switch (param_id) {
case BOX3D_PROP_PSI:
- g_value_set_double (value, box->psi);
+ g_value_set_int (value, (int) (box->psi * 180. / M_PI));
break;
case BOX3D_PROP_THETA:
- g_value_set_double (value, box->theta);
+ g_value_set_int (value, (int) (box->theta * 180. / M_PI));
break;
case BOX3D_PROP_PHI:
- g_value_set_double (value, box->phi);
+ g_value_set_int (value, (int) (box->phi * 180. / M_PI));
break;
case BOX3D_PROP_FOV:
- g_value_set_double (value, box->fov);
+ g_value_set_int (value, (int) (box->fov * 180. / M_PI));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
@@ -285,31 +285,31 @@
/* Using 3.141593 instead of M_PI to avoid rounding errors */
g_object_class_install_property (gobject_klass, BOX3D_PROP_PSI,
- g_param_spec_double ("psi",
+ g_param_spec_int ("psi",
"Psi",
_("Euler angle psi"),
- 0.0, 2 * 3.141593, 70. / 180. * M_PI,
+ 0, 360, 70,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE
| GOG_PARAM_PERSISTENT));
g_object_class_install_property (gobject_klass, BOX3D_PROP_THETA,
- g_param_spec_double ("theta",
+ g_param_spec_int ("theta",
"Theta",
_("Euler angle theta"),
- 0.0, 3.141593, 10. / 180. * M_PI,
+ 0, 360, 10,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE
| GOG_PARAM_PERSISTENT));
g_object_class_install_property (gobject_klass, BOX3D_PROP_PHI,
- g_param_spec_double ("phi",
+ g_param_spec_int ("phi",
"Phi",
_("Euler angle phi"),
- 0.0, 2 * 3.141593, 270. / 180. * M_PI,
+ 0, 360, 270,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE
| GOG_PARAM_PERSISTENT));
g_object_class_install_property (gobject_klass, BOX3D_PROP_FOV,
- g_param_spec_double ("fov",
+ g_param_spec_int ("fov",
"FoV",
_("Field of view"),
- 0.0, 3.141593, 10. / 180. * M_PI,
+ 0, 90, 10,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE
| GOG_PARAM_PERSISTENT));
Modified: trunk/goffice/graph/gog-axis-line.c
==============================================================================
--- trunk/goffice/graph/gog-axis-line.c (original)
+++ trunk/goffice/graph/gog-axis-line.c Mon Jul 14 05:55:04 2008
@@ -25,6 +25,7 @@
#include <goffice/graph/gog-axis.h>
#include <goffice/graph/gog-chart.h>
#include <goffice/graph/gog-chart-map.h>
+#include <goffice/graph/gog-chart-map-3d.h>
#include <goffice/graph/gog-data-allocator.h>
#include <goffice/graph/gog-renderer.h>
#include <goffice/graph/gog-style.h>
@@ -280,8 +281,8 @@
crossed_type = GOG_AXIS_RADIAL;
break;
case GOG_AXIS_SET_X:
- break;
case GOG_AXIS_SET_XYZ:
+ break;
case GOG_AXIS_SET_ALL:
case GOG_AXIS_SET_NONE:
default:
@@ -614,6 +615,7 @@
if (axis_type == GOG_AXIS_X ||
axis_type == GOG_AXIS_Y ||
+ axis_type == GOG_AXIS_Z ||
axis_type == GOG_AXIS_RADIAL) {
w = glade_xml_get_widget (gui, "padding_spinbutton");
gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), axis_base->padding);
@@ -812,7 +814,8 @@
GogAxisType type = gog_axis_get_atype (axis_base->axis);
return (type == GOG_AXIS_X ||
- type == GOG_AXIS_Y);
+ type == GOG_AXIS_Y ||
+ type == GOG_AXIS_Z);
}
@@ -1769,14 +1772,207 @@
xyz_process (GogAxisBaseAction action, GogView *view, GogViewPadding *padding,
GogViewAllocation const *plot_area, double x, double y)
{
- GogAxisBase *axis_base = GOG_AXIS_BASE (view->model);
- GogAxisType axis_type = gog_axis_get_atype (axis_base->axis);
- g_return_val_if_fail (axis_type == GOG_AXIS_X ||
- axis_type == GOG_AXIS_Y ||
- axis_type == GOG_AXIS_Z, FALSE);
+ GogAxisBase *axis_base = GOG_AXIS_BASE (view->model);
+ GogAxisBaseView *axis_base_view = GOG_AXIS_BASE_VIEW (view);
+ GogAxisType axis_type = gog_axis_get_atype (axis_base->axis);
+ GogAxis *axis1, *axis2;
+ GogChartMap3D *c_map;
+ GogAxisMap *a_map;
+ GogViewAllocation axis_line_bbox;
+ GSList *axes;
+ GogAxisType perp_axis;
+ double ax, ay, az, bx, by, bz, ox, oy, dist, tmp;
+ double xposition, yposition, zposition;
+ double start, stop;
+ double *px[] = {&ax, &ax, &bx, &bx, &ax, &ax, &bx, &bx};
+ double *py[] = {&ay, &by, &by, &ay, &ay, &by, &by, &ay};
+ double *pz[] = {&az, &az, &az, &az, &bz, &bz, &bz, &bz};
+ double rx[8], ry[8], rz[8];
+
+ /* Note: Anti-clockwise order in each face,
+ * important for calculating normals */
+ const int faces[] = {
+ 3, 2, 1, 0, /* Bottom */
+ 4, 5, 6, 7, /* Top */
+ 0, 1, 5, 4, /* Left */
+ 2, 3, 7, 6, /* Right */
+ 1, 2, 6, 5, /* Front */
+ 0, 4, 7, 3 /* Back */
+ };
+ int i, vertex = 0, base = 0;
+ GOGeometrySide side = GO_SIDE_LEFT;
- return TRUE;
+ g_return_val_if_fail (axis_type == GOG_AXIS_X ||
+ axis_type == GOG_AXIS_Y ||
+ axis_type == GOG_AXIS_Z, FALSE);
+ if (!gog_object_is_visible (axis_base->axis))
+ return FALSE;
+
+ if (axis_type == GOG_AXIS_X) {
+ axes = gog_chart_get_axes (axis_base->chart, GOG_AXIS_Y);
+ axis1 = GOG_AXIS (axes->data);
+ axes = gog_chart_get_axes (axis_base->chart, GOG_AXIS_Z);
+ axis2 = GOG_AXIS (axes->data);
+ c_map = gog_chart_map_3d_new (axis_base->chart, plot_area,
+ axis_base->axis, axis1, axis2);
+ } else if (axis_type == GOG_AXIS_Y) {
+ axes = gog_chart_get_axes (axis_base->chart, GOG_AXIS_Z);
+ axis1 = GOG_AXIS (axes->data);
+ axes = gog_chart_get_axes (axis_base->chart, GOG_AXIS_X);
+ axis2 = GOG_AXIS (axes->data);
+ c_map = gog_chart_map_3d_new (axis_base->chart, plot_area,
+ axis2, axis_base->axis, axis1);
+ } else {
+ axes = gog_chart_get_axes (axis_base->chart, GOG_AXIS_X);
+ axis1 = GOG_AXIS (axes->data);
+ axes = gog_chart_get_axes (axis_base->chart, GOG_AXIS_Y);
+ axis2 = GOG_AXIS (axes->data);
+ c_map = gog_chart_map_3d_new (axis_base->chart, plot_area,
+ axis1, axis2, axis_base->axis);
+ }
+
+ a_map = gog_chart_map_3d_get_axis_map (c_map, 0);
+ gog_axis_map_get_bounds (a_map, &ax, &bx);
+ a_map = gog_chart_map_3d_get_axis_map (c_map, 1);
+ gog_axis_map_get_bounds (a_map, &ay, &by);
+ a_map = gog_chart_map_3d_get_axis_map (c_map, 2);
+ gog_axis_map_get_bounds (a_map, &az, &bz);
+
+ /* Projecting vertices */
+ for (i = 0; i < 8; ++i)
+ gog_chart_map_3d_to_view (c_map, *px[i], *py[i], *pz[i],
+ &rx[i], &ry[i], &rz[i]);
+
+ /* Determining base plane */
+ dist = ry[0] + ry[1] + ry[2] + ry[3];
+ for (i = 4; i < 24; i += 4) {
+ tmp = ry[faces[i]] + ry[faces[i + 1]]
+ + ry[faces[i + 2]] + ry[faces[i + 3]];
+ if (tmp > dist) {
+ dist = tmp;
+ base = i;
+ }
+ }
+ if (base == 0 || base == 4)
+ perp_axis = GOG_AXIS_Z;
+ else if (base == 8 || base == 12)
+ perp_axis = GOG_AXIS_X;
+ else
+ perp_axis = GOG_AXIS_Y;
+
+ /* Position of the centre of the base plane */
+ ox = 0.25 * (rx[faces[base]] + rx[faces[base + 1]]
+ + rx[faces[base + 2]] + rx[faces[base + 3]]);
+ oy = 0.25 * dist;
+
+ /* Choosing the most distant vertex with respect to the centre
+ * of the base plane */
+ dist = (rx[faces[base]] - ox);
+ tmp = (ry[faces[base]] - oy);
+ dist = dist * dist + tmp * tmp;
+ for (i = 1; i < 4; ++i) {
+ double dx = rx[faces[base + i]] - ox;
+ double dy = ry[faces[base + i]] - oy;
+ tmp = dx * dx + dy * dy;
+ if (tmp > dist) {
+ dist = tmp;
+ vertex = i;
+ }
+ }
+
+ if (axis_type != perp_axis) {
+ /* Here we're choosing one of the nearest neighbours
+ * of the vertex previously chosen */
+ int pvtx = (vertex + 3) % 4; /* Previous vertex */
+ int nvtx = (vertex + 1) % 4; /* Next vertex */
+ int prev = faces[base + pvtx];
+ int next = faces[base + nvtx];
+ int curr = faces[base + vertex];
+ tmp = (rx[next] - rx[curr]) * (ry[prev] - ry[curr])
+ - (ry[next] - ry[curr]) * (rx[prev] - rx[curr]);
+ /* If normal is negative, we're choosing vertex which
+ * is closer to the screen */
+ if ((tmp < 0 && rz[prev] < rz[next])
+ || (tmp > 0 && rz[prev] > rz[next]))
+ vertex = pvtx;
+ else
+ vertex = nvtx;
+ }
+
+ if (axis_type == GOG_AXIS_Z) {
+ xposition = *px[faces[base + vertex]];
+ yposition = *py[faces[base + vertex]];
+
+ a_map = gog_chart_map_3d_get_axis_map (c_map, 2);
+ gog_axis_map_get_extents (a_map, &start, &stop);
+ gog_chart_map_3d_to_view (c_map, xposition, yposition, start,
+ &ax, &ay, NULL);
+ gog_chart_map_3d_to_view (c_map, xposition, yposition, stop,
+ &bx, &by, NULL);
+ } else if (axis_type == GOG_AXIS_X) {
+ yposition = *py[faces[base + vertex]];
+ zposition = *pz[faces[base + vertex]];
+
+ a_map = gog_chart_map_3d_get_axis_map (c_map, 0);
+ gog_axis_map_get_extents (a_map, &start, &stop);
+ gog_chart_map_3d_to_view (c_map, start, yposition, zposition,
+ &ax, &ay, NULL);
+ gog_chart_map_3d_to_view (c_map, stop, yposition, zposition,
+ &bx, &by, NULL);
+ } else {
+ zposition = *pz[faces[base + vertex]];
+ xposition = *px[faces[base + vertex]];
+
+ a_map = gog_chart_map_3d_get_axis_map (c_map, 1);
+ gog_axis_map_get_extents (a_map, &start, &stop);
+ gog_chart_map_3d_to_view (c_map, xposition, start, zposition,
+ &ax, &ay, NULL);
+ gog_chart_map_3d_to_view (c_map, xposition, stop, zposition,
+ &bx, &by, NULL);
+ }
+
+ if (axis_type == perp_axis) {
+ /* Calculating cross-product of two planar vectors
+ * to determine "chirality" of the projected axis */
+ tmp = (ax - 0.5 * plot_area->w) * (by - ay)
+ - (ay - 0.5 * plot_area->h) * (bx - ax);
+ } else {
+ /* Same here, but relative to the centre of the base,
+ * except for a special case, when its 0 */
+ if ((ax == bx && ax == ox) || (ay == by && ay == oy))
+ tmp = (ax - 0.5 * plot_area->w) * (by - ay)
+ - (ay - 0.5 * plot_area->h) * (bx - ax);
+ else
+ tmp = (ax - ox) * (by - ay) - (ay - oy) * (bx - ax);
+ }
+ side = (tmp > 0)? GO_SIDE_LEFT : GO_SIDE_RIGHT;
+
+ gog_chart_map_3d_free (c_map);
+
+ switch (action) {
+ case GOG_AXIS_BASE_RENDER:
+ axis_line_render (axis_base, axis_base_view,
+ view->renderer,
+ ax, ay, bx - ax , by - ay, side, -1.,
+ axis_base->major_tick_labeled, TRUE);
+ break;
+ case GOG_AXIS_BASE_PADDING_REQUEST:
+ axis_line_bbox = axis_line_get_bbox (axis_base,
+ view->renderer, ax, ay, bx - ax, by - ay,
+ side, -1., axis_base->major_tick_labeled);
+ padding->wl = MAX (0., plot_area->x - axis_line_bbox.x);
+ padding->ht = MAX (0., plot_area->y - axis_line_bbox.y);
+ padding->wr = MAX (0., axis_line_bbox.x + axis_line_bbox.w
+ - plot_area->x - plot_area->w);
+ padding->hb = MAX (0., axis_line_bbox.y + axis_line_bbox.h
+ - plot_area->y - plot_area->h);
+ break;
+ case GOG_AXIS_BASE_POINT:
+ break;
+ }
+
+ return FALSE;
}
static gboolean
@@ -1815,7 +2011,7 @@
pointed = radar_process (GOG_AXIS_BASE_POINT, view, NULL, plot_area, x, y);
break;
case GOG_AXIS_SET_XYZ:
- xyz_process (GOG_AXIS_BASE_PADDING_REQUEST, view, NULL, plot_area, x, y);
+ xyz_process (GOG_AXIS_BASE_POINT, view, NULL, plot_area, x, y);
break;
default:
g_warning ("[AxisBaseView::point] not implemented for this axis set (%i)",
@@ -1852,6 +2048,8 @@
radar_process (GOG_AXIS_BASE_PADDING_REQUEST, view, padding, bbox, 0., 0.);
break;
case GOG_AXIS_SET_XYZ:
+ xyz_process (GOG_AXIS_BASE_PADDING_REQUEST, view,
+ padding, bbox, 0., 0.);
break;
default:
g_warning ("[AxisBaseView::padding_request] not implemented for this axis set (%i)",
@@ -1894,6 +2092,9 @@
case GOG_AXIS_SET_RADAR:
radar_process (GOG_AXIS_BASE_RENDER, view, NULL, plot_area, 0., 0.);
break;
+ case GOG_AXIS_SET_XYZ:
+ xyz_process (GOG_AXIS_BASE_RENDER, view, NULL, plot_area, 0., 0.);
+ break;
default:
g_warning ("[AxisBaseView::render] not implemented for this axis set (%i)",
axis_set);
Modified: trunk/goffice/graph/gog-chart-map-3d.c
==============================================================================
--- trunk/goffice/graph/gog-chart-map-3d.c (original)
+++ trunk/goffice/graph/gog-chart-map-3d.c Mon Jul 14 05:55:04 2008
@@ -142,6 +142,27 @@
}
/**
+ * gog_chart_map_3d_get_axis_map:
+ * @map: a #GogChartMap3D
+ * @index: axis index
+ *
+ * Convenience function which returns one of the associated axis_map.
+ *
+ * Valid values are in range [0..2].
+ *
+ * returns: a #GogAxisMap.
+ **/
+
+GogAxisMap *
+gog_chart_map_3d_get_axis_map (GogChartMap3D *map, unsigned int i)
+{
+ g_return_val_if_fail (map != NULL, NULL);
+ g_return_val_if_fail (i < 3, NULL);
+
+ return map->axis_map[i];
+}
+
+/**
* gog_chart_map_3d_is_valid:
* @map: a #GogChartMap3D
*
Modified: trunk/goffice/graph/gog-chart-map-3d.h
==============================================================================
--- trunk/goffice/graph/gog-chart-map-3d.h (original)
+++ trunk/goffice/graph/gog-chart-map-3d.h Mon Jul 14 05:55:04 2008
@@ -35,6 +35,7 @@
GogChartMap3D *gog_chart_map_3d_new (GogChart *chart, GogViewAllocation const *area,
GogAxis *axis0, GogAxis *axis1, GogAxis *axis2);
void gog_chart_map_3d_to_view (GogChartMap3D *map, double x, double y, double z, double *u, double *v, double *w);
+GogAxisMap *gog_chart_map_3d_get_axis_map (GogChartMap3D *map, unsigned int index);
gboolean gog_chart_map_3d_is_valid (GogChartMap3D *map);
void gog_chart_map_3d_free (GogChartMap3D *map);
Modified: trunk/goffice/graph/gog-chart.c
==============================================================================
--- trunk/goffice/graph/gog-chart.c (original)
+++ trunk/goffice/graph/gog-chart.c Mon Jul 14 05:55:04 2008
@@ -941,6 +941,10 @@
} else
*plot_area = view->residual;
+ /* special treatment for 3d charts */
+ if (gog_chart_is_3d (chart))
+ gog_chart_3d_process (chart, plot_area);
+
tmp = *plot_area;
gog_view_padding_request (view, plot_area, &padding);
@@ -969,10 +973,6 @@
if (GOG_POSITION_IS_SPECIAL (child->model->position))
gog_view_size_allocate (child, plot_area);
}
-
- /* special treatment for 3d charts */
- if (gog_chart_is_3d (chart))
- gog_chart_3d_process (chart, plot_area);
}
static void
@@ -1054,13 +1054,20 @@
for (ptr = view->children ; ptr != NULL ; ptr = ptr->next) {
child_view = ptr->data;
if (!IS_GOG_AXIS (child_view->model) && !IS_GOG_PLOT (child_view->model))
- gog_view_render (ptr->data, bbox);
+ gog_view_render (ptr->data, bbox);
}
/* now render plot and axes */
for (ptr = view->children ; ptr != NULL ; ptr = ptr->next) {
child_view = ptr->data;
+ if (!IS_GOG_AXIS (child_view->model)) continue;
+ gog_view_render (ptr->data, bbox);
+ }
+ for (ptr = view->children ; ptr != NULL ; ptr = ptr->next) {
+ child_view = ptr->data;
+ if (IS_GOG_AXIS (child_view->model))
+ continue;
if (IS_GOG_PLOT (child_view->model))
- gog_view_render (ptr->data, bbox);
+ gog_view_render (ptr->data, bbox);
}
} else {
/* KLUDGE: render grid lines before axis */
Modified: trunk/goffice/gtk/go-3d-rotation-sel.glade
==============================================================================
--- trunk/goffice/gtk/go-3d-rotation-sel.glade (original)
+++ trunk/goffice/gtk/go-3d-rotation-sel.glade Mon Jul 14 05:55:04 2008
@@ -55,7 +55,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="adjustment">0 0 180 1 10 0</property>
+ <property name="adjustment">0 0 90 1 10 0</property>
<property name="digits">0</property>
<property name="draw_value">False</property>
</widget>
Modified: trunk/plugins/plot_surface/gog-xyz.c
==============================================================================
--- trunk/plugins/plot_surface/gog-xyz.c (original)
+++ trunk/plugins/plot_surface/gog-xyz.c Mon Jul 14 05:55:04 2008
@@ -182,7 +182,7 @@
go_data_matrix_get_minmax (mat, &tmp_min, &tmp_max);
if ((tmp_min != model->z.minima)
|| (tmp_max != model->z.maxima)) {
- model->z.minima = tmp_min;
+ model->z.minima = tmp_min - 0.5 * fabs (tmp_max - tmp_min);
model->z.maxima = tmp_max;
gog_axis_bound_changed (
model->base.axis[GOG_XYZ_PLOT_GET_CLASS (model)->third_axis],
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]