comparison scripts/general/sph2cart.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
24 ######################################################################## 24 ########################################################################
25 25
26 ## -*- texinfo -*- 26 ## -*- texinfo -*-
27 ## @deftypefn {} {[@var{x}, @var{y}, @var{z}] =} sph2cart (@var{theta}, @var{phi}, @var{r}) 27 ## @deftypefn {} {[@var{x}, @var{y}, @var{z}] =} sph2cart (@var{theta}, @var{phi}, @var{r})
28 ## @deftypefnx {} {[@var{x}, @var{y}, @var{z}] =} sph2cart (@var{S}) 28 ## @deftypefnx {} {[@var{x}, @var{y}, @var{z}] =} sph2cart (@var{S})
29 ## @deftypefnx {} {@var{C} =} sph2cart (@dots{})
30 ## Transform spherical coordinates to Cartesian coordinates. 29 ## Transform spherical coordinates to Cartesian coordinates.
31 ## 30 ##
32 ## The inputs @var{theta}, @var{phi}, and @var{r} must be the same shape, or 31 ## The inputs @var{theta}, @var{phi}, and @var{r} must be the same shape, or
33 ## scalar. If called with a single matrix argument then each row of @var{S} 32 ## scalar. If called with a single matrix argument then each row of @var{S}
34 ## represents the spherical coordinate (@var{theta}, @var{phi}, @var{r}). 33 ## must represent a spherical coordinate triplet (@var{theta}, @var{phi},
35 ## 34 ## @var{r}).
36 ## @var{theta} describes the angle relative to the positive x-axis. 35 ##
37 ## 36 ## The outputs @var{x}, @var{y}, @var{z} match the shape of the inputs. For a
38 ## @var{phi} is the angle relative to the xy-plane. 37 ## matrix input @var{S} the outputs are column vectors with rows corresponding
38 ## to the rows of the input matrix.
39 ##
40 ## @var{theta} describes the azimuth angle relative to the positive x-axis
41 ## measured in the xy-plane.
42 ##
43 ## @var{phi} is the elevation angle measured relative to the xy-plane.
39 ## 44 ##
40 ## @var{r} is the distance to the origin @w{(0, 0, 0)}. 45 ## @var{r} is the distance to the origin @w{(0, 0, 0)}.
41 ## 46 ##
42 ## If only a single return argument is requested then return a matrix @var{C} 47 ## The coordinate transformation is computed using:
43 ## where each row represents one Cartesian coordinate 48 ##
44 ## (@var{x}, @var{y}, @var{z}). 49 ## @tex
50 ## $$ x = r \cos \phi \cos \theta $$
51 ## $$ y = r \cos \phi \sin \theta $$
52 ## $$ z = r \sin \phi $$
53 ## @end tex
54 ## @ifnottex
55 ##
56 ## @example
57 ## @var{x} = r * cos (@var{phi}) * cos (@var{theta})
58 ## @var{y} = r * cos (@var{phi}) * sin (@var{theta})
59 ## @var{z} = r * sin (@var{phi})
60 ## @end example
61 ##
62 ## @end ifnottex
63 ## @c FIXME: Remove this note in Octave 9.1 (two releases after 7.1).
64 ## Note: For @sc{matlab} compatibility, this function no longer returns a full
65 ## coordinate matrix when called with a single return argument.
45 ## @seealso{cart2sph, pol2cart, cart2pol} 66 ## @seealso{cart2sph, pol2cart, cart2pol}
46 ## @end deftypefn 67 ## @end deftypefn
47 68
48 function [x, y, z] = sph2cart (theta, phi, r) 69 function [x, y, z] = sph2cart (theta, phi, r)
49 70
50 if (nargin != 1 && nargin != 3) 71 if (nargin != 1 && nargin != 3)
51 print_usage (); 72 print_usage ();
52 endif 73 endif
53 74
54 if (nargin == 1) 75 if (nargin == 1)
55 if (! (isnumeric (theta) && ismatrix (theta) && columns (theta) == 3)) 76 if (! (isnumeric (theta) && ismatrix (theta)))
56 error ("sph2cart: matrix input must have 3 columns [THETA, PHI, R]"); 77 error ("sph2cart: matrix input must be a 2-D numeric array");
57 endif 78 endif
58 r = theta(:,3); 79 if (columns (theta) != 3 && numel (theta) != 3)
59 phi = theta(:,2); 80 error ("sph2cart: matrix input must be a 3-element vector or 3-column array");
60 theta = theta(:,1); 81 endif
82
83 if (numel (theta) == 3)
84 r = theta(3);
85 phi = theta(2);
86 theta = theta(1);
87 else
88 r = theta(:,3);
89 phi = theta(:,2);
90 theta = theta(:,1);
91 endif
92
61 else 93 else
62 if (! isnumeric (theta) || ! isnumeric (phi) || ! isnumeric (r)) 94 if (! (isnumeric (theta) && isnumeric (phi) && isnumeric (r)))
63 error ("sph2cart: THETA, PHI, R must be numeric arrays of the same size, or scalar"); 95 error ("sph2cart: THETA, PHI, R must be numeric arrays or scalars");
64 endif 96 endif
65 [err, theta, phi, r] = common_size (theta, phi, r); 97 [err, theta, phi, r] = common_size (theta, phi, r);
66 if (err) 98 if (err)
67 error ("sph2cart: THETA, PHI, R must be numeric arrays of the same size, or scalar"); 99 error ("sph2cart: THETA, PHI, R must be the same size or scalars");
68 endif 100 endif
69 endif 101 endif
70 102
71 x = r .* cos (phi) .* cos (theta); 103 x = r .* cos (phi) .* cos (theta);
72 y = r .* cos (phi) .* sin (theta); 104 y = r .* cos (phi) .* sin (theta);
73 z = r .* sin (phi); 105 z = r .* sin (phi);
74 106
75 if (nargout <= 1)
76 x = [x(:), y(:), z(:)];
77 endif
78
79 endfunction 107 endfunction
80 108
81 109
82 %!test 110 %!test
83 %! t = [0, 0, 0]; 111 %! t = [0, 0, 0];
87 %! assert (x, r); 115 %! assert (x, r);
88 %! assert (y, [0, 0, 0]); 116 %! assert (y, [0, 0, 0]);
89 %! assert (z, [0, 0, 0]); 117 %! assert (z, [0, 0, 0]);
90 118
91 %!test 119 %!test
120 %! t = [0; 0; 0];
121 %! p = [0; 0; 0];
122 %! r = [0; 1; 2];
123 %! [x, y, z] = sph2cart (t, p, r);
124 %! assert (x, [0; 1; 2]);
125 %! assert (y, [0; 0; 0]);
126 %! assert (z, [0; 0; 0]);
127
128 %!test
92 %! t = 0; 129 %! t = 0;
93 %! p = [0, 0, 0]; 130 %! p = [0, 0, 0];
94 %! r = [0, 1, 2]; 131 %! r = [0, 1, 2];
95 %! C = sph2cart (t, p, r); 132 %! [x, y, z] = sph2cart (t, p, r);
96 %! assert (C(:,1), r(:)); 133 %! assert (x, [0, 1, 2]);
97 %! assert (C(:,2), [0; 0; 0]); 134 %! assert (y, [0, 0, 0]);
98 %! assert (C(:,3), [0; 0; 0]); 135 %! assert (z, [0, 0, 0]);
99 136
100 %!test 137 %!test
101 %! t = [0, 0, 0]; 138 %! t = [0, 0, 0];
102 %! p = 0; 139 %! p = 0;
103 %! r = [0, 1, 2]; 140 %! r = [0, 1, 2];
121 %! assert (y, [0, 0, 0], eps); 158 %! assert (y, [0, 0, 0], eps);
122 %! assert (z, [0, 0, 0], eps); 159 %! assert (z, [0, 0, 0], eps);
123 160
124 %!test 161 %!test
125 %! S = [ 0, 0, 1; 0.5*pi, 0, 1; pi, 0, 1]; 162 %! S = [ 0, 0, 1; 0.5*pi, 0, 1; pi, 0, 1];
126 %! C = [ 1, 0, 0; 0, 1, 0; -1, 0, 0]; 163 %! [x, y, z] = sph2cart (S);
127 %! assert (sph2cart (S), C, eps); 164 %! assert (x, [1; 0; -1], eps);
165 %! assert (y, [0; 1; 0], eps);
166 %! assert (z, [0; 0; 0], eps);
167
168 %!test
169 %! S = [ 0, 0, 1; 0.5*pi, 0, 1; pi, 0, 1; pi, pi, 1];
170 %! [x, y, z] = sph2cart (S);
171 %! assert (x, [1; 0; -1; 1], eps);
172 %! assert (y, [0; 1; 0; 0], eps);
173 %! assert (z, [0; 0; 0; 0], eps);
174
128 175
129 %!test 176 %!test
130 %! [t, p, r] = meshgrid ([0, pi/2], [0, pi/2], [0, 1]); 177 %! [t, p, r] = meshgrid ([0, pi/2], [0, pi/2], [0, 1]);
131 %! [x, y, z] = sph2cart (t, p, r); 178 %! [x, y, z] = sph2cart (t, p, r);
132 %! X = zeros(2, 2, 2); 179 %! X = zeros(2, 2, 2);
141 188
142 ## Test input validation 189 ## Test input validation
143 %!error sph2cart () 190 %!error sph2cart ()
144 %!error sph2cart (1,2) 191 %!error sph2cart (1,2)
145 %!error sph2cart (1,2,3,4) 192 %!error sph2cart (1,2,3,4)
146 %!error <matrix input must have 3 columns> sph2cart ({1,2,3}) 193 %!error <matrix input must be a 2-D numeric array> sph2cart ({1,2,3})
147 %!error <matrix input must have 3 columns> sph2cart (ones (3,3,2)) 194 %!error <matrix input must be a 2-D numeric array> sph2cart (ones (3,3,2))
148 %!error <matrix input must have 3 columns> sph2cart ([1,2,3,4]) 195 %!error <matrix input must be a 3-element> sph2cart ([1,2,3,4])
149 %!error <numeric arrays of the same size> sph2cart ({1,2,3}, [1,2,3], [1,2,3]) 196 %!error <matrix input must be a 3-element> sph2cart ([1,2,3,4; 1,2,3,4; 1,2,3,4])
150 %!error <numeric arrays of the same size> sph2cart ([1,2,3], {1,2,3}, [1,2,3]) 197 %!error <must be numeric arrays or scalars> sph2cart ({1,2,3}, [1,2,3], [1,2,3])
151 %!error <numeric arrays of the same size> sph2cart ([1,2,3], [1,2,3], {1,2,3}) 198 %!error <must be numeric arrays or scalars> sph2cart ([1,2,3], {1,2,3}, [1,2,3])
152 %!error <numeric arrays of the same size> sph2cart (ones (3,3,3), 1, ones (3,2,3)) 199 %!error <must be numeric arrays or scalars> sph2cart ([1,2,3], [1,2,3], {1,2,3})
153 %!error <numeric arrays of the same size> sph2cart (ones (3,3,3), ones (3,2,3), 1) 200 %!error <must be the same size or scalars> sph2cart ([1,2,3], [1,2,3], [1,2,3]')
201 %!error <must be the same size or scalars> sph2cart (ones (3,3,3), 1, ones (3,2,3))
202 %!error <must be the same size or scalars> sph2cart (ones (3,3,3), ones (3,2,3), 1)