ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/gensky.c
Revision: 2.12
Committed: Mon Jun 14 13:54:26 1993 UTC (30 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.11: +39 -28 lines
Log Message:
added -B option for global irradiance and -R for solar irradiance

File Contents

# Content
1 /* Copyright (c) 1992 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * gensky.c - program to generate sky functions.
9 * Our zenith is along the Z-axis, the X-axis
10 * points east, and the Y-axis points north.
11 * Radiance is in watts/steradian/sq. meter.
12 *
13 * 3/26/86
14 */
15
16 #include <stdio.h>
17
18 #include <math.h>
19
20 #include "color.h"
21
22 extern char *strcpy(), *strcat(), *malloc();
23 extern double stadj(), sdec(), sazi(), salt();
24
25 #define PI 3.141592654
26
27 #define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])
28
29 double normsc();
30 /* sun calculation constants */
31 extern double s_latitude;
32 extern double s_longitude;
33 extern double s_meridian;
34 /* required values */
35 int month, day; /* date */
36 double hour; /* time */
37 int tsolar; /* 0=standard, 1=solar */
38 double altitude, azimuth; /* or solar angles */
39 /* default values */
40 int cloudy = 0; /* 1=standard, 2=uniform */
41 int dosun = 1;
42 double zenithbr = 0.0;
43 int u_zenith = 0; /* -1=irradiance, 1=radiance */
44 double turbidity = 2.75;
45 double gprefl = 0.2;
46 /* computed values */
47 double sundir[3];
48 double groundbr;
49 double F2;
50 double solarbr = 0.0;
51 int u_solar = 0; /* -1=irradiance, 1=radiance */
52
53 char *progname;
54 char errmsg[128];
55
56
57 main(argc, argv)
58 int argc;
59 char *argv[];
60 {
61 int i;
62
63 progname = argv[0];
64 if (argc == 2 && !strcmp(argv[1], "-defaults")) {
65 printdefaults();
66 exit(0);
67 }
68 if (argc < 4)
69 userror("arg count");
70 if (!strcmp(argv[1], "-ang")) {
71 altitude = atof(argv[2]) * (PI/180);
72 azimuth = atof(argv[3]) * (PI/180);
73 month = 0;
74 } else {
75 month = atoi(argv[1]);
76 if (month < 1 || month > 12)
77 userror("bad month");
78 day = atoi(argv[2]);
79 if (day < 1 || day > 31)
80 userror("bad day");
81 hour = atof(argv[3]);
82 if (hour < 0 || hour >= 24)
83 userror("bad hour");
84 tsolar = argv[3][0] == '+';
85 }
86 for (i = 4; i < argc; i++)
87 if (argv[i][0] == '-' || argv[i][0] == '+')
88 switch (argv[i][1]) {
89 case 's':
90 cloudy = 0;
91 dosun = argv[i][0] == '+';
92 break;
93 case 'r':
94 case 'R':
95 u_solar = argv[i][1]=='R' ? -1 : 1;
96 solarbr = atof(argv[++i]);
97 break;
98 case 'c':
99 cloudy = argv[i][0] == '+' ? 2 : 1;
100 dosun = 0;
101 break;
102 case 't':
103 turbidity = atof(argv[++i]);
104 break;
105 case 'b':
106 case 'B':
107 u_zenith = argv[i][1]=='B' ? -1 : 1;
108 zenithbr = atof(argv[++i]);
109 break;
110 case 'g':
111 gprefl = atof(argv[++i]);
112 break;
113 case 'a':
114 s_latitude = atof(argv[++i]) * (PI/180);
115 break;
116 case 'o':
117 s_longitude = atof(argv[++i]) * (PI/180);
118 break;
119 case 'm':
120 s_meridian = atof(argv[++i]) * (PI/180);
121 break;
122 default:
123 sprintf(errmsg, "unknown option: %s", argv[i]);
124 userror(errmsg);
125 }
126 else
127 userror("bad option");
128
129 if (fabs(s_meridian-s_longitude) > 30*PI/180)
130 fprintf(stderr,
131 "%s: warning: %.1f hours btwn. standard meridian and longitude\n",
132 progname, (s_longitude-s_meridian)*12/PI);
133
134 printhead(argc, argv);
135
136 computesky();
137 printsky();
138 }
139
140
141 computesky() /* compute sky parameters */
142 {
143 double normfactor;
144 /* compute solar direction */
145 if (month) { /* from date and time */
146 int jd;
147 double sd, st;
148
149 jd = jdate(month, day); /* Julian date */
150 sd = sdec(jd); /* solar declination */
151 if (tsolar) /* solar time */
152 st = hour;
153 else
154 st = hour + stadj(jd);
155 altitude = salt(sd, st);
156 azimuth = sazi(sd, st);
157 printf("# Solar altitude and azimuth: %f %f\n",
158 180./PI*altitude, 180./PI*azimuth);
159 }
160 if (!cloudy && altitude > 87.*PI/180.) {
161 fprintf(stderr,
162 "%s: warning - sun too close to zenith, reducing altitude to 87 degrees\n",
163 progname);
164 printf(
165 "# warning - sun too close to zenith, reducing altitude to 87 degrees\n");
166 altitude = 87.*PI/180.;
167 }
168 sundir[0] = -sin(azimuth)*cos(altitude);
169 sundir[1] = -cos(azimuth)*cos(altitude);
170 sundir[2] = sin(altitude);
171
172 /* Compute normalization factor */
173 if (cloudy == 2)
174 normfactor = 1.0;
175 else if (cloudy == 1)
176 normfactor = 0.777778;
177 else {
178 F2 = 0.274*(0.91 + 10.0*exp(-3.0*(PI/2.0-altitude)) +
179 0.45*sundir[2]*sundir[2]);
180 normfactor = normsc(altitude)/F2/PI;
181 }
182 /* Compute zenith brightness */
183 if (u_zenith == -1)
184 zenithbr /= normfactor*PI;
185 else if (u_zenith == 0) {
186 if (cloudy)
187 zenithbr = 8.6*sundir[2] + .123;
188 else
189 zenithbr = (1.376*turbidity-1.81)*tan(altitude)+0.38;
190 if (zenithbr < 0.0)
191 zenithbr = 0.0;
192 else
193 zenithbr *= 1000.0/SKYEFFICACY;
194 }
195 /* Compute horizontal radiance */
196 groundbr = zenithbr*normfactor;
197 printf("# Ground ambient level: %f\n", groundbr);
198 if (sundir[2] > 0.0 && (!u_solar || solarbr > 0.0)) {
199 if (u_solar == -1)
200 solarbr /= 6e-5*sundir[2];
201 else if (u_solar == 0)
202 solarbr = 1.5e9/SUNEFFICACY *
203 (1.147 - .147/(sundir[2]>.16?sundir[2]:.16));
204 groundbr += 6e-5/PI*solarbr*sundir[2];
205 } else
206 dosun = 0;
207 groundbr *= gprefl;
208 }
209
210
211 printsky() /* print out sky */
212 {
213 if (dosun) {
214 printf("\nvoid light solar\n");
215 printf("0\n0\n");
216 printf("3 %.2e %.2e %.2e\n", solarbr, solarbr, solarbr);
217 printf("\nsolar source sun\n");
218 printf("0\n0\n");
219 printf("4 %f %f %f 0.5\n", sundir[0], sundir[1], sundir[2]);
220 }
221
222 printf("\nvoid brightfunc skyfunc\n");
223 printf("2 skybright skybright.cal\n");
224 printf("0\n");
225 if (cloudy)
226 printf("3 %d %.2e %.2e\n", cloudy, zenithbr, groundbr);
227 else
228 printf("7 -1 %.2e %.2e %.2e %f %f %f\n", zenithbr, groundbr,
229 F2, sundir[0], sundir[1], sundir[2]);
230 }
231
232
233 printdefaults() /* print default values */
234 {
235 if (cloudy == 1)
236 printf("-c\t\t\t\t# Cloudy sky\n");
237 else if (cloudy == 2)
238 printf("+c\t\t\t\t# Uniform cloudy sky\n");
239 else if (dosun)
240 printf("+s\t\t\t\t# Sunny sky with sun\n");
241 else
242 printf("-s\t\t\t\t# Sunny sky without sun\n");
243 printf("-g %f\t\t\t# Ground plane reflectance\n", gprefl);
244 if (zenithbr > 0.0)
245 printf("-b %f\t\t\t# Zenith radiance (watts/ster/m2\n", zenithbr);
246 else
247 printf("-t %f\t\t\t# Atmospheric turbidity\n", turbidity);
248 printf("-a %f\t\t\t# Site latitude (degrees)\n", s_latitude*(180/PI));
249 printf("-o %f\t\t\t# Site longitude (degrees)\n", s_longitude*(180/PI));
250 printf("-m %f\t\t\t# Standard meridian (degrees)\n", s_meridian*(180/PI));
251 }
252
253
254 userror(msg) /* print usage error and quit */
255 char *msg;
256 {
257 if (msg != NULL)
258 fprintf(stderr, "%s: Use error - %s\n", progname, msg);
259 fprintf(stderr, "Usage: %s month day hour [options]\n", progname);
260 fprintf(stderr, " Or: %s -ang altitude azimuth [options]\n", progname);
261 fprintf(stderr, " Or: %s -defaults\n", progname);
262 exit(1);
263 }
264
265
266 double
267 normsc(theta) /* compute normalization factor (E0*F2/L0) */
268 double theta;
269 {
270 static double nf[5] = {2.766521, 0.547665,
271 -0.369832, 0.009237, 0.059229};
272 double x, nsc;
273 register int i;
274 /* polynomial approximation */
275 x = (theta - PI/4.0)/(PI/4.0);
276 nsc = nf[4];
277 for (i = 3; i >= 0; i--)
278 nsc = nsc*x + nf[i];
279
280 return(nsc);
281 }
282
283
284 printhead(ac, av) /* print command header */
285 register int ac;
286 register char **av;
287 {
288 putchar('#');
289 while (ac--) {
290 putchar(' ');
291 fputs(*av++, stdout);
292 }
293 putchar('\n');
294 }