changeset 27274:f49226d21c26

Implement missing functions rotx, roty, and rotz (bug #50772, patch #9310) * scripts/geometry/rotx.m, roty.m, rotz.m: Add new functions. * scripts/geometry/module.mk: Add files to scripts_general_FCN_FILES list. * doc/interpreter/geometry.txi: Add section for vector rotation matrices * NEWS: Add rotx, roty, and rotz under 'new functions added in Octave 6'.
author Nicholas R. Jankowski <jankowskin@asme.org>
date Fri, 22 Mar 2019 15:42:44 -0400
parents aaf788e496a3
children 1565c39aa940
files NEWS doc/interpreter/geometry.txi scripts/geometry/module.mk scripts/geometry/rotx.m scripts/geometry/roty.m scripts/geometry/rotz.m
diffstat 6 files changed, 344 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Sun Jul 21 15:46:19 2019 +0200
+++ b/NEWS	Fri Mar 22 15:42:44 2019 -0400
@@ -81,6 +81,9 @@
 
 - `lightangle`
 - `newline`
+- `rotx`
+- `roty`
+- `rotz`
 - `verLessThan`
 - `web`
 - `weboptions`
--- a/doc/interpreter/geometry.txi	Sun Jul 21 15:46:19 2019 +0200
+++ b/doc/interpreter/geometry.txi	Fri Mar 22 15:42:44 2019 -0400
@@ -32,6 +32,7 @@
 * Voronoi Diagrams::
 * Convex Hull::
 * Interpolation on Scattered Data::
+* Vector Rotation Matrices::
 @end menu
 
 @node Delaunay Triangulation
@@ -448,3 +449,28 @@
 @caption{Interpolation from a scattered data to a regular grid}
 @end float
 @end ifnotinfo
+
+@node Vector Rotation Matrices
+@section Vector Rotation Matrices
+
+Also included in Octave's geometry functions are primitive functions to enable
+vector rotations in 3 dimensional space. Separate functions are provided for
+rotation about each of the principle axes, @var{x}, @var{y}, and @var{z}.
+According to Euler's rotation theorem, any arbitrary rotation, @var{R}, of any
+vector, @var{p}, can be expressed as a product of the three principle rotations:
+
+@tex
+$p' = R \cdot p = R_z \cdot R_y \cdot R_x \cdot p$
+@end tex
+
+@ifnottex
+@example
+p' = Rp = Rz*Ry*Rx*p
+@end example
+@end ifnottex
+
+@DOCSTRING(rotx)
+
+@DOCSTRING(roty)
+
+@DOCSTRING(rotz)
\ No newline at end of file
--- a/scripts/geometry/module.mk	Sun Jul 21 15:46:19 2019 +0200
+++ b/scripts/geometry/module.mk	Fri Mar 22 15:42:44 2019 -0400
@@ -11,6 +11,9 @@
   %reldir%/griddatan.m \
   %reldir%/inpolygon.m \
   %reldir%/rectint.m \
+  %reldir%/rotx.m \
+  %reldir%/roty.m \
+  %reldir%/rotz.m \
   %reldir%/tsearchn.m \
   %reldir%/voronoi.m \
   %reldir%/voronoin.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/geometry/rotx.m	Fri Mar 22 15:42:44 2019 -0400
@@ -0,0 +1,104 @@
+## Copyright (C) 2019 Nicholas R. Jankowski
+##
+## 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
+## <https://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {} {@var{T} =} rotx (@var{angle})
+##
+## @code{rotx} returns the 3x3 transformation matrix corresponding to an active
+## rotation of the vector about the x-axis by the specified @var{angle}, given
+## in degrees, where a positive angle corresponds to a counter-clockwise
+## rotation when viewing the y-z plane from the positive x side.
+##
+## The form of the transformation matrix is:
+## @tex
+## $$
+## T = \left[\matrix{ 1 & 0 & 0 \cr
+##                    0 & \cos(angle) & -\sin(angle)\cr
+##                    0 & \sin(angle) & \cos(angle)}\right].
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##      | 1      0           0      |
+##  T = | 0  cos(@var{angle}) -sin(@var{angle}) |
+##      | 0  sin(@var{angle})  cos(@var{angle}) |
+## @end group
+## @end example
+## @end ifnottex
+##
+## This rotation matrix is intended to be used as a left-multiplyig matrix
+## when acting on a column vector, using the notation @var{v} = @var{T}@var{u}.
+## For example, a vector, @var{u}, pointing along the positive y-axis, rotated
+## 90-degrees about the x-axis, will result in a vector pointing along the
+## positive z-axis:
+##
+## @example
+## @group
+## >> u = [0 1 0]'
+## u =
+##    0
+##    1
+##    0
+##
+## >> T = rotx (90)
+## T =
+##    1.00000   0.00000   0.00000
+##    0.00000   0.00000  -1.00000
+##    0.00000   1.00000   0.00000
+##
+## >> v = T*u
+## v =
+##    0.00000
+##    0.00000
+##    1.00000
+## @end group
+## @end example
+##
+## @seealso{roty, rotz}
+## @end deftypefn
+
+## Author: Nicholas Jankowski <jankowskin@asme.org>
+## Created: 2017-04-09
+
+function retmat = rotx (angle_in_deg)
+
+  if ((nargin != 1) || ! isscalar (angle_in_deg))
+    print_usage ();
+  endif
+
+  angle_in_rad = angle_in_deg * pi / 180;
+
+  s = sin (angle_in_rad);
+  c = cos (angle_in_rad);
+
+  retmat = [1 0 0; 0 c -s; 0 s c];
+
+endfunction
+
+## Function output tests
+%!assert (rotx (0), [1 0 0; 0 1 0; 0 0 1]);
+%!assert (rotx (45), [1, 0, 0; [0; 0],[(sqrt(2)/2).*[1 -1; 1 1]]], 1e-12);
+%!assert (rotx (90), [1 0 0; 0 0 -1; 0 1 0], 1e-12);
+%!assert (rotx (180), [1 0 0; 0 -1 0; 0 0 -1], 1e-12);
+
+## Test input validation
+%!error rotx ()
+%!error rotx (1, 2)
+%!error rotx ([1 2 3])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/geometry/roty.m	Fri Mar 22 15:42:44 2019 -0400
@@ -0,0 +1,104 @@
+## Copyright (C) 2019 Nicholas R. Jankowski
+##
+## 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
+## <https://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {} {@var{T} =} roty (@var{angle})
+##
+## @code{roty} returns the 3x3 transformation matrix corresponding to an active
+## rotation of a vector about the y-axis by the specified @var{angle}, given in
+## degrees, where a positive angle corresponds to a counter-clockwise
+## rotation when viewing the z-x plane from the positive y side.
+##
+## The form of the transformation matrix is:
+## @tex
+## $$
+## T = \left[\matrix{ \cos(angle) & 0 & \sin(angle) \cr
+##                    0 & 1 & 0 \cr
+##                    -\sin(angle) & 0 & \cos(angle)}\right].
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##      |  cos(@var{angle})  0  sin(@var{angle}) |
+##  T = |      0       1      0      |
+##      | -sin(@var{angle})  0  cos(@var{angle}) |
+## @end group
+## @end example
+## @end ifnottex
+##
+## This rotation matrix is intended to be used as a left-multiplyig matrix
+## when acting on a column vector, using the notation @var{v} = @var{T}@var{u}.
+## For example, a vector, @var{u}, pointing along the positive z-axis, rotated
+## 90-degrees about the y-axis, will result in a vector pointing along the
+## positive x-axis:
+##
+## @example
+## @group
+##   >> u = [0 0 1]'
+##    u =
+##       0
+##       0
+##       1
+##
+##    >> T = roty (90)
+##    T =
+##       0.00000   0.00000   1.00000
+##       0.00000   1.00000   0.00000
+##      -1.00000   0.00000   0.00000
+##
+##    >> v = T*u
+##    v =
+##       1.00000
+##       0.00000
+##       0.00000
+## @end group
+## @end example
+##
+## @seealso{rotx, rotz}
+## @end deftypefn
+
+## Author: Nicholas Jankowski <jankowskin@asme.org>
+## Created: 2017-04-09
+
+function retmat = roty (angle_in_deg)
+
+  if ((nargin != 1) || ! isscalar (angle_in_deg))
+    print_usage ();
+  endif
+
+  angle_in_rad = angle_in_deg * pi / 180;
+
+  s = sin (angle_in_rad);
+  c = cos (angle_in_rad);
+
+  retmat = [c 0 s; 0 1 0; -s 0 c];
+
+endfunction
+
+## Function output tests
+%!assert (roty (0), [1 0 0; 0 1 0; 0 0 1]);
+%!assert (roty (45), [sqrt(2) 0 sqrt(2); 0 2 0; -sqrt(2) 0 sqrt(2)]./2, 1e-12);
+%!assert (roty (90), [0 0 1; 0 1 0; -1 0 0], 1e-12);
+%!assert (roty (180), [-1 0 0; 0 1 0; 0 0 -1], 1e-12);
+
+## Test input validation
+%!error roty ()
+%!error roty (1, 2)
+%!error roty ([1 2 3])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/geometry/rotz.m	Fri Mar 22 15:42:44 2019 -0400
@@ -0,0 +1,104 @@
+## Copyright (C) 2017 Nicholas R. Jankowski
+##
+## 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
+## <https://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {} {@var{T} =} rotz (@var{angle})
+##
+## @code{rotz} returns the 3x3 transformation matrix corresponding to an active
+## rotation of a vector about the z-axis by the specified @var{angle}, given in
+## degrees, where a positive angle corresponds to a counter-clockwise
+## rotation when viewing the x-y plane from the positive z side.
+##
+## The form of the transformation matrix is:
+## @tex
+## $$
+## T = \left[\matrix{ \cos(angle) & -\sin(angle) & 0 \cr
+##                    \sin(angle) & \cos(angle) & 0 \cr
+##                    0 & 0 & 1}\right].
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##      | cos(@var{angle}) -sin(@var{angle}) 0 |
+##  T = | sin(@var{angle})  cos(@var{angle}) 0 |
+##      |     0           0      1 |
+## @end group
+## @end example
+## @end ifnottex
+##
+## This rotation matrix is intended to be used as a left-multiplyig matrix
+## when acting on a column vector, using the notation @var{v} = @var{T}@var{u}.
+## For example, a vector, @var{u}, pointing along the positive x-axis, rotated
+## 90-degrees about the z-axis, will result in a vector pointing along the
+## positive y-axis:
+##
+## @example
+## @group
+##   >> u = [1 0 0]'
+##    u =
+##       1
+##       0
+##       0
+##
+##    >> T = rotz (90)
+##    T =
+##       0.00000  -1.00000   0.00000
+##       1.00000   0.00000   0.00000
+##       0.00000   0.00000   1.00000
+##
+##    >> v = T*u
+##    v =
+##       0.00000
+##       1.00000
+##       0.00000
+## @end group
+## @end example
+##
+## @seealso{rotx, roty}
+## @end deftypefn
+
+## Author: Nicholas Jankowski <jankowskin@asme.org>
+## Created: 2017-04-09
+
+function retmat = rotz (angle_in_deg)
+
+  if ((nargin != 1) || ! isscalar (angle_in_deg))
+    print_usage ();
+  endif
+
+  angle_in_rad = angle_in_deg * pi / 180;
+
+  s = sin (angle_in_rad);
+  c = cos (angle_in_rad);
+
+  retmat = [c -s 0; s c 0; 0 0 1];
+
+endfunction
+
+## Function output tests
+%!assert (rotz (0), [1 0 0; 0 1 0; 0 0 1]);
+%!assert (rotz (45), [(sqrt(2)/2).*[1 -1; 1 1] ,[0; 0]; 0, 0, 1], 1e-12);
+%!assert (rotz (90), [0 -1 0; 1 0 0; 0 0 1], 1e-12);
+%!assert (rotz (180), [-1 0 0; 0 -1 0; 0 0 1], 1e-12);
+
+## Test input validation
+%!error rotz ()
+%!error rotz (1, 2)
+%!error rotz ([1 2 3])