9
#include "libplanet/Planet.h"
11
Ring::Ring(const double inner_radius, const double outer_radius,
12
const double planet_radius,
13
const double *ring_brightness, const int num_bright,
14
const double *ring_transparency, const int num_trans,
15
const double sunlon, const double sunlat,
17
Planet *p) : planet_(p), shade_(shade)
19
r_out = outer_radius/planet_radius;
20
dr_b = (outer_radius - inner_radius) / (num_bright * planet_radius);
21
dr_t = (outer_radius - inner_radius) / (num_trans * planet_radius);
23
const int innerPadding = 100;
24
const int outerPadding = 20;
25
num_b = outerPadding + num_bright + innerPadding;
26
num_t = outerPadding + num_trans + innerPadding;
28
// brightness and transparency arrays are from the outside in
29
radius_b = new double[num_b];
30
for (int i = 0; i < num_b; i++)
31
radius_b[i] = r_out - i * dr_b;
33
brightness = new double[num_b];
34
// drop the brightness to 0 at the outer radius
35
for (int i = 0; i < outerPadding; i++)
37
double weight = ((double) i) / (outerPadding - 1);
38
brightness[i] = weight * ring_brightness[0];
41
for (int i = 0; i < num_bright; i++)
42
brightness[i + outerPadding] = ring_brightness[i];
44
for (int i = 0; i < innerPadding; i++)
45
brightness[outerPadding + num_bright + i] = ring_brightness[num_bright-1];
47
const double cos_sun_lat = cos(sunlat);
48
for (int i = 0; i < num_b; i++)
49
brightness[i] *= cos_sun_lat;
51
radius_t = new double[num_t];
52
for (int i = 0; i < num_t; i++)
53
radius_t[i] = r_out - i * dr_t;
55
transparency = new double[num_t];
56
// bring the transparency up to 1 at the outer radius
57
for (int i = 0; i < outerPadding; i++)
59
double weight = ((double) i) / (outerPadding - 1);
60
transparency[i] = (1 - (1 - ring_transparency[0]) * weight);
63
for (int i = 0; i < num_trans; i++)
64
transparency[i + outerPadding] = ring_transparency[i];
66
// bring the transparency up to 1 at the inner radius
67
for (int i = 0; i < innerPadding; i++)
69
double weight = 1 - ((double) i) / (innerPadding - 1);
70
transparency[outerPadding + num_trans + i] = (1 - (1-ring_transparency[num_trans-1])
74
planet_->XYZToPlanetaryXYZ(0, 0, 0, sunX_, sunY_, sunZ_);
79
ellipseCoeffC_ = sunZ_ / (1 - planet_->Flattening());
80
ellipseCoeffC_ *= ellipseCoeffC_;
81
ellipseCoeffC_ += sunY_ * sunY_;
82
ellipseCoeffC_ += sunX_ * sunX_;
92
delete [] transparency;
96
Given a subsolar point and a location on the planet surface, check
97
if the surface location can be in shadow by the rings, and if so,
98
return the ring radius.
101
Ring::getShadowRadius(double lat, double lon)
103
// If this point is on the same side of the rings as the sun,
104
// there's no shadow.
105
if(sun_lat * lat >= 0) return(-1);
107
const double rad = planet_->Radius(lat);
108
planet_->PlanetographicToPlanetocentric(lat, lon);
110
const double x = rad * cos(lat) * cos(lon);
111
const double y = rad * cos(lat) * sin(lon);
112
const double z = rad * sin(lat);
114
const double dist = z/sunZ_;
116
const double dx = x - sunX_ * dist;
117
const double dy = y - sunY_ * dist;
119
return(sqrt(dx * dx + dy * dy));
123
Ring::getBrightness(const double lon, const double r)
125
return(getValue(brightness, num_b, window_b, dr_b, r, lon));
129
Ring::getBrightness(const double lon, const double r, const double t)
138
returnval = getValue(transparency, num_t, window_t, dr_t, r, lon);
144
Ring::getTransparency(const double r)
146
return(getValue(transparency, num_t, window_t, dr_t, r));
150
Ring::getValue(const double *array, const int size, const int window,
151
const double dr, const double r)
153
int i = (int) ((r_out - r)/dr);
155
if (i < 0 || i >= size) return(-1.0);
160
if (j2 >= size) j2 = size - 1;
163
for (int j = j1; j < j2; j++) sum += array[j];
170
Ring::getValue(const double *array, const int size, const int window,
171
const double dr, const double r, const double lon)
173
double cos_lon = cos(lon-sun_lon);
174
if (cos_lon > -0.45) return(getValue(array, size, window, dr, r));
176
int i = static_cast<int> ((r_out - r)/dr);
178
if (i < 0 || i >= size) return(-1.0);
182
const int interval = j2 - j1;
185
if (j2 >= size) j2 = size - 1;
189
for (int j = j1; j < j2; j++)
191
const double x = r0 * cos(-lon);
192
const double y = r0 * sin(-lon);
195
if (planet_->IsInMyShadow(x, y, z))
196
sum += (shade_ * array[j]);
207
// units for dist_per_pixel is planetary radii
209
Ring::setDistPerPixel(const double dist_per_pixel)
211
window_b = static_cast<int> (dist_per_pixel / dr_b + 0.5);
212
window_t = static_cast<int> (dist_per_pixel / dr_t + 0.5);
214
window_b = window_b/2 + 1;
215
window_t = window_t/2 + 1;