comparison scripts/general/pol2cart.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 e82484e1b2f6
comparison
equal deleted inserted replaced
28170:5e49ba5bdcc1 28171:a23da76e0693
26 ## -*- texinfo -*- 26 ## -*- texinfo -*-
27 ## @deftypefn {} {[@var{x}, @var{y}] =} pol2cart (@var{theta}, @var{r}) 27 ## @deftypefn {} {[@var{x}, @var{y}] =} pol2cart (@var{theta}, @var{r})
28 ## @deftypefnx {} {[@var{x}, @var{y}, @var{z}] =} pol2cart (@var{theta}, @var{r}, @var{z}) 28 ## @deftypefnx {} {[@var{x}, @var{y}, @var{z}] =} pol2cart (@var{theta}, @var{r}, @var{z})
29 ## @deftypefnx {} {[@var{x}, @var{y}] =} pol2cart (@var{P}) 29 ## @deftypefnx {} {[@var{x}, @var{y}] =} pol2cart (@var{P})
30 ## @deftypefnx {} {[@var{x}, @var{y}, @var{z}] =} pol2cart (@var{P}) 30 ## @deftypefnx {} {[@var{x}, @var{y}, @var{z}] =} pol2cart (@var{P})
31 ## @deftypefnx {} {@var{C} =} pol2cart (@dots{})
32 ## Transform polar or cylindrical coordinates to Cartesian coordinates. 31 ## Transform polar or cylindrical coordinates to Cartesian coordinates.
33 ## 32 ##
34 ## The inputs @var{theta}, @var{r}, (and @var{z}) must be the same shape, or 33 ## The inputs @var{theta}, @var{r}, (and @var{z}) must be the same shape, or
35 ## scalar. If called with a single matrix argument then each row of @var{P} 34 ## scalar. If called with a single matrix argument then each row of @var{P}
36 ## represents the polar/(cylindrical) coordinate (@var{theta}, @var{r} 35 ## represents the polar coordinate pair (@var{theta}, @var{r}) or the
37 ## (, @var{z})). 36 ## cylindrical triplet (@var{theta}, @var{r}, @var{z}).
38 ## 37 ##
39 ## @var{theta} describes the angle relative to the positive x-axis. 38 ## The outputs @var{x}, @var{y} (, and @var{z}) match the shape of the inputs.
40 ## 39 ## For a matrix input @var{P} the outputs will be column vectors with rows
41 ## @var{r} is the distance to the z-axis (0, 0, z). 40 ## corresponding to the rows of the input matrix.
42 ## 41 ##
43 ## If only a single return argument is requested then return a matrix @var{C} 42 ## @var{theta} describes the angle relative to the positive x-axis measured in
44 ## where each row represents one Cartesian coordinate 43 ## the xy-plane.
45 ## (@var{x}, @var{y} (, @var{z})). 44 ##
45 ## @var{r} is the distance to the z-axis @w{(0, 0, z)}.
46 ##
47 ## @var{z}, if present, is unchanged by the transformation.
48 ##
49 ## The coordinate transformation is computed using:
50 ##
51 ## @tex
52 ## $$ x = r \cos \theta $$
53 ## $$ y = r \sin \theta $$
54 ## $$ z = z $$
55 ## @end tex
56 ## @ifnottex
57 ##
58 ## @example
59 ## @var{x} = @var{r} * cos (@var{theta})
60 ## @var{y} = @var{r} * sin (@var{theta})
61 ## @var{z} = @var{z}
62 ## @end example
63 ##
64 ## @end ifnottex
65 ## @c FIXME: Remove this note in Octave 9.1 (two releases after 7.1).
66 ## Note: For @sc{matlab} compatibility, this function no longer returns a full
67 ## coordinate matrix when called with a single return argument.
46 ## @seealso{cart2pol, sph2cart, cart2sph} 68 ## @seealso{cart2pol, sph2cart, cart2sph}
47 ## @end deftypefn 69 ## @end deftypefn
48 70
49 function [x, y, z] = pol2cart (theta, r, z = []) 71 function [x, y, z] = pol2cart (theta, r, z = [])
50 72
51 if (nargin < 1 || nargin > 3) 73 if (nargin < 1 || nargin > 3)
52 print_usage (); 74 print_usage ();
53 endif 75 endif
54 76
55 if (nargin == 1) 77 if (nargin == 1)
56 if (! (isnumeric (theta) && ismatrix (theta) 78 if (! (isnumeric (theta) && ismatrix (theta)))
57 && (columns (theta) == 2 || columns (theta) == 3))) 79 error ("cart2pol: matrix input P must be 2-D numeric array");
58 error ("pol2cart: matrix input must have 2 or 3 columns [THETA, R (, Z)]"); 80 endif
59 endif 81 if (isvector (theta))
60 if (columns (theta) == 3) 82 n = numel (theta);
61 z = theta(:,3); 83 if (n != 2 && n != 3)
62 endif 84 error ("cart2pol: matrix input must be a 2- or 3-element vector or a 2- or 3-column array");
63 r = theta(:,2); 85 endif
64 theta = theta(:,1); 86 if (n == 3)
87 z = theta(3);
88 endif
89 r = theta(2);
90 theta = theta(1);
91
92 else
93 ncols = columns(theta);
94 if (ncols != 2 && ncols != 3)
95 error ("cart2pol: matrix input must be a 2- or 3-element vector or a 2- or 3-column array");
96 endif
97
98 if (ncols == 3)
99 z = theta(:,3);
100 endif
101 r = theta(:,2);
102 theta = theta(:,1);
103 endif
104
65 elseif (nargin == 2) 105 elseif (nargin == 2)
66 if (! isnumeric (theta) || ! isnumeric (r)) 106 if (! (isnumeric (theta) && isnumeric (r)))
67 error ("pol2cart: THETA, R must be numeric arrays of the same size, or scalar"); 107 error ("pol2cart: THETA, R must be numeric arrays or scalars");
68 endif 108 endif
69 [err, theta, r] = common_size (theta, r); 109 [err, theta, r] = common_size (theta, r);
70 if (err) 110 if (err)
71 error ("pol2cart: THETA, R must be numeric arrays of the same size, or scalar"); 111 error ("pol2cart: THETA, R must be the same size or scalars");
72 endif 112 endif
113
73 elseif (nargin == 3) 114 elseif (nargin == 3)
74 if (! isnumeric (theta) || ! isnumeric (r) || ! isnumeric (z)) 115 if (! (isnumeric (theta) && isnumeric (r) && isnumeric (z)))
75 error ("pol2cart: THETA, R, Z must be numeric arrays of the same size, or scalar"); 116 error ("pol2cart: THETA, R, Z must be numeric arrays or scalars");
76 endif 117 endif
77 [err, theta, r, z] = common_size (theta, r, z); 118 [err, theta, r, z] = common_size (theta, r, z);
78 if (err) 119 if (err)
79 error ("pol2cart: THETA, R, Z must be numeric arrays of the same size, or scalar"); 120 error ("pol2cart: THETA, R, Z must be the same size or scalars");
80 endif 121 endif
81 endif 122 endif
82 123
83 x = r .* cos (theta); 124 x = r .* cos (theta);
84 y = r .* sin (theta); 125 y = r .* sin (theta);
85
86 if (nargout <= 1)
87 if (isempty (z))
88 x = [x(:), y(:)];
89 else
90 x = [x(:), y(:), z(:)];
91 endif
92 endif
93 126
94 endfunction 127 endfunction
95 128
96 129
97 %!test 130 %!test
98 %! t = [0, 0.5, 1] * pi; 131 %! t = [0, 0.5, 1] * pi;
99 %! r = 1; 132 %! r = 1;
100 %! [x, y] = pol2cart (t, r); 133 %! [x, y] = pol2cart (t, r);
101 %! assert (x, [1, 0, -1], sqrt (eps)); 134 %! assert (x, [1, 0, -1], eps);
102 %! assert (y, [0, 1, 0], sqrt (eps)); 135 %! assert (y, [0, 1, 0], eps);
103 136
104 %!test 137 %!test
105 %! t = [0, 1, 1] * pi/4; 138 %! t = [0, 1, 1] * pi/4;
106 %! r = sqrt (2) * [0, 1, 2]; 139 %! r = sqrt (2) * [0, 1, 2];
107 %! C = pol2cart (t, r); 140 %! [x, y] = pol2cart (t, r);
108 %! assert (C(:,1), [0; 1; 2], sqrt (eps)); 141 %! assert (x, [0, 1, 2], 2*eps);
109 %! assert (C(:,2), [0; 1; 2], sqrt (eps)); 142 %! assert (y, [0, 1, 2], 2*eps);
110 143
111 %!test 144 %!test
112 %! t = [0, 1, 1] * pi/4; 145 %! t = [0, 1, 1] * pi/4;
113 %! r = sqrt (2) * [0, 1, 2]; 146 %! r = sqrt (2) * [0, 1, 2];
114 %! z = [0, 1, 2]; 147 %! z = [0, 1, 2];
115 %! [x, y, z2] = pol2cart (t, r, z); 148 %! [x, y, z2] = pol2cart (t, r, z);
116 %! assert (x, [0, 1, 2], sqrt (eps)); 149 %! assert (x, [0, 1, 2], 2*eps);
117 %! assert (y, [0, 1, 2], sqrt (eps)); 150 %! assert (y, [0, 1, 2], 2*eps);
118 %! assert (z2, z); 151 %! assert (z2, z);
152
153 %!test
154 %! t = [0; 1; 1] * pi/4;
155 %! r = sqrt (2) * [0; 1; 2];
156 %! z = [0; 1; 2];
157 %! [x, y, z2] = pol2cart (t, r, z);
158 %! assert (x, [0; 1; 2], 2*eps);
159 %! assert (y, [0; 1; 2], 2*eps);
160 %! assert (z2, z);
161
119 162
120 %!test 163 %!test
121 %! t = 0; 164 %! t = 0;
122 %! r = [0, 1, 2]; 165 %! r = [0, 1, 2];
123 %! z = [0, 1, 2]; 166 %! z = [0, 1, 2];
124 %! [x, y, z2] = pol2cart (t, r, z); 167 %! [x, y, z2] = pol2cart (t, r, z);
125 %! assert (x, [0, 1, 2], sqrt (eps)); 168 %! assert (x, [0, 1, 2], eps);
126 %! assert (y, [0, 0, 0], sqrt (eps)); 169 %! assert (y, [0, 0, 0], eps);
127 %! assert (z2, z); 170 %! assert (z2, z);
128 171
129 %!test 172 %!test
130 %! t = [1, 1, 1]*pi/4; 173 %! t = [1, 1, 1]*pi/4;
131 %! r = 1; 174 %! r = 1;
144 %! assert (y, [0, 0, 0] / sqrt (2), eps); 187 %! assert (y, [0, 0, 0] / sqrt (2), eps);
145 %! assert (z2, [1, 1, 1]); 188 %! assert (z2, [1, 1, 1]);
146 189
147 %!test 190 %!test
148 %! P = [0, 0; pi/4, sqrt(2); pi/4, 2*sqrt(2)]; 191 %! P = [0, 0; pi/4, sqrt(2); pi/4, 2*sqrt(2)];
149 %! C = [0, 0; 1, 1; 2, 2]; 192 %! [x, y] = pol2cart(P);
150 %! assert (pol2cart (P), C, sqrt (eps)); 193 %! assert (x, [0; 1; 2], 2*eps);
194 %! assert (y, [0; 1; 2], 2*eps);
151 195
152 %!test 196 %!test
153 %! P = [0, 0, 0; pi/4, sqrt(2), 1; pi/4, 2*sqrt(2), 2]; 197 %! P = [0, 0, 0; pi/4, sqrt(2), 1; pi/4, 2*sqrt(2), 2];
154 %! C = [0, 0, 0; 1, 1, 1; 2, 2, 2]; 198 %! [x, y, z] = pol2cart(P);
155 %! assert (pol2cart (P), C, sqrt (eps)); 199 %! assert (x, [0; 1; 2], 2*eps);
200 %! assert (y, [0; 1; 2], 2*eps);
201 %! assert (z, P(:,3), 2*eps);
202
203 %!test
204 %! P = [0, 0, 0; pi/4, sqrt(2), 1; pi/4, 2*sqrt(2), 2; 0, 0, 0];
205 %! [x, y, z] = pol2cart(P);
206 %! assert (x, [0; 1; 2; 0], 2*eps);
207 %! assert (y, [0; 1; 2; 0], 2*eps);
208 %! assert (z, P(:,3), 2*eps);
156 209
157 %!test 210 %!test
158 %! r = ones (1, 1, 1, 2); 211 %! r = ones (1, 1, 1, 2);
159 %! r(1, 1, 1, 2) = 2; 212 %! r(1, 1, 1, 2) = 2;
160 %! t = pi/2 * r; 213 %! t = pi/2 * r;
180 %! assert (z, Z); 233 %! assert (z, Z);
181 234
182 ## Test input validation 235 ## Test input validation
183 %!error pol2cart () 236 %!error pol2cart ()
184 %!error pol2cart (1,2,3,4) 237 %!error pol2cart (1,2,3,4)
185 %!error <matrix input must have 2 or 3 columns> pol2cart ({1,2,3}) 238 %!error <matrix input P must be 2-D numeric array> pol2cart ({1,2,3})
186 %!error <matrix input must have 2 or 3 columns> pol2cart (ones (3,3,2)) 239 %!error <matrix input P must be 2-D numeric array> pol2cart (ones (3,3,2))
187 %!error <matrix input must have 2 or 3 columns> pol2cart ([1]) 240 %!error <matrix input must be a 2- or 3-element> pol2cart ([1])
188 %!error <matrix input must have 2 or 3 columns> pol2cart ([1,2,3,4]) 241 %!error <matrix input must be a 2- or 3-element> pol2cart ([1,2,3,4])
189 %!error <numeric arrays of the same size> pol2cart ({1,2,3}, [1,2,3]) 242 %!error <must be numeric arrays or scalars> pol2cart ({1,2,3}, [1,2,3])
190 %!error <numeric arrays of the same size> pol2cart ([1,2,3], {1,2,3}) 243 %!error <must be numeric arrays or scalars> pol2cart ([1,2,3], {1,2,3})
191 %!error <numeric arrays of the same size> pol2cart (ones (3,3,3), ones (3,2,3)) 244 %!error <must be the same size or scalars> pol2cart (ones (3,3,3), ones (3,2,3))
192 %!error <numeric arrays of the same size> pol2cart ({1,2,3}, [1,2,3], [1,2,3]) 245 %!error <must be the same size or scalars> pol2cart ([1; 1], [2, 2])
193 %!error <numeric arrays of the same size> pol2cart ([1,2,3], {1,2,3}, [1,2,3]) 246 %!error <must be the same size or scalars> pol2cart ([1; 1], [2, 2], [3, 3])
194 %!error <numeric arrays of the same size> pol2cart ([1,2,3], [1,2,3], {1,2,3}) 247 %!error <must be numeric arrays or scalars> pol2cart ({1,2,3}, [1,2,3], [1,2,3])
195 %!error <numeric arrays of the same size> pol2cart (ones (3,3,3), 1, ones (3,2,3)) 248 %!error <must be numeric arrays or scalars> pol2cart ([1,2,3], {1,2,3}, [1,2,3])
196 %!error <numeric arrays of the same size> pol2cart (ones (3,3,3), ones (3,2,3), 1) 249 %!error <must be numeric arrays or scalars> pol2cart ([1,2,3], [1,2,3], {1,2,3})
250 %!error <must be the same size or scalars> pol2cart (ones (3,3,3), 1, ones (3,2,3))
251 %!error <must be the same size or scalars> pol2cart (ones (3,3,3), ones (3,2,3), 1)