Mercurial > octave
comparison scripts/general/cart2pol.m @ 28171:a23da76e0693
Matlab compatibility fixes for coordinate transform functions (bug #57794).
* cart2pol.m, cart2sph.m, pol2cart.m, sph2cart.m: Modified to allow row or
column vector inputs, remove full matrix single output argument option, and
clarified coordinate definitions in help text.
* lightangle.m, surfl.m: Fix existing instances where single output was used
and a matrix was expected.
* NEWS: Added coordinate transform changes to Matlab compatibility section.
author | Nicholas R. Jankowski <jankowskin@asme.org> |
---|---|
date | Sun, 16 Feb 2020 20:19:05 -0500 |
parents | a4268efb7334 |
children | 28de41192f3c |
comparison
equal
deleted
inserted
replaced
28170:5e49ba5bdcc1 | 28171:a23da76e0693 |
---|---|
26 ## -*- texinfo -*- | 26 ## -*- texinfo -*- |
27 ## @deftypefn {} {[@var{theta}, @var{r}] =} cart2pol (@var{x}, @var{y}) | 27 ## @deftypefn {} {[@var{theta}, @var{r}] =} cart2pol (@var{x}, @var{y}) |
28 ## @deftypefnx {} {[@var{theta}, @var{r}, @var{z}] =} cart2pol (@var{x}, @var{y}, @var{z}) | 28 ## @deftypefnx {} {[@var{theta}, @var{r}, @var{z}] =} cart2pol (@var{x}, @var{y}, @var{z}) |
29 ## @deftypefnx {} {[@var{theta}, @var{r}] =} cart2pol (@var{C}) | 29 ## @deftypefnx {} {[@var{theta}, @var{r}] =} cart2pol (@var{C}) |
30 ## @deftypefnx {} {[@var{theta}, @var{r}, @var{z}] =} cart2pol (@var{C}) | 30 ## @deftypefnx {} {[@var{theta}, @var{r}, @var{z}] =} cart2pol (@var{C}) |
31 ## @deftypefnx {} {@var{P} =} cart2pol (@dots{}) | |
32 ## | 31 ## |
33 ## Transform Cartesian coordinates to polar or cylindrical coordinates. | 32 ## Transform Cartesian coordinates to polar or cylindrical coordinates. |
34 ## | 33 ## |
35 ## The inputs @var{x}, @var{y} (, and @var{z}) must be the same shape, or | 34 ## The inputs @var{x}, @var{y} (, and @var{z}) must be the same shape, or |
36 ## scalar. If called with a single matrix argument then each row of @var{C} | 35 ## scalar. If called with a single matrix argument then each row of @var{C} |
37 ## represents the Cartesian coordinate (@var{x}, @var{y} (, @var{z})). | 36 ## represents the Cartesian coordinate pair (@var{x}, @var{y}) or triplet |
38 ## | 37 ## (@var{x}, @var{y}, @var{z}). |
39 ## @var{theta} describes the angle relative to the positive x-axis. | 38 ## |
39 ## The outputs @var{theta}, @var{r} (, and @var{z}) match the shape of the | |
40 ## inputs. For a matrix input @var{C} the outputs will be column vectors with | |
41 ## rows corresponding to the rows of the input matrix. | |
42 ## | |
43 ## @var{theta} describes the angle relative to the positive x-axis measured in | |
44 ## the xy-plane. | |
40 ## | 45 ## |
41 ## @var{r} is the distance to the z-axis @w{(0, 0, z)}. | 46 ## @var{r} is the distance to the z-axis @w{(0, 0, z)}. |
42 ## | 47 ## |
43 ## If only a single return argument is requested then return a matrix @var{P} | 48 ## @var{z}, if present, is unchanged by the transformation. |
44 ## where each row represents one polar/(cylindrical) coordinate | 49 ## |
45 ## (@var{theta}, @var{phi} (, @var{z})). | 50 ## The coordinate transformation is computed using: |
51 ## | |
52 ## @tex | |
53 ## $$ \theta = \arctan \left ( {y \over x} \right ) $$ | |
54 ## $$ r = \sqrt{x^2 + y^2} $$ | |
55 ## $$ z = z $$ | |
56 ## @end tex | |
57 ## @ifnottex | |
58 ## | |
59 ## @example | |
60 ## @group | |
61 ## @var{theta} = arctan (@var{y} / @var{x}) | |
62 ## @var{r} = sqrt (@var{x}^2 + @var{y}^2) | |
63 ## @var{z} = @var{z} | |
64 ## @end group | |
65 ## @end example | |
66 ## | |
67 ## @end ifnottex | |
68 ## | |
69 ## @c FIXME: Remove this note in Octave 9.1 (two releases after 7.1). | |
70 ## Note: For @sc{matlab} compatibility, this function no longer returns a full | |
71 ## coordinate matrix when called with a single return argument. | |
46 ## @seealso{pol2cart, cart2sph, sph2cart} | 72 ## @seealso{pol2cart, cart2sph, sph2cart} |
47 ## @end deftypefn | 73 ## @end deftypefn |
48 | 74 |
49 function [theta, r, z] = cart2pol (x, y, z = []) | 75 function [theta, r, z] = cart2pol (x, y, z = []) |
50 | 76 |
51 if (nargin < 1 || nargin > 3) | 77 if (nargin < 1 || nargin > 3) |
52 print_usage (); | 78 print_usage (); |
53 endif | 79 endif |
54 | 80 |
55 if (nargin == 1) | 81 if (nargin == 1) |
56 if (! (isnumeric (x) && ismatrix (x) | 82 if (! (isnumeric (x) && ismatrix (x))) |
57 && (columns (x) == 2 || columns (x) == 3))) | 83 error ("cart2pol: matrix input must be 2-D numeric array"); |
58 error ("cart2pol: matrix input must have 2 or 3 columns [X, Y (, Z)]"); | 84 endif |
59 endif | 85 if (isvector (x)) |
60 if (columns (x) == 3) | 86 n = numel (x); |
61 z = x(:,3); | 87 if (n != 2 && n != 3) |
62 endif | 88 error ("cart2pol: matrix input must be a 2- or 3-element vector or a 2- or 3-column array"); |
63 y = x(:,2); | 89 endif |
64 x = x(:,1); | 90 if (n == 3) |
91 z = x(3); | |
92 endif | |
93 y = x(2); | |
94 x = x(1); | |
95 else | |
96 ncols = columns (x); | |
97 if (ncols != 2 && ncols != 3) | |
98 error ("cart2pol: matrix input must be a 2- or 3-element vector or a 2- or 3-column array"); | |
99 endif | |
100 | |
101 if (ncols == 3) | |
102 z = x(:,3); | |
103 endif | |
104 y = x(:,2); | |
105 x = x(:,1); | |
106 endif | |
107 | |
65 elseif (nargin == 2) | 108 elseif (nargin == 2) |
66 if (! isnumeric (x) || ! isnumeric (y)) | 109 if (! (isnumeric (x) && isnumeric (y))) |
67 error ("cart2pol: X, Y must be numeric arrays of the same size, or scalar"); | 110 error ("cart2pol: X, Y must be numeric arrays or scalars"); |
68 endif | 111 endif |
69 [err, x, y] = common_size (x, y); | 112 [err, x, y] = common_size (x, y); |
70 if (err) | 113 if (err) |
71 error ("cart2pol: X, Y must be numeric arrays of the same size, or scalar"); | 114 error ("cart2pol: X, Y must be the same size or scalars"); |
72 endif | 115 endif |
116 | |
73 elseif (nargin == 3) | 117 elseif (nargin == 3) |
74 if (! isnumeric (x) || ! isnumeric (y) || ! isnumeric (z)) | 118 if (! (isnumeric (x) && isnumeric (y) && isnumeric (z))) |
75 error ("cart2pol: X, Y, Z must be numeric arrays of the same size, or scalar"); | 119 error ("cart2pol: X, Y, Z must be numeric arrays or scalars"); |
76 endif | 120 endif |
77 [err, x, y, z] = common_size (x, y, z); | 121 [err, x, y, z] = common_size (x, y, z); |
78 if (err) | 122 if (err) |
79 error ("cart2pol: X, Y, Z must be numeric arrays of the same size, or scalar"); | 123 error ("cart2pol: X, Y, Z must be the same size or scalars"); |
80 endif | 124 endif |
81 endif | 125 endif |
82 | 126 |
83 theta = atan2 (y, x); | 127 theta = atan2 (y, x); |
84 r = sqrt (x .^ 2 + y .^ 2); | 128 r = sqrt (x .^ 2 + y .^ 2); |
85 | 129 |
86 if (nargout <= 1) | |
87 if (isempty (z)) | |
88 theta = [theta(:), r(:)]; | |
89 else | |
90 theta = [theta(:), r(:), z(:)]; | |
91 endif | |
92 endif | |
93 | |
94 endfunction | 130 endfunction |
95 | 131 |
96 | 132 |
97 %!test | 133 %!test |
98 %! x = [0, 1, 2]; | 134 %! x = [0, 1, 2]; |
102 %! assert (r, x); | 138 %! assert (r, x); |
103 | 139 |
104 %!test | 140 %!test |
105 %! x = [0, 1, 2]; | 141 %! x = [0, 1, 2]; |
106 %! y = [0, 1, 2]; | 142 %! y = [0, 1, 2]; |
107 %! P = cart2pol (x, y); | 143 %! [t, r] = cart2pol (x, y); |
108 %! assert (P(:,1), [0; pi/4; pi/4], sqrt (eps)); | 144 %! assert (t, [0, pi/4, pi/4], eps); |
109 %! assert (P(:,2), sqrt (2)*[0; 1; 2], sqrt (eps)); | 145 %! assert (r, sqrt (2)*[0, 1, 2], eps); |
146 | |
147 %!test | |
148 %! x = [0, 1, 2]'; | |
149 %! y = [0, 1, 2]'; | |
150 %! [t, r] = cart2pol (x, y); | |
151 %! assert (t, [0; pi/4; pi/4], eps); | |
152 %! assert (r, sqrt (2)*[0; 1; 2], eps); | |
110 | 153 |
111 %!test | 154 %!test |
112 %! x = [0, 1, 2]; | 155 %! x = [0, 1, 2]; |
113 %! y = [0, 1, 2]; | 156 %! y = [0, 1, 2]; |
114 %! z = [0, 1, 2]; | 157 %! z = [0, 1, 2]; |
144 %! assert (r, [0, 0, 0]); | 187 %! assert (r, [0, 0, 0]); |
145 %! assert (z2, z); | 188 %! assert (z2, z); |
146 | 189 |
147 %!test | 190 %!test |
148 %! C = [0, 0; 1, 1; 2, 2]; | 191 %! C = [0, 0; 1, 1; 2, 2]; |
149 %! P = [0, 0; pi/4, sqrt(2); pi/4, 2*sqrt(2)]; | 192 %! [t, r] = cart2pol (C); |
150 %! assert (cart2pol (C), P, sqrt (eps)); | 193 %! assert (t, [0; 1; 1]*pi/4, eps); |
194 %! assert (r, [0; 1; 2]*sqrt(2), eps); | |
151 | 195 |
152 %!test | 196 %!test |
153 %! C = [0, 0, 0; 1, 1, 1; 2, 2, 2]; | 197 %! C = [0, 0, 0; 1, 1, 1; 2, 2, 2]; |
154 %! P = [0, 0, 0; pi/4, sqrt(2), 1; pi/4, 2*sqrt(2), 2]; | 198 %! [t, r, z] = cart2pol (C); |
155 %! assert (cart2pol (C), P, sqrt (eps)); | 199 %! assert (t, [0; 1; 1]*pi/4, eps); |
200 %! assert (r, [0; 1; 2]*sqrt(2), eps); | |
201 %! assert (z, [0; 1; 2]); | |
202 | |
203 %!test | |
204 %! C = [0, 0, 0; 1, 1, 1; 2, 2, 2;1, 1, 1]; | |
205 %! [t, r, z] = cart2pol (C); | |
206 %! assert (t, [0; 1; 1; 1]*pi/4, eps); | |
207 %! assert (r, [0; 1; 2; 1]*sqrt(2), eps); | |
208 %! assert (z, [0; 1; 2; 1]); | |
156 | 209 |
157 %!test | 210 %!test |
158 %! x = zeros (1, 1, 1, 2); | 211 %! x = zeros (1, 1, 1, 2); |
159 %! x(1, 1, 1, 2) = sqrt (2); | 212 %! x(1, 1, 1, 2) = sqrt (2); |
160 %! y = x; | 213 %! y = x; |
177 %! assert (z, Z); | 230 %! assert (z, Z); |
178 | 231 |
179 ## Test input validation | 232 ## Test input validation |
180 %!error cart2pol () | 233 %!error cart2pol () |
181 %!error cart2pol (1,2,3,4) | 234 %!error cart2pol (1,2,3,4) |
182 %!error <matrix input must have 2 or 3 columns> cart2pol ({1,2,3}) | 235 %!error <matrix input must be 2-D numeric array> cart2pol ({1,2,3}) |
183 %!error <matrix input must have 2 or 3 columns> cart2pol (ones (3,3,2)) | 236 %!error <matrix input must be 2-D numeric array> cart2pol (ones (3,3,2)) |
184 %!error <matrix input must have 2 or 3 columns> cart2pol ([1]) | 237 %!error <matrix input must be a 2- or 3-element> cart2pol ([1]) |
185 %!error <matrix input must have 2 or 3 columns> cart2pol ([1,2,3,4]) | 238 %!error <matrix input must be a 2- or 3-element> cart2pol ([1,2,3,4]) |
186 %!error <numeric arrays of the same size> cart2pol ({1,2,3}, [1,2,3]) | 239 %!error <must be numeric arrays or scalars> cart2pol ({1,2,3}, [1,2,3]) |
187 %!error <numeric arrays of the same size> cart2pol ([1,2,3], {1,2,3}) | 240 %!error <must be numeric arrays or scalars> cart2pol ([1,2,3], {1,2,3}) |
188 %!error <numeric arrays of the same size> cart2pol (ones (3,3,3), ones (3,2,3)) | 241 %!error <must be the same size or scalars> cart2pol (ones (3,3,3), ones (3,2,3)) |
189 %!error <numeric arrays of the same size> cart2pol ({1,2,3}, [1,2,3], [1,2,3]) | 242 %!error <must be the same size or scalars> cart2pol ([1; 1], [2, 2]) |
190 %!error <numeric arrays of the same size> cart2pol ([1,2,3], {1,2,3}, [1,2,3]) | 243 %!error <must be the same size or scalars> cart2pol ([1; 1], [2, 2], [3, 3]) |
191 %!error <numeric arrays of the same size> cart2pol ([1,2,3], [1,2,3], {1,2,3}) | 244 %!error <must be numeric arrays or scalars> cart2pol ({1,2,3}, [1,2,3], [1,2,3]) |
192 %!error <numeric arrays of the same size> cart2pol (ones (3,3,3), 1, ones (3,2,3)) | 245 %!error <must be numeric arrays or scalars> cart2pol ([1,2,3], {1,2,3}, [1,2,3]) |
193 %!error <numeric arrays of the same size> cart2pol (ones (3,3,3), ones (3,2,3), 1) | 246 %!error <must be numeric arrays or scalars> cart2pol ([1,2,3], [1,2,3], {1,2,3}) |
247 %!error <must be the same size or scalars> cart2pol (ones (3,3,3), 1, ones (3,2,3)) | |
248 %!error <must be the same size or scalars> cart2pol (ones (3,3,3), ones (3,2,3), 1) |