ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/gensky.c
(Generate patch)

Comparing ray/src/gen/gensky.c (file contents):
Revision 1.6 by greg, Thu Oct 24 13:43:22 1991 UTC vs.
Revision 2.16 by greg, Tue Jun 25 20:48:17 1996 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1986 Regents of the University of California */
1 > /* Copyright (c) 1992 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# Line 26 | Line 26 | extern double  stadj(), sdec(), sazi(), salt();
26  
27   #define  DOT(v1,v2)     (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])
28  
29 + #define  S_CLEAR        1
30 + #define  S_OVER         2
31 + #define  S_UNIF         3
32 + #define  S_INTER        4
33 +
34 + #define  overcast       (skytype==S_OVER|skytype==S_UNIF)
35 +
36   double  normsc();
37                                          /* sun calculation constants */
38   extern double  s_latitude;
39   extern double  s_longitude;
40   extern double  s_meridian;
41                                          /* required values */
42 < int  month, day;
43 < double  hour;
42 > int  month, day;                                /* date */
43 > double  hour;                                   /* time */
44 > int  tsolar;                                    /* 0=standard, 1=solar */
45 > double  altitude, azimuth;                      /* or solar angles */
46                                          /* default values */
47 < int  cloudy = 0;
47 > int  skytype = S_CLEAR;                         /* sky type */
48   int  dosun = 1;
49 < double  zenithbr = -1.0;
49 > double  zenithbr = 0.0;
50 > int     u_zenith = 0;                           /* -1=irradiance, 1=radiance */
51   double  turbidity = 2.75;
52   double  gprefl = 0.2;
53                                          /* computed values */
54   double  sundir[3];
55   double  groundbr;
56   double  F2;
57 < double  solarbr;
57 > double  solarbr = 0.0;
58 > int     u_solar = 0;                            /* -1=irradiance, 1=radiance */
59  
60   char  *progname;
61   char  errmsg[128];
# Line 54 | Line 65 | main(argc, argv)
65   int  argc;
66   char  *argv[];
67   {
57        extern double  atof(), fabs();
68          int  i;
69  
70          progname = argv[0];
# Line 64 | Line 74 | char  *argv[];
74          }
75          if (argc < 4)
76                  userror("arg count");
77 <        month = atoi(argv[1]);
78 <        day = atoi(argv[2]);
79 <        hour = atof(argv[3]);
77 >        if (!strcmp(argv[1], "-ang")) {
78 >                altitude = atof(argv[2]) * (PI/180);
79 >                azimuth = atof(argv[3]) * (PI/180);
80 >                month = 0;
81 >        } else {
82 >                month = atoi(argv[1]);
83 >                if (month < 1 || month > 12)
84 >                        userror("bad month");
85 >                day = atoi(argv[2]);
86 >                if (day < 1 || day > 31)
87 >                        userror("bad day");
88 >                cvthour(argv[3]);
89 >        }
90          for (i = 4; i < argc; i++)
91                  if (argv[i][0] == '-' || argv[i][0] == '+')
92                          switch (argv[i][1]) {
93                          case 's':
94 <                                cloudy = 0;
94 >                                skytype = S_CLEAR;
95                                  dosun = argv[i][0] == '+';
96                                  break;
97 +                        case 'r':
98 +                        case 'R':
99 +                                u_solar = argv[i][1]=='R' ? -1 : 1;
100 +                                solarbr = atof(argv[++i]);
101 +                                break;
102                          case 'c':
103 <                                cloudy = 1;
79 <                                dosun = 0;
103 >                                skytype = S_OVER;
104                                  break;
105 +                        case 'u':
106 +                                skytype = S_UNIF;
107 +                                break;
108 +                        case 'i':
109 +                                skytype = S_INTER;
110 +                                dosun = argv[i][0] == '+';
111 +                                break;
112                          case 't':
113                                  turbidity = atof(argv[++i]);
114                                  break;
115                          case 'b':
116 +                        case 'B':
117 +                                u_zenith = argv[i][1]=='B' ? -1 : 1;
118                                  zenithbr = atof(argv[++i]);
119                                  break;
120                          case 'g':
# Line 112 | Line 145 | char  *argv[];
145  
146          computesky();
147          printsky();
148 +
149 +        exit(0);
150   }
151  
152  
153   computesky()                    /* compute sky parameters */
154   {
155 <        int  jd;
121 <        double  sd, st;
122 <        double  altitude, azimuth;
155 >        double  normfactor;
156                                          /* compute solar direction */
157 <        jd = jdate(month, day);                 /* Julian date */
158 <        sd = sdec(jd);                          /* solar declination */
159 <        st = hour + stadj(jd);                  /* solar time */
160 <        altitude = salt(sd, st);
161 <        azimuth = sazi(sd, st);
157 >        if (month) {                    /* from date and time */
158 >                int  jd;
159 >                double  sd, st;
160 >
161 >                jd = jdate(month, day);         /* Julian date */
162 >                sd = sdec(jd);                  /* solar declination */
163 >                if (tsolar)                     /* solar time */
164 >                        st = hour;
165 >                else
166 >                        st = hour + stadj(jd);
167 >                altitude = salt(sd, st);
168 >                azimuth = sazi(sd, st);
169 >                printf("# Solar altitude and azimuth: %.1f %.1f\n",
170 >                                180./PI*altitude, 180./PI*azimuth);
171 >        }
172 >        if (!overcast && altitude > 87.*PI/180.) {
173 >                fprintf(stderr,
174 > "%s: warning - sun too close to zenith, reducing altitude to 87 degrees\n",
175 >                                progname);
176 >                printf(
177 > "# warning - sun too close to zenith, reducing altitude to 87 degrees\n");
178 >                altitude = 87.*PI/180.;
179 >        }
180          sundir[0] = -sin(azimuth)*cos(altitude);
181          sundir[1] = -cos(azimuth)*cos(altitude);
182          sundir[2] = sin(altitude);
183  
184 +                                        /* Compute normalization factor */
185 +        switch (skytype) {
186 +        case S_UNIF:
187 +                normfactor = 1.0;
188 +                break;
189 +        case S_OVER:
190 +                normfactor = 0.777778;
191 +                break;
192 +        case S_CLEAR:
193 +                F2 = 0.274*(0.91 + 10.0*exp(-3.0*(PI/2.0-altitude)) +
194 +                                0.45*sundir[2]*sundir[2]);
195 +                normfactor = normsc()/F2/PI;
196 +                break;
197 +        case S_INTER:
198 +                F2 = (2.739 + .9891*sin(.3119+2.6*altitude)) *
199 +                        exp(-(PI/2.0-altitude)*(.4441+1.48*altitude));
200 +                normfactor = normsc()/F2/PI;
201 +                break;
202 +        }
203                                          /* Compute zenith brightness */
204 <        if (zenithbr <= 0.0)
205 <                if (cloudy) {
204 >        if (u_zenith == -1)
205 >                zenithbr /= normfactor*PI;
206 >        else if (u_zenith == 0) {
207 >                if (overcast)
208                          zenithbr = 8.6*sundir[2] + .123;
209 <                        zenithbr *= 1000.0/SKYEFFICACY;
138 <                } else {
209 >                else
210                          zenithbr = (1.376*turbidity-1.81)*tan(altitude)+0.38;
211 +                if (skytype == S_INTER)
212 +                        zenithbr = (zenithbr + 8.6*sundir[2] + .123)/2.0;
213 +                if (zenithbr < 0.0)
214 +                        zenithbr = 0.0;
215 +                else
216                          zenithbr *= 1000.0/SKYEFFICACY;
141                }
142        if (zenithbr < 0.0)
143                zenithbr = 0.0;
144                                        /* Compute horizontal radiance */
145        if (cloudy) {
146                groundbr = zenithbr*0.777778;
147                printf("# Ground ambient level: %f\n", groundbr);
148        } else {
149                F2 = 0.274*(0.91 + 10.0*exp(-3.0*(PI/2.0-altitude)) +
150                                0.45*sundir[2]*sundir[2]);
151                groundbr = zenithbr*normsc(PI/2.0-altitude)/F2/PI;
152                printf("# Ground ambient level: %f\n", groundbr);
153                if (sundir[2] > 0.0) {
154                        if (sundir[2] > .16)
155                                solarbr = (1.5e9/SUNEFFICACY) *
156                                        (1.147 - .147/sundir[2]);
157                        else
158                                solarbr = 1.5e9/SUNEFFICACY*(1.147-.147/.16);
159                        groundbr += solarbr*6e-5*sundir[2]/PI;
160                } else
161                        dosun = 0;
217          }
218 +                                        /* Compute horizontal radiance */
219 +        groundbr = zenithbr*normfactor;
220 +        printf("# Ground ambient level: %.1f\n", groundbr);
221 +        if (!overcast && sundir[2] > 0.0 && (!u_solar || solarbr > 0.0)) {
222 +                if (u_solar == -1)
223 +                        solarbr /= 6e-5*sundir[2];
224 +                else if (u_solar == 0) {
225 +                        solarbr = 1.5e9/SUNEFFICACY *
226 +                        (1.147 - .147/(sundir[2]>.16?sundir[2]:.16));
227 +                        if (skytype == S_INTER)
228 +                                solarbr *= 0.15;        /* fudge factor! */
229 +                }
230 +                groundbr += 6e-5/PI*solarbr*sundir[2];
231 +        } else
232 +                dosun = 0;
233          groundbr *= gprefl;
234   }
235  
# Line 176 | Line 246 | printsky()                     /* print out sky */
246          }
247          
248          printf("\nvoid brightfunc skyfunc\n");
249 <        printf("2 skybright skybright.cal\n");
249 >        printf("2 skybr skybright.cal\n");
250          printf("0\n");
251 <        if (cloudy)
252 <                printf("3 1 %.2e %.2e\n", zenithbr, groundbr);
251 >        if (overcast)
252 >                printf("3 %d %.2e %.2e\n", skytype, zenithbr, groundbr);
253          else
254 <                printf("7 -1 %.2e %.2e %.2e %f %f %f\n", zenithbr, groundbr,
255 <                                F2, sundir[0], sundir[1], sundir[2]);
254 >                printf("7 %d %.2e %.2e %.2e %f %f %f\n",
255 >                                skytype, zenithbr, groundbr, F2,
256 >                                sundir[0], sundir[1], sundir[2]);
257   }
258  
259  
260   printdefaults()                 /* print default values */
261   {
262 <        if (cloudy)
262 >        switch (skytype) {
263 >        case S_OVER:
264                  printf("-c\t\t\t\t# Cloudy sky\n");
265 <        else if (dosun)
266 <                printf("+s\t\t\t\t# Sunny sky with sun\n");
267 <        else
268 <                printf("-s\t\t\t\t# Sunny sky without sun\n");
265 >                break;
266 >        case S_UNIF:
267 >                printf("-u\t\t\t\t# Uniform cloudy sky\n");
268 >                break;
269 >        case S_INTER:
270 >                if (dosun)
271 >                        printf("+i\t\t\t\t# Intermediate sky with sun\n");
272 >                else
273 >                        printf("-i\t\t\t\t# Intermediate sky without sun\n");
274 >                break;
275 >        case S_CLEAR:
276 >                if (dosun)
277 >                        printf("+s\t\t\t\t# Sunny sky with sun\n");
278 >                else
279 >                        printf("-s\t\t\t\t# Sunny sky without sun\n");
280 >                break;
281 >        }
282          printf("-g %f\t\t\t# Ground plane reflectance\n", gprefl);
283          if (zenithbr > 0.0)
284                  printf("-b %f\t\t\t# Zenith radiance (watts/ster/m2\n", zenithbr);
# Line 211 | Line 296 | char  *msg;
296          if (msg != NULL)
297                  fprintf(stderr, "%s: Use error - %s\n", progname, msg);
298          fprintf(stderr, "Usage: %s month day hour [options]\n", progname);
299 +        fprintf(stderr, "   Or: %s -ang altitude azimuth [options]\n", progname);
300          fprintf(stderr, "   Or: %s -defaults\n", progname);
301          exit(1);
302   }
303  
304  
305   double
306 < normsc(theta)                   /* compute normalization factor (E0*F2/L0) */
221 < double  theta;
306 > normsc()                        /* compute normalization factor (E0*F2/L0) */
307   {
308 <        static double  nf[5] = {2.766521, 0.547665,
309 <                                -0.369832, 0.009237, 0.059229};
308 >        static double  nfc[2][5] = {
309 >                                /* clear sky approx. */
310 >                {2.766521, 0.547665, -0.369832, 0.009237, 0.059229},
311 >                                /* intermediate sky approx. */
312 >                {3.5556, -2.7152, -1.3081, 1.0660, 0.60227},
313 >        };
314 >        register double  *nf;
315          double  x, nsc;
316          register int  i;
317                                          /* polynomial approximation */
318 <        x = (theta - PI/4.0)/(PI/4.0);
319 <        nsc = nf[4];
320 <        for (i = 3; i >= 0; i--)
318 >        nf = nfc[skytype==S_INTER];
319 >        x = (altitude - PI/4.0)/(PI/4.0);
320 >        nsc = nf[i=4];
321 >        while (i--)
322                  nsc = nsc*x + nf[i];
323  
324          return(nsc);
325 + }
326 +
327 +
328 + cvthour(hs)                     /* convert hour string */
329 + char  *hs;
330 + {
331 +        register char  *cp = hs;
332 +
333 +        while (*cp && *cp++ != ':')
334 +                ;
335 +        if (*cp)
336 +                hour = atoi(hs) + atoi(cp)/60.0;
337 +        else
338 +                hour = atof(hs);
339 +        tsolar = *hs == '+';
340   }
341  
342  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines