# HG changeset patch # User Ben Abbott # Date 1232231531 18000 # Node ID fb1b87ea4af98498a68ecc7fa52c86089254d544 # Parent 4d884a01684634e5c45a47050a943f0e8e5c4bc9 Permit scalars when transforming coordinates. diff --git a/scripts/ChangeLog b/scripts/ChangeLog --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,8 @@ +2009-01-17 Ben Abbott + + * general/cart2sph.m, cart2pol.m, sph2cart.m pol2cart.m: + Permit scalars when transforming coordinates. + 2009-01-17 Steven Verstoep * plot/__quiver__.m: __quiver__.m: Fix auto-size of (x,y) coord. diff --git a/scripts/general/cart2pol.m b/scripts/general/cart2pol.m --- a/scripts/general/cart2pol.m +++ b/scripts/general/cart2pol.m @@ -20,7 +20,7 @@ ## @deftypefn {Function File} {[@var{theta}, @var{r}] =} cart2pol (@var{x}, @var{y}) ## @deftypefnx {Function File} {[@var{theta}, @var{r}, @var{z}] =} cart2pol (@var{x}, @var{y}, @var{z}) ## Transform cartesian to polar or cylindrical coordinates. -## @var{x}, @var{y} (and @var{z}) must be of same shape. +## @var{x}, @var{y} (and @var{z}) must be of same shape, or scalar. ## @var{theta} describes the angle relative to the x-axis. ## @var{r} is the distance to the z-axis (0, 0, z). ## @seealso{pol2cart, cart2sph, sph2cart} @@ -29,7 +29,7 @@ ## Author: Kai Habel ## Adapted-by: jwe -function [Theta, R, Z] = cart2pol (X, Y, Z) +function [theta, r, z] = cart2pol (x, y, z) if (nargin < 2 || nargin > 3) error ("cart2pol: number of arguments must be 2 or 3"); @@ -39,13 +39,67 @@ error ("cart2pol: number of output arguments must not be greater than number of input arguments"); endif - if (! (ismatrix (X) && ismatrix (Y)) - || ! size_equal (X, Y) - || (nargin == 3 && ! (size_equal (X, Z) && ismatrix (Z)))) - error ("cart2pol: arguments must be matrices of same size"); + if ((ismatrix (x) && ismatrix (y) && (nargin == 2 || ismatrix (z))) + && (size_equal (x, y) || isscalar (x) || isscalar (y)) + && (nargin == 2 || size_equal (x, z) || isscalar (x) || isscalar (z)) + && (nargin == 2 || size_equal (y, z) || isscalar (y) || isscalar (z))) + + theta = atan2 (y, x); + r = sqrt (x .^ 2 + y .^ 2); + + else + error ("cart2pol: arguments must be matrices of same size, or scalar"); endif - Theta = atan2 (Y, X); - R = sqrt (X .^ 2 + Y .^ 2); +endfunction + +%!test +%! x = [0, 1, 2]; +%! y = 0; +%! [t, r] = cart2pol (x, y); +%! assert (t, [0, 0, 0]); +%! assert (r, x); + +%!test +%! x = [0, 1, 2]; +%! y = [0, 1, 2]; +%! [t, r] = cart2pol (x, y); +%! assert (t, [0, pi/4, pi/4], sqrt(eps)); +%! assert (r, sqrt(2)*[0, 1, 2], sqrt(eps)); + +%!test +%! x = [0, 1, 2]; +%! y = [0, 1, 2]; +%! z = [0, 1, 2]; +%! [t, r, z2] = cart2pol (x, y, z); +%! assert (t, [0, pi/4, pi/4], sqrt(eps)); +%! assert (r, sqrt(2)*[0, 1, 2], sqrt(eps)); +%! assert (z, z2); -endfunction +%!test +%! x = [0, 1, 2]; +%! y = 0; +%! z = 0; +%! [t, r, z2] = cart2pol (x, y, z); +%! assert (t, [0, 0, 0], eps); +%! assert (r, x, eps); +%! assert (z, z2); + +%!test +%! x = 0; +%! y = [0, 1, 2]; +%! z = 0; +%! [t, r, z2] = cart2pol (x, y, z); +%! assert (t, [0, 1, 1]*pi/2, eps); +%! assert (r, y, eps); +%! assert (z, z2); + +%!test +%! x = 0; +%! y = 0; +%! z = [0, 1, 2]; +%! [t, r, z2] = cart2pol (x, y, z); +%! assert (t, 0); +%! assert (r, 0); +%! assert (z, z2); + diff --git a/scripts/general/cart2sph.m b/scripts/general/cart2sph.m --- a/scripts/general/cart2sph.m +++ b/scripts/general/cart2sph.m @@ -19,7 +19,7 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{theta}, @var{phi}, @var{r}] =} cart2sph (@var{x}, @var{y}, @var{z}) ## Transform cartesian to spherical coordinates. -## @var{x}, @var{y} and @var{z} must be of same shape. +## @var{x}, @var{y} and @var{z} must be of same shape, or scalar. ## @var{theta} describes the angle relative to the x-axis. ## @var{phi} is the angle relative to the xy-plane. ## @var{r} is the distance to the origin (0, 0, 0). @@ -29,20 +29,60 @@ ## Author: Kai Habel ## Adapted-by: jwe -function [Theta, Phi, R] = cart2sph (X, Y, Z) +function [theta, phi, r] = cart2sph (x, y, z) if (nargin != 3) print_usage (); endif - if (! (ismatrix (X) && ismatrix (Y) && ismatrix (Z)) - || ! size_equal (X, Y) - || ! size_equal (X, Z)) - error ("cart2sph: arguments must be matrices of same size"); + if ((ismatrix (x) && ismatrix (y) && ismatrix (z)) + && (size_equal (x, y) || isscalar (x) || isscalar (y)) + && (size_equal (x, z) || isscalar (x) || isscalar (z)) + && (size_equal (y, z) || isscalar (y) || isscalar (z))) + + theta = atan2 (y, x); + phi = atan2 (z, sqrt (x .^ 2 + y .^ 2)); + r = sqrt (x .^ 2 + y .^ 2 + z .^ 2); + + else + error ("cart2sph: arguments must be matrices of same size, or scalar"); endif - Theta = atan2 (Y, X); - Phi = atan2 (Z, sqrt (X .^ 2 + Y .^ 2)); - R = sqrt (X .^ 2 + Y .^ 2 + Z .^ 2); +endfunction + +%!test +%! x = [0, 1, 2]; +%! y = [0, 1, 2]; +%! z = [0, 1, 2]; +%! [t, p, r] = cart2sph (x, y, z); +%! assert (t, [0, pi/4, pi/4], eps); +%! assert (p, [0, 1, 1]*atan(sqrt(0.5)), eps); +%! assert (r, [0, 1, 2]*sqrt(3), eps); -endfunction +%!test +%! x = 0; +%! y = [0, 1, 2]; +%! z = [0, 1, 2]; +%! [t, p, r] = cart2sph (x, y, z); +%! assert (t, [0, 1, 1] * pi/2, eps); +%! assert (p, [0, 1, 1] * pi/4, eps); +%! assert (r, [0, 1, 2] * sqrt(2), eps); + +%!test +%! x = [0, 1, 2]; +%! y = 0; +%! z = [0, 1, 2]; +%! [t, p, r] = cart2sph (x, y, z); +%! assert (t, [0, 0, 0]); +%! assert (p, [0, 1, 1] * pi/4); +%! assert (r, [0, 1, 2] * sqrt(2)); + +%!test +%! x = [0, 1, 2]; +%! y = [0, 1, 2]; +%! z = 0; +%! [t, p, r] = cart2sph (x, y, z); +%! assert (t, [0, 1, 1] * pi/4); +%! assert (p, [0, 0, 0]); +%! assert (r, [0, 1, 2] * sqrt(2)); + diff --git a/scripts/general/pol2cart.m b/scripts/general/pol2cart.m --- a/scripts/general/pol2cart.m +++ b/scripts/general/pol2cart.m @@ -20,7 +20,7 @@ ## @deftypefn {Function File} {[@var{x}, @var{y}] =} pol2cart (@var{theta}, @var{r}) ## @deftypefnx {Function File} {[@var{x}, @var{y}, @var{z}] =} pol2cart (@var{theta}, @var{r}, @var{z}) ## Transform polar or cylindrical to cartesian coordinates. -## @var{theta}, @var{r} (and @var{z}) must be of same shape. +## @var{theta}, @var{r} (and @var{z}) must be of same shape, or scalar. ## @var{theta} describes the angle relative to the x-axis. ## @var{r} is the distance to the z-axis (0, 0, z). ## @seealso{cart2pol, cart2sph, sph2cart} @@ -29,7 +29,7 @@ ## Author: Kai Habel ## Adapted-by: jwe -function [X, Y, Z] = pol2cart (Theta, R, Z) +function [x, y, z] = pol2cart (theta, r, z) if (nargin < 2 || nargin > 3) error ("pol2cart: number of arguments must be 2 or 3"); @@ -39,17 +39,67 @@ error ("pol2cart: number of output arguments must not be greater than number of input arguments"); endif - if (! (ismatrix (Theta) && ismatrix (R)) - || ! size_equal (Theta, R) && ! isscalar (Theta) && ! isscalar (R) - || (nargin == 3 - && (! ismatrix (Z) - || (! isscalar (Z) - && (! (isscalar (R) || size_equal (R, Z)) - || ! (isscalar(Theta) || size_equal (Theta, Z))))))) - error ("pol2cart: arguments must be matrices of same size or scalar"); + if ((ismatrix (theta) && ismatrix (r) && (nargin == 2 || ismatrix (z))) + && (size_equal (theta, r) || isscalar (theta) || isscalar (r)) + && (nargin == 2 || size_equal (theta, z) || isscalar (theta) || isscalar (z)) + && (nargin == 2 || size_equal (r, z) || isscalar (r) || isscalar (z))) + + x = cos (theta) .* r; + y = sin (theta) .* r; + + else + error ("pol2cart: arguments must be matrices of same size, or scalar"); endif - X = cos (Theta) .* R; - Y = sin (Theta) .* R; +endfunction + +%!test +%! t = [0, 0.5, 1] * pi; +%! r = 1; +%! [x, y] = pol2cart (t, r); +%! assert (x, [1, 0, -1], sqrt(eps)); +%! assert (y, [0, 1, 0], sqrt(eps)); + +%!test +%! t = [0, 1, 1] * pi/4; +%! r = sqrt(2) * [0, 1, 2]; +%! [x, y] = pol2cart (t, r); +%! assert (x, [0, 1, 2], sqrt(eps)); +%! assert (y, [0, 1, 2], sqrt(eps)); + +%!test +%! t = [0, 1, 1] * pi/4; +%! r = sqrt(2) * [0, 1, 2]; +%! z = [0, 1, 2]; +%! [x, y, z2] = pol2cart (t, r, z); +%! assert (x, [0, 1, 2], sqrt(eps)); +%! assert (y, [0, 1, 2], sqrt(eps)); +%! assert (z, z2); -endfunction +%!test +%! t = 0; +%! r = [0, 1, 2]; +%! z = [0, 1, 2]; +%! [x, y, z2] = pol2cart (t, r, z); +%! assert (x, [0, 1, 2], sqrt(eps)); +%! assert (y, [0, 0, 0], sqrt(eps)); +%! assert (z, z2); + +%!test +%! t = [1, 1, 1]*pi/4; +%! r = 1; +%! z = [0, 1, 2]; +%! [x, y, z2] = pol2cart (t, r, z); +%! assert (x, [1, 1, 1] / sqrt(2), eps); +%! assert (y, [1, 1, 1] / sqrt(2), eps); +%! assert (z, z2); + +%!test +%! t = 0; +%! r = [1, 2, 3]; +%! z = 1; +%! [x, y, z2] = pol2cart (t, r, z); +%! assert (x, [1, 2, 3], eps); +%! assert (y, [0, 0, 0] / sqrt(2), eps); +%! assert (z, z2); + diff --git a/scripts/general/sph2cart.m b/scripts/general/sph2cart.m --- a/scripts/general/sph2cart.m +++ b/scripts/general/sph2cart.m @@ -19,7 +19,7 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{x}, @var{y}, @var{z}] =} sph2cart (@var{theta}, @var{phi}, @var{r}) ## Transform spherical to cartesian coordinates. -## @var{x}, @var{y} and @var{z} must be of same shape. +## @var{x}, @var{y} and @var{z} must be of same shape, or scalar. ## @var{theta} describes the angle relative to the x-axis. ## @var{phi} is the angle relative to the xy-plane. ## @var{r} is the distance to the origin (0, 0, 0). @@ -29,20 +29,60 @@ ## Author: Kai Habel ## Adapted-by: jwe -function [X, Y, Z] = sph2cart (Theta, Phi, R) +function [x, y, z] = sph2cart (theta, phi, r) if (nargin != 3) print_usage (); endif - if ((! (ismatrix (Theta) && ismatrix (Phi) && ismatrix (R))) - || (! size_equal (Theta, Phi)) - || (! size_equal (Theta, R))) - error ("sph2cart: arguments must be matrices of same size"); + if ((ismatrix (theta) && ismatrix (phi) && ismatrix (r)) + && (size_equal (theta, phi) || isscalar (theta) || isscalar (phi)) + && (size_equal (theta, r) || isscalar (theta) || isscalar (r)) + && (size_equal (phi, r) || isscalar (phi) || isscalar (r))) + + x = r .* cos (phi) .* cos (theta); + y = r .* cos (phi) .* sin (theta); + z = r .* sin (phi); + + else + error ("sph2cart: arguments must be matrices of same size, or scalar"); endif - X = R .* cos (Phi) .* cos (Theta); - Y = R .* cos (Phi) .* sin (Theta); - Z = R .* sin (Phi); +endfunction + +%!test +%! t = [0, 0, 0]; +%! p = [0, 0, 0]; +%! r = [0, 1, 2]; +%! [x, y, z] = sph2cart (t, p, r); +%! assert (x, r); +%! assert (y, [0, 0, 0]); +%! assert (z, [0, 0, 0]); -endfunction +%!test +%! t = 0; +%! p = [0, 0, 0]; +%! r = [0, 1, 2]; +%! [x, y, z] = sph2cart (t, p, r); +%! assert (x, r); +%! assert (y, [0, 0, 0]); +%! assert (z, [0, 0, 0]); + +%!test +%! t = [0, 0, 0]; +%! p = 0; +%! r = [0, 1, 2]; +%! [x, y, z] = sph2cart (t, p, r); +%! assert (x, r); +%! assert (y, [0, 0, 0]); +%! assert (z, [0, 0, 0]); + +%!test +%! t = [0, 0.5, 1]*pi; +%! p = [0, 0, 0]; +%! r = 1; +%! [x, y, z] = sph2cart (t, p, r); +%! assert (x, [1, 0, -1], eps); +%! assert (y, [0, 1, 0], eps); +%! assert (z, [0, 0, 0], eps); +