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, 9 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

# User Rev Content
1 greg 2.9 /* Copyright (c) 1992 Regents of the University of California */
2 greg 1.1
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 greg 1.6 #include "color.h"
21 greg 1.1
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 greg 2.3 int month, day; /* date */
36 greg 2.5 double hour; /* time */
37     int tsolar; /* 0=standard, 1=solar */
38 greg 2.3 double altitude, azimuth; /* or solar angles */
39 greg 1.1 /* default values */
40 greg 2.4 int cloudy = 0; /* 1=standard, 2=uniform */
41 greg 1.1 int dosun = 1;
42 greg 2.12 double zenithbr = 0.0;
43     int u_zenith = 0; /* -1=irradiance, 1=radiance */
44 greg 1.1 double turbidity = 2.75;
45     double gprefl = 0.2;
46     /* computed values */
47     double sundir[3];
48     double groundbr;
49     double F2;
50 greg 2.12 double solarbr = 0.0;
51     int u_solar = 0; /* -1=irradiance, 1=radiance */
52 greg 1.1
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 greg 2.3 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 greg 2.6 if (month < 1 || month > 12)
77     userror("bad month");
78 greg 2.3 day = atoi(argv[2]);
79 greg 2.6 if (day < 1 || day > 31)
80     userror("bad day");
81 greg 2.3 hour = atof(argv[3]);
82 greg 2.6 if (hour < 0 || hour >= 24)
83     userror("bad hour");
84 greg 2.5 tsolar = argv[3][0] == '+';
85 greg 2.3 }
86 greg 1.1 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 greg 2.8 case 'r':
94 greg 2.12 case 'R':
95     u_solar = argv[i][1]=='R' ? -1 : 1;
96 greg 2.8 solarbr = atof(argv[++i]);
97     break;
98 greg 1.1 case 'c':
99 greg 2.4 cloudy = argv[i][0] == '+' ? 2 : 1;
100 greg 1.1 dosun = 0;
101     break;
102     case 't':
103     turbidity = atof(argv[++i]);
104     break;
105     case 'b':
106 greg 2.12 case 'B':
107     u_zenith = argv[i][1]=='B' ? -1 : 1;
108 greg 1.1 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 greg 1.5
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 greg 1.1
134     printhead(argc, argv);
135    
136     computesky();
137     printsky();
138     }
139    
140    
141     computesky() /* compute sky parameters */
142     {
143 greg 2.12 double normfactor;
144 greg 1.1 /* compute solar direction */
145 greg 2.3 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 greg 2.5 if (tsolar) /* solar time */
152     st = hour;
153     else
154     st = hour + stadj(jd);
155 greg 2.3 altitude = salt(sd, st);
156     azimuth = sazi(sd, st);
157 greg 2.11 printf("# Solar altitude and azimuth: %f %f\n",
158     180./PI*altitude, 180./PI*azimuth);
159 greg 2.9 }
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 greg 2.3 }
168 greg 1.1 sundir[0] = -sin(azimuth)*cos(altitude);
169     sundir[1] = -cos(azimuth)*cos(altitude);
170     sundir[2] = sin(altitude);
171    
172 greg 2.12 /* 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 greg 1.1 /* Compute zenith brightness */
183 greg 2.12 if (u_zenith == -1)
184     zenithbr /= normfactor*PI;
185     else if (u_zenith == 0) {
186     if (cloudy)
187 greg 1.1 zenithbr = 8.6*sundir[2] + .123;
188 greg 2.12 else
189 greg 1.1 zenithbr = (1.376*turbidity-1.81)*tan(altitude)+0.38;
190 greg 2.12 if (zenithbr < 0.0)
191     zenithbr = 0.0;
192     else
193 greg 1.6 zenithbr *= 1000.0/SKYEFFICACY;
194 greg 2.12 }
195 greg 1.1 /* Compute horizontal radiance */
196 greg 2.12 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 greg 1.1 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 greg 1.6 printf("3 %.2e %.2e %.2e\n", solarbr, solarbr, solarbr);
217 greg 1.1 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 greg 2.4 printf("3 %d %.2e %.2e\n", cloudy, zenithbr, groundbr);
227 greg 1.1 else
228 greg 1.6 printf("7 -1 %.2e %.2e %.2e %f %f %f\n", zenithbr, groundbr,
229     F2, sundir[0], sundir[1], sundir[2]);
230 greg 1.1 }
231    
232    
233     printdefaults() /* print default values */
234     {
235 greg 2.4 if (cloudy == 1)
236 greg 1.1 printf("-c\t\t\t\t# Cloudy sky\n");
237 greg 2.4 else if (cloudy == 2)
238     printf("+c\t\t\t\t# Uniform cloudy sky\n");
239 greg 1.1 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 greg 2.3 fprintf(stderr, " Or: %s -ang altitude azimuth [options]\n", progname);
261 greg 1.1 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     }