# HG changeset patch
# User Nicholas R. Jankowski <jankowskin@asme.org>
# Date 1553283764 14400
#      Fri Mar 22 15:42:44 2019 -0400
# Node ID 8e22088dde243c100619e1ffb2a73695776552aa
# Parent  6731d89ef576d59fc0b0921fd5f87e8cf3d516ea
Implemented missing functions rotx, roty, and rotz (bug #50772, patch #9310)

* /scripts/geometry/rotx.m: new function m-file
* /scripts/geometry/roty.m: new function m-file
* /scripts/geometry/rotz.m: new function m-file
* /scripts/geometry/module.mk: added m-files to scripts_general_FCN_FILES list
* /doc/interpreter/geometry.txi: added section for vector rotation matrices
* /NEWS: added rotx, roty, and rotz under 'new new functions added in Octave 6'

diff -r 6731d89ef576 -r 8e22088dde24 NEWS
--- a/NEWS	Thu Mar 21 19:06:09 2019 +0000
+++ b/NEWS	Fri Mar 22 15:42:44 2019 -0400
@@ -103,6 +103,9 @@
 ### Alphabetical list of new functions added in Octave 6
 
 - `lightangle`
+- `rotx`
+- `roty`
+- `rotz`
 - `verLessThan`
 
 
diff -r 6731d89ef576 -r 8e22088dde24 doc/interpreter/geometry.txi
--- a/doc/interpreter/geometry.txi	Thu Mar 21 19:06:09 2019 +0000
+++ b/doc/interpreter/geometry.txi	Fri Mar 22 15:42:44 2019 -0400
@@ -448,3 +448,30 @@
 @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. A separate function is 
+provided for rotation about each of the principle axis, @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 defined as a product of the three
+principle rotations:
+
+@tex
+\mathbf{p}'=R\cdot \mathbf{p}=R_z\cdot R_y\cdot R_x\cdot \mathbf{p}
+@end tex
+
+@ifnotex
+@example
+p' = Rp = Rz*Ry*Rx*p
+@end example
+@end ifnotex
+
+@DOCSTRING(rotx)
+
+@DOCSTRING(roty)
+
+@DOCSTRING(rotz)
\ No newline at end of file
diff -r 6731d89ef576 -r 8e22088dde24 scripts/geometry/module.mk
--- a/scripts/geometry/module.mk	Thu Mar 21 19:06:09 2019 +0000
+++ 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
diff -r 6731d89ef576 -r 8e22088dde24 scripts/geometry/rotx.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 program 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.
+## 
+## This program 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 this program.  If not, see <http://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
+## $$
+## \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, createRotation, createRotationOx, createRotationOy,
+##   createRotationOz}
+## @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])
diff -r 6731d89ef576 -r 8e22088dde24 scripts/geometry/roty.m
--- /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 program 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.
+## 
+## This program 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 this program.  If not, see <http://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
+## $$
+## \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, createRotation, createRotationOx, createRotationOy,
+##   createRotationOz}
+## @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])
diff -r 6731d89ef576 -r 8e22088dde24 scripts/geometry/rotz.m
--- /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 program 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.
+## 
+## This program 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 this program.  If not, see <http://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
+## $$
+## \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, createRotation, createRotationOx, createRotationOy,
+##   createRotationOz}
+## @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])
