Mercurial > octave-libtiff
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) |