Mercurial > hg > octave-avbm
changeset 11167:51ac3a08e53c
Fix {d,pb}aspectratios for OpenGL backends.
author | Konstantinos Poulios <logari81@googlemail.com> |
---|---|
date | Thu, 28 Oct 2010 14:12:46 +0200 |
parents | 9cdf43d1fa16 |
children | 36442102c340 |
files | src/ChangeLog src/graphics.cc src/graphics.h.in |
diffstat | 3 files changed, 164 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -3,6 +3,29 @@ * gl-render.cc: Crop ticks, ticklabels, and gridlines for OpenGL backend. +2010-10-28 Konstantinos Poulios <logari81@googlemail.com> + + * graphics.cc (normalized_aspectratios, max_axes_scale): + New file-scope static function + (updating_aspectratios): New file-scope variable. + (axes::properties::update_aspectratios, axes::update_axis_limits): + Return immediately if updating_aspecratios is true. + (axes::properties::update_aspectratios): + If dataaspectratiomode is set to manual this function will try to + respect it even after changes in xlim, ylim, zlim. + If both dataaspectratiomode and plotboxaspectratiomode is set to + manual this function will try to recalulate xlim, ylim, zlim + depending on the status of xlimmode, ylimmode, zlimmode. If + altering xlim, ylim, zlim is not possible, plotboxaspectratio will + be overriden. + * graphics.h.in (class axes::properties): Tag dataaspectratio, + dataaspectratiomode, plotboxaspectratio, and + plotboxaspectratiomode with "u" qualifier. + (axes::update_dataaspectratio, + axes::update_dataaspectratiomode, + axes::update_plotboxaspectratio, + axes::update_plotboxaspectratiomode): New functions. + 2010-10-25 John W. Eaton <jwe@octave.org> * octave.cc (octave_main): Use F77_CHAR_ARC_LEN macro to pass
--- a/src/graphics.cc +++ b/src/graphics.cc @@ -3911,9 +3911,51 @@ x_gl_mat2 = x_viewport * x_projection; } +static void +normalized_aspectratios (Matrix& aspectratios, const Matrix& scalefactors, + double xlength, double ylength, double zlength) +{ + double xval = xlength/scalefactors(0); + double yval = ylength/scalefactors(1); + double zval = zlength/scalefactors(2); + + double minval = xmin (xmin (xval, yval), zval); + + aspectratios(0) = xval/minval; + aspectratios(1) = yval/minval; + aspectratios(2) = zval/minval; +} + +static void +max_axes_scale (double& s, Matrix& limits, const Matrix& kids, + double pbfactor, double dafactor, char limit_type, bool tight) +{ + if (tight) + { + double minval = octave_Inf; + double maxval = -octave_Inf; + double min_pos = octave_Inf; + get_children_limits (minval, maxval, min_pos, kids, limit_type); + if (!xisinf (minval) && !xisnan (minval) + && !xisinf (maxval) && !xisnan (maxval)) + { + limits(0) = minval; + limits(1) = maxval; + s = xmax(s, (maxval - minval) / (pbfactor * dafactor)); + } + } + else + s = xmax(s, (limits(1) - limits(0)) / (pbfactor * dafactor)); +} + +static bool updating_aspectratios = false; + void axes::properties::update_aspectratios (void) { + if (updating_aspectratios) + return; + Matrix xlimits = get_xlim ().matrix_value (); Matrix ylimits = get_ylim ().matrix_value (); Matrix zlimits = get_zlim ().matrix_value (); @@ -3922,35 +3964,102 @@ double dy = (ylimits(1)-ylimits(0)); double dz = (zlimits(1)-zlimits(0)); + Matrix da = get_dataaspectratio ().matrix_value (); + Matrix pba = get_plotboxaspectratio ().matrix_value (); + if (dataaspectratiomode_is ("auto")) { - double dmin = xmin (xmin (dx, dy), dz); - Matrix da (1, 3, 0.0); - - da(0) = dx/dmin; - da(1) = dy/dmin; - da(2) = dz/dmin; - - dataaspectratio = da; - } - - if (plotboxaspectratiomode_is ("auto")) - { - if (dataaspectratiomode_is ("auto")) - plotboxaspectratio = Matrix (1, 3, 1.0); + if (plotboxaspectratiomode_is ("auto")) + { + pba = Matrix (1, 3, 1.0); + plotboxaspectratio.set (pba, false); + } + + normalized_aspectratios (da, pba, dx, dy, dz); + dataaspectratio.set (da, false); + } + else if (plotboxaspectratiomode_is ("auto")) + { + normalized_aspectratios (pba, da, dx, dy, dz); + plotboxaspectratio.set (pba, false); + } + else + { + double s = -octave_Inf; + bool modified_limits = false; + Matrix kids; + + if (xlimmode_is ("auto") && ylimmode_is ("auto") && zlimmode_is ("auto")) + { + modified_limits = true; + kids = get_children (); + max_axes_scale (s, xlimits, kids, pba(0), da(0), 'x', true); + max_axes_scale (s, ylimits, kids, pba(1), da(1), 'y', true); + max_axes_scale (s, zlimits, kids, pba(2), da(2), 'z', true); + } + else if (xlimmode_is ("auto") && ylimmode_is ("auto")) + { + modified_limits = true; + max_axes_scale (s, zlimits, kids, pba(2), da(2), 'z', false); + } + else if (ylimmode_is ("auto") && zlimmode_is ("auto")) + { + modified_limits = true; + max_axes_scale (s, xlimits, kids, pba(0), da(0), 'x', false); + } + else if (zlimmode_is ("auto") && xlimmode_is ("auto")) + { + modified_limits = true; + max_axes_scale (s, ylimits, kids, pba(1), da(1), 'y', false); + } + + if (modified_limits) + { + + unwind_protect frame; + frame.protect_var (updating_aspectratios); + + updating_aspectratios = true; + + dx = pba(0) *da(0); + dy = pba(1) *da(1); + dz = pba(2) *da(2); + if (xisinf (s)) + s = 1 / xmin (xmin (dx, dy), dz); + + if (xlimmode_is ("auto")) + { + dx = s * dx; + xlimits(0) = 0.5 * (xlimits(0) + xlimits(1) - dx); + xlimits(1) = xlimits(0) + dx; + set_xlim (xlimits); + set_xlimmode ("auto"); + } + + if (ylimmode_is ("auto")) + { + dy = s * dy; + ylimits(0) = 0.5 * (ylimits(0) + ylimits(1) - dy); + ylimits(1) = ylimits(0) + dy; + set_ylim (ylimits); + set_ylimmode ("auto"); + } + + if (zlimmode_is ("auto")) + { + dz = s * dz; + zlimits(0) = 0.5 * (zlimits(0) + zlimits(1) - dz); + zlimits(1) = zlimits(0) + dz; + set_zlim (zlimits); + set_zlimmode ("auto"); + } + } else { - Matrix da = get_dataaspectratio ().matrix_value (); - Matrix pba (1, 3, 0.0); - - pba(0) = dx/da(0); - pba(1) = dy/da(1); - pba(2) = dz/da(2); + normalized_aspectratios (pba, da, dx, dy, dz); + plotboxaspectratio.set (pba, false); } } - - // FIXME -- if plotboxaspectratiomode is "manual", limits - // and/or dataaspectratio might be adapted. } // The INTERNAL flag defines whether position or outerposition is used. @@ -4448,7 +4557,7 @@ void axes::update_axis_limits (const std::string& axis_type) { - if (updating_axis_limits) + if (updating_axis_limits || updating_aspectratios) return; Matrix kids = xproperties.get_children ();
--- a/src/graphics.h.in +++ b/src/graphics.h.in @@ -2911,8 +2911,8 @@ array_property position u , default_axes_position () bool_property box , "on" array_property colororder , default_colororder () - array_property dataaspectratio m , Matrix (1, 3, 1.0) - radio_property dataaspectratiomode , "{auto}|manual" + array_property dataaspectratio mu , Matrix (1, 3, 1.0) + radio_property dataaspectratiomode u , "{auto}|manual" radio_property layer , "{bottom}|top" row_vector_property xlim mu , default_lim () row_vector_property ylim mu , default_lim () @@ -2988,8 +2988,8 @@ string_array_property linestyleorder , "-" double_property linewidth , 0.5 radio_property minorgridlinestyle , "-|--|{:}|-.|none" - array_property plotboxaspectratio m , Matrix (1, 3, 1.0) - radio_property plotboxaspectratiomode , "{auto}|manual" + array_property plotboxaspectratio mu , Matrix (1, 3, 1.0) + radio_property plotboxaspectratiomode u , "{auto}|manual" radio_property projection , "{orthographic}|perpective" radio_property tickdir m , "{in}|out" radio_property tickdirmode , "{auto}|manual" @@ -3014,6 +3014,10 @@ void update_zscale (void) { sz = get_zscale (); } void update_view (void) { update_camera (); } + void update_dataaspectratio (void) { update_transform (); } + void update_dataaspectratiomode (void) { update_transform (); } + void update_plotboxaspectratio (void) { update_transform (); } + void update_plotboxaspectratiomode (void) { update_transform (); } void update_xdir (void) { update_camera (); } void update_ydir (void) { update_camera (); }