# HG changeset patch # User John W. Eaton # Date 1410466032 14400 # Node ID d59d052c9858d534e26b472f82bbf191c036f5eb # Parent af9c22e20a57f1b3a78bacab563a514d44f212ed rotate.m: new function * rotate.m: New function. * NEWS: List it. * plot.txi: Document it in new section. diff -r af9c22e20a57 -r d59d052c9858 NEWS --- a/NEWS Thu Sep 11 00:49:22 2014 -0400 +++ b/NEWS Thu Sep 11 16:07:12 2014 -0400 @@ -4,7 +4,7 @@ ** A new syntax for object oriented programming termed classdef has been introduced. See the manual for more extensive documentation of the classdef interface. - + New keywords: classdef endclassdef @@ -49,7 +49,7 @@ results equivalent to Matlab even for esoteric combinations of faces/vertices/cdata. - ** The polar() plot function now draws a circular theta axis and + ** The polar() plot function now draws a circular theta axis and radial rho axis rather than using a rectangular x/y axis. ** linkprop has been completely re-coded for performance and Matlab @@ -66,11 +66,22 @@ ** Other new functions added in 4.2: - bandwidth ilu javachk - dir_in_loadpath isbanded linkaxes - hgload isdiag numfields - hgsave istril sylvester - ichol istriu lscov + bandwidth + dir_in_loadpath + hgload + hgsave + ichol + ilu + isbanded + isdiag + istril + istriu + javachk + linkaxes + lscov + numfields + rotate + sylvester ** Deprecated functions. @@ -78,22 +89,23 @@ be removed from Octave 4.6 (or whatever version is the second major release after 4.2): - bicubic syl + bicubic find_dir_in_path nargchk nfields + syl The following functions were deprecated in Octave 3.8 and have been removed from Octave 4.2. - default_save_options java_new - gen_doc_cache java_unsigned_conversion - interp1q javafields - isequalwithequalnans javamethods + default_save_options java_new + gen_doc_cache java_unsigned_conversion + interp1q javafields + isequalwithequalnans javamethods java_convert_matrix re_read_readline_init_file - java_debug read_readline_init_file - java_invoke saving_history - + java_debug read_readline_init_file + java_invoke saving_history + The following keywords were deprecated in Octave 3.8 and have been removed from Octave 4.2 @@ -144,12 +156,12 @@ The following functions were deprecated in Octave 3.6 and have been removed from Octave 4.0. - - cut polyderiv - cor shell_cmd - corrcoef studentize - __error_text__ sylvester_matrix - error_text + + cut polyderiv + cor shell_cmd + corrcoef studentize + __error_text__ sylvester_matrix + error_text The following functions have been deprecated in Octave 4.0 and will be removed from Octave 4.4 (or whatever version is the second major @@ -157,7 +169,7 @@ allow_noninteger_range_as_index do_braindead_shortcircuit_evaluation - + The internal function atan2 of the sparse matrix class has been deprecated in Octave 4.0 and will be removed from Octave 4.4 (or whatever version is the second major release after 4.0). Use the Fatan2 function with sparse diff -r af9c22e20a57 -r d59d052c9858 doc/interpreter/plot.txi --- a/doc/interpreter/plot.txi Thu Sep 11 00:49:22 2014 -0400 +++ b/doc/interpreter/plot.txi Thu Sep 11 16:07:12 2014 -0400 @@ -63,6 +63,7 @@ * Plot Annotations:: * Multiple Plots on One Page:: * Multiple Plot Windows:: +* Manipulation of Plot Objects:: * Manipulation of Plot Windows:: * Use of the @code{interpreter} Property:: * Printing and Saving Plots:: @@ -530,6 +531,12 @@ @DOCSTRING(figure) +@node Manipulation of Plot Objects +@subsection Manipulation of Plot Objects +@cindex plotting, object manipulation + +@DOCSTRING(rotate) + @node Manipulation of Plot Windows @subsection Manipulation of Plot Windows @cindex plotting, window manipulation diff -r af9c22e20a57 -r d59d052c9858 scripts/plot/draw/peaks.m --- a/scripts/plot/draw/peaks.m Thu Sep 11 00:49:22 2014 -0400 +++ b/scripts/plot/draw/peaks.m Thu Sep 11 16:07:12 2014 -0400 @@ -83,6 +83,9 @@ if (nargout == 0) surf (x, y, Z); + Z_max = max (Z(:)); + Z_min = min (Z(:)); + axis ([-3, 3, -3, 3, Z_min, Z_max]); elseif (nargout == 1) X_out = Z; else diff -r af9c22e20a57 -r d59d052c9858 scripts/plot/draw/rotate.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/draw/rotate.m Thu Sep 11 16:07:12 2014 -0400 @@ -0,0 +1,188 @@ +## Copyright (C) 2014 John W. Eaton +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} rotate (@var{h}, @var{dir}, @var{alpha}) +## @deftypefnx {Function File} {} rotate (@dots{}, @var{origin}) +## Rotate the plot object @var{h} through @var{alpha} degrees around +## the line with direction @var{dir} and origin @var{origin}. +## +## The default value of @var{origin} is the center of the axes +## object that is the parent of @var{h}. +## +## If @var{h} is a vector of handles, they must all have the same +## parent axes object. +## +## Graphics objects that may be rotated are lines, surfaces, patches, +## and images. +## @end deftypefn + +function rotate (h, direction, alpha, origin) + + ## Note in doc string about compatibility issues with calculation of + ## default origin due to possible differences in the auto-scaling + ## algorithm between Octave and Matlab. + + if (nargin < 3 || nargin > 4) + print_unage (); + endif + + is_h = ishandle (h); + if (is_h) + ax_list = get (h, "parent"); + if (iscell (ax_list)) + ax_list = cell2mat (ax_list); + endif + if (ax_list == ax_list(1)) + ax = ax_list(1); + else + error ("rotate: all handles must be children of the same axes object"); + endif + else + error ("rotate: H must be an array of one or more graphics handles"); + endif + + if (! (isnumeric (direction) && numel (direction) == 3)) + error ("rotate: invalid direction"); + endif + + if (! (isnumeric (alpha) && isscalar (alpha))) + error ("rotate: invalid rotation angle"); + endif + + t = get (h, "type"); + + is_image = strcmp (t, "image"); + is_line = strcmp (t, "line"); + is_patch = strcmp (t, "patch"); + is_surface = strcmp (t, "surface"); + + if (! all (is_image | is_line | is_patch | is_surface)) + error ("rotate: expecting image, line, patch, or surface objects"); + endif + + if (nargin == 4) + if (! (isnumeric (origin) && numel (origin) == 3)) + error ("rotate: invalid origin"); + endif + else + ## Should Z limit be considered when computing origin? + + use_zlim = any (is_patch | is_surface); + + if (! use_zlim && any (is_line)) + idx = find (is_line)'; + for i = idx + if (! isempty (get (h(i), "zdata"))) + use_zlim = true; + break; + endif + endfor + endif + + xlim = get (ax, "xlim"); + ylim = get (ax, "ylim"); + + a = (xlim(1) + xlim(2)) / 2; + b = (ylim(1) + ylim(2)) / 2; + + if (use_zlim) + zlim = get (ax, "zlim"); + c = (zlim(1) + zlim(2)) / 2; + else + c = 0; + endif + + origin = [a, b, c]; + endif + + direction = direction / norm (direction); + + u = direction(1); + v = direction(2); + w = direction(3); + + a = origin(1); + b = origin(2); + c = origin(3); + + sa = sind (alpha); + ca = cosd (alpha); + + for i = 1:numel (h) + x = get (h(i), "xdata"); + y = get (h(i), "ydata"); + + if (is_image(i)) + z = zeros (size (x)); + else + z = get (h(i), "zdata"); + if (isempty (z)) + z = zeros (size (x)); + elseif (isvector (x) && isvector (y) && ! isvector (z)) + [x, y] = meshgrid (x, y); + endif + endif + + if (a == 0 && b == 0 && c == 0) + tmp = (u*x + v*y + w*z) * (1 - ca); + + xr = u*tmp + x*ca + (-w*y + v*z)*sa; + yr = v*tmp + y*ca + (w*x - u*z)*sa; + zr = w*tmp + z*ca + (-v*x + u*y)*sa; + else + one_m_ca = 1 - ca; + tmp = u*x + v*y + w*z; + + xr = ((a*(v**2 + w**2) - u*(b*v + c*w - tmp))*one_m_ca + + x*ca + (-c*v + b*w - w*y + v*z)*sa); + yr = ((b*(u**2 + w**2) - v*(a*u + c*w - tmp))*one_m_ca + + y*ca + (c*u - a*w + w*x - u*z)*sa); + zr = ((c*(u**2 + v**2) - w*(a*u + b*v - tmp))*one_m_ca + + z*ca + (-b*u + a*v - v*x + u*y)*sa); + endif + + set (h(i), "xdata", xr, "ydata", yr); + + if (! is_image(i)) + set (h(i), "zdata", zr); + endif + endfor + +endfunction + +%% Test input validation +%!shared h1, h2, o1, o2, o3 +%! h1 = figure ("visible", "off"); +%! o1 = line (); +%! h2 = figure ("visible", "off"); +%! o2 = line (); +%! o3 = text (0, 0, "foobar"); +%!error rotate () +%!error rotate (o1) +%!error rotate (o1, [0,0,0]); +%!error rotate ([o1, o2], [0,0,0], 90); +%!error rotate (o1, "foo", 90); +%!error rotate (o1, [0,0,0], "foo"); +%!error rotate (o1, [0,0,0], 90, "foo"); +%!error rotate (o1, [0,0,0], 90, [0,0,0], 1); +%!error rotate (NaN, [0,0,0], 90); +%!error rotate (o3, [0,0,0], 90); +%!test +%! close (h1); +%! close (h2);