|
3 | 3 | % planet3D Creates high-resolution renderings of the Earth and the major |
4 | 4 | % celestial bodies in our solar system for space mechanics applications. |
5 | 5 | % |
| 6 | +% planet3D |
6 | 7 | % planet3D(planet) |
7 | 8 | % planet3D(planet,opts) |
8 | 9 | % planet_surface = planet3D(__) |
9 | 10 | % |
10 | 11 | % See also background, ground_track. |
11 | 12 | % |
12 | 13 | % Copyright © 2021 Tamas Kis |
13 | | -% Last Update: 2021-12-12 |
| 14 | +% Last Update: 2022-04-20 |
14 | 15 | % Website: https://tamaskis.github.io |
15 | 16 | % Contact: tamas.a.kis@outlook.com |
16 | 17 | % |
17 | 18 | % TECHNICAL DOCUMENTATION: |
18 | 19 | % https://tamaskis.github.io/documentation/Visualizing_Celestial_Bodies_in_3D.pdf |
19 | 20 | % |
20 | | -% REFERENCES: |
21 | | -% [1] https://mathworks.com/matlabcentral/fileexchange/27123-earth-sized-sphere-with-topography |
22 | | -% [2] https://apps.dtic.mil/sti/pdfs/AD1000581.pdf |
23 | | -% [3] https://www.mathworks.com/matlabcentral/fileexchange/13823-3d-earth-example |
24 | | -% [4] https://nssdc.gsfc.nasa.gov/planetary/factsheet/mercuryfact.html |
25 | | -% [5] https://en.wikipedia.org/wiki/Moon |
26 | | -% [6] https://www.jpl.nasa.gov/images/pluto-color-map |
27 | | -% [7] https://en.wikipedia.org/wiki/Rings_of_Saturn |
28 | | -% [8] https://www.solarsystemscope.com/textures/ |
29 | | -% [9] https://en.wikipedia.org/wiki/Sun |
30 | | -% [10] https://visibleearth.nasa.gov/images/57730/the-blue-marble-land-surface-ocean-color-and-sea-ice/57731l |
31 | | -% [11] Vallado, "Fundamentals of Astrodynamics and Applications", 4th |
32 | | -% Ed., Tables D-3, D-4, and D-5 (pp. 1041-1042) |
33 | | -% [12] https://nssdc.gsfc.nasa.gov/planetary/factsheet/venusfact.html |
34 | | -% |
35 | 21 | %-------------------------------------------------------------------------- |
36 | 22 | % |
37 | 23 | % ------ |
38 | 24 | % INPUT: |
39 | 25 | % ------ |
40 | | -% planet - (char) 'Sun', 'Moon', 'Mercury', 'Venus', 'Earth', |
41 | | -% 'Earth Cloudy', 'Earth Coastlines', 'Earth Night', |
42 | | -% 'Earth Night Cloudy', 'Mars', 'Jupiter', 'Saturn', |
43 | | -% 'Uranus', 'Neptune', or 'Pluto' |
44 | | -% opts - (OPTIONAL) (1×1 struct) plot options |
| 26 | +% planet - (char) (OPTIONAL) 'Sun', 'Moon', 'Mercury', 'Venus', |
| 27 | +% 'Earth', 'Earth Cloudy', 'Earth Coastlines', |
| 28 | +% 'Earth Night', 'Earth Night Cloudy', 'Mars', |
| 29 | +% 'Jupiter', 'Saturn', 'Uranus', 'Neptune', or 'Pluto' |
| 30 | +% (defaults to 'Earth Cloudy') |
| 31 | +% opts - (1×1 struct) (OPTIONAL) plot options |
45 | 32 | % • Clipping - (char) 'on' or 'off' (defaults to 'off') |
46 | 33 | % --> if 'on', the surface will be "clipped" to fit |
47 | 34 | % the axes when zooming in |
|
76 | 63 | % background, the function call on "background" must occur BEFORE the |
77 | 64 | % function call on "planet3D", otherwise the background will be |
78 | 65 | % plotted over the celestial body. |
| 66 | +% --> If you want to produce separate plots on separate figures using the |
| 67 | +% "planet3D" function, always use the "drawnow" command before |
| 68 | +% initializing a new figure to ensure that the correct plots are |
| 69 | +% drawn on the correct figures. |
79 | 70 | % |
80 | 71 | %========================================================================== |
81 | 72 | function planet_surface = planet3D(planet,opts) |
|
91 | 82 | 'm' 1; |
92 | 83 | 'mi' 100/160934.4; |
93 | 84 | 'nmi' 1/1852}; |
94 | | - |
| 85 | + |
95 | 86 | % planet/body radius, flattening, obliquity, |
96 | 87 | % R [m] f [-] obl [deg] |
97 | 88 | data = {'Sun' 696000e3 0.000009 0; |
|
114 | 105 | % Sets (or defaults) plotting options. |
115 | 106 | % ------------------------------------ |
116 | 107 |
|
| 108 | + % defaults "planet" to 'Earth Cloudy' if not input |
| 109 | + if (nargin == 0) || isempty(planet) |
| 110 | + planet = 'Earth Cloudy'; |
| 111 | + end |
| 112 | + |
117 | 113 | % sets position of planet's geometric center (defaults to origin) |
118 | | - if (nargin == 1) || ~isfield(opts,'Position') |
| 114 | + if (nargin < 2) || ~isfield(opts,'Position') |
119 | 115 | position = [0;0;0]; |
120 | 116 | else |
121 | 117 | position = opts.Position; |
122 | 118 | end |
123 | 119 |
|
124 | 120 | % sets rotation angle (defaults to 0) |
125 | | - if (nargin == 1) || ~isfield(opts,'RotAngle') |
| 121 | + if (nargin < 2) || ~isfield(opts,'RotAngle') |
126 | 122 | theta = 0; |
127 | 123 | else |
128 | 124 | theta = opts.RotAngle; |
129 | 125 | end |
130 | 126 |
|
131 | 127 | % sets conversion factor (defaults to 1, assuming units of m) |
132 | | - if (nargin == 1) || ~isfield(opts,'Units') |
| 128 | + if (nargin < 2) || ~isfield(opts,'Units') |
133 | 129 | units = 'm'; |
134 | 130 | else |
135 | 131 | units = opts.Units; |
136 | 132 | end |
137 | 133 |
|
138 | 134 | % sets reference plane (defaults to equatorial plane) |
139 | | - if (nargin == 1) || ~isfield(opts,'RefPlane') |
| 135 | + if (nargin < 2) || ~isfield(opts,'RefPlane') |
140 | 136 | reference_plane = 'equatorial'; |
141 | 137 | else |
142 | 138 | reference_plane = opts.RefPlane; |
143 | 139 | end |
144 | 140 |
|
145 | 141 | % sets transparency (defaults to 1 so celestial body is solid) |
146 | | - if (nargin == 1) || ~isfield(opts,'FaceAlpha') |
| 142 | + if (nargin < 2) || ~isfield(opts,'FaceAlpha') |
147 | 143 | FaceAlpha = 1; |
148 | 144 | else |
149 | 145 | FaceAlpha = opts.FaceAlpha; |
|
157 | 153 | end |
158 | 154 |
|
159 | 155 | % sets clipping (defaults to 'off') |
160 | | - if (nargin == 1) || ~isfield(opts,'Clipping') |
| 156 | + if (nargin < 2) || ~isfield(opts,'Clipping') |
161 | 157 | Clipping = 'off'; |
162 | 158 | else |
163 | 159 | Clipping = opts.Clipping; |
164 | 160 | end |
165 | 161 |
|
166 | 162 | % sets line color (defaults to default MATLAB color) |
167 | | - if (nargin == 1) || ~isfield(opts,'Color') |
| 163 | + if (nargin < 2) || ~isfield(opts,'Color') |
168 | 164 | Color = [0,0.4470,0.7410]; |
169 | 165 | else |
170 | 166 | Color = opts.Color; |
171 | 167 | end |
172 | | - |
| 168 | + |
173 | 169 | % sets line style (defaults to solid line) |
174 | | - if (nargin == 1) || ~isfield(opts,'LineStyle') |
| 170 | + if (nargin < 2) || ~isfield(opts,'LineStyle') |
175 | 171 | LineStyle = '-'; |
176 | 172 | else |
177 | 173 | LineStyle = opts.LineStyle; |
178 | 174 | end |
179 | 175 |
|
180 | 176 | % sets line width (defaults to 0.5) |
181 | | - if (nargin == 1) || ~isfield(opts,'LineWidth') |
| 177 | + if (nargin < 2) || ~isfield(opts,'LineWidth') |
182 | 178 | LineWidth = 0.5; |
183 | 179 | else |
184 | 180 | LineWidth = opts.LineWidth; |
|
217 | 213 | else |
218 | 214 | cdata = imread(strcat('',lower(planet),'.png')); |
219 | 215 | end |
220 | | - |
| 216 | + |
221 | 217 | % draws planet |
222 | 218 | planet_surface = surface(x,y,z,'FaceColor','texture',... |
223 | 219 | 'EdgeColor','none','CData',flipud(cdata),'DiffuseStrength',... |
224 | 220 | 1,'SpecularStrength',0,'FaceAlpha',FaceAlpha); |
225 | | - |
| 221 | + |
226 | 222 | end |
227 | 223 |
|
228 | 224 | % drawing Earth coastlines |
|
251 | 247 | R3 = [ cosd(theta) sind(theta) 0; |
252 | 248 | -sind(theta) cosd(theta) 0; |
253 | 249 | 0 0 1]; |
254 | | - |
| 250 | + |
255 | 251 | % transformation matrix for tilt |
256 | 252 | R1 = [1 0 0; |
257 | 253 | 0 cosd(obl) -sind(obl); |
258 | 254 | 0 sind(obl) cosd(obl)]; |
259 | | - |
| 255 | + |
260 | 256 | % axes for rotations (must be row vectors) |
261 | 257 | alpha1 = [1,0,0]; |
262 | 258 | alpha2 = (R1*[0;0;1])'; |
263 | 259 |
|
264 | 260 | % tilts celestial body if referenced to ecliptic plane |
265 | 261 | rotate(planet_surface,alpha1,obl); |
266 | | - |
| 262 | + |
267 | 263 | % rotates celestial body about its 3rd axis |
268 | 264 | rotate(planet_surface,alpha2,theta); |
269 | 265 |
|
|
0 commit comments