ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glarendx.c
Revision: 2.2
Committed: Tue Apr 28 09:11:00 1992 UTC (32 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +2 -2 lines
Log Message:
changed call to sscanview

File Contents

# Content
1 /* Copyright (c) 1991 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * Compute Glare Index given by program name or -t option:
9 *
10 * guth_dgr - Guth discomfort glare rating
11 * guth_vcp - Guth visual comfort probability
12 * cie_cgi - CIE Glare Index (1983, due to Einhorn)
13 * vert_dir - Direct vertical illuminance
14 * vert_ind - Indirect vertical illuminance (from input)
15 * vert_ill - Total vertical illuminance
16 *
17 * 12 April 1991 Greg Ward EPFL
18 */
19
20 #include "standard.h"
21 #include "view.h"
22
23 extern double erfc();
24
25 double posindex();
26
27 double direct(), guth_dgr(), guth_vcp(), cie_cgi(),
28 indirect(), total();
29
30 struct named_func {
31 char *name;
32 double (*func)();
33 char *descrip;
34 } all_funcs[] = {
35 {"guth_vcp", guth_vcp, "Guth Visual Comfort Probability"},
36 {"cie_cgi", cie_cgi, "CIE Glare Index (Einhorn)"},
37 {"guth_dgr", guth_dgr, "Guth Disability Glare Rating"},
38 {"vert_dir", direct, "Direct Vertical Illuminance"},
39 {"vert_ill", total, "Total Vertical Illuminance"},
40 {"vert_ind", indirect, "Indirect Vertical Illuminance"},
41 {NULL}
42 };
43
44 struct glare_src {
45 FVECT dir; /* source direction */
46 double dom; /* solid angle */
47 double lum; /* average luminance */
48 struct glare_src *next;
49 } *all_srcs = NULL;
50
51 struct glare_dir {
52 double ang; /* angle (in radians) */
53 double indirect; /* indirect illuminance */
54 struct glare_dir *next;
55 } *all_dirs = NULL;
56
57 #define newp(type) (type *)malloc(sizeof(type))
58
59 char *progname;
60 int print_header = 1;
61
62 VIEW midview = STDVIEW;
63
64 int wrongformat = 0;
65
66
67 main(argc, argv)
68 int argc;
69 char *argv[];
70 {
71 extern char *rindex();
72 struct named_func *funp;
73 char *progtail;
74 int i;
75 /* get program name */
76 progname = argv[0];
77 progtail = rindex(progname, '/'); /* final component */
78 if (progtail == NULL)
79 progtail = progname;
80 else
81 progtail++;
82 /* get options */
83 for (i = 1; i < argc && argv[i][0] == '-'; i++)
84 switch (argv[i][1]) {
85 case 't':
86 progtail = argv[++i];
87 break;
88 case 'h':
89 print_header = 0;
90 break;
91 default:
92 goto userr;
93 }
94 if (i < argc-1)
95 goto userr;
96 if (i == argc-1) /* open file */
97 if (freopen(argv[i], "r", stdin) == NULL) {
98 perror(argv[i]);
99 exit(1);
100 }
101 /* find and run calculation */
102 for (funp = all_funcs; funp->name != NULL; funp++)
103 if (!strcmp(funp->name, progtail)) {
104 init();
105 read_input();
106 if (print_header) {
107 printargs(i, argv, stdout);
108 putchar('\n');
109 }
110 print_values(funp->func);
111 exit(0); /* we're done */
112 }
113 /* invalid function */
114 userr:
115 fprintf(stderr, "Usage: %s -t type [-h] [input]\n", progname);
116 fprintf(stderr, "\twhere 'type' is one of the following:\n");
117 for (funp = all_funcs; funp->name != NULL; funp++)
118 fprintf(stderr, "\t%12s\t%s\n", funp->name, funp->descrip);
119 exit(1);
120 }
121
122
123 headline(s) /* get line from header */
124 char *s;
125 {
126 char fmt[32];
127
128 if (print_header) /* copy to output */
129 fputs(s, stdout);
130 if (isview(s))
131 sscanview(&midview, s);
132 else if (isformat(s)) {
133 formatval(fmt, s);
134 wrongformat = strcmp(fmt, "ascii");
135 }
136 }
137
138
139 init() /* initialize calculation */
140 {
141 /* read header */
142 getheader(stdin, headline, NULL);
143 if (wrongformat) {
144 fprintf(stderr, "%s: bad input format\n", progname);
145 exit(1);
146 }
147 /* set view */
148 if (setview(&midview) != NULL) {
149 fprintf(stderr, "%s: bad view information in input\n",
150 progname);
151 exit(1);
152 }
153 }
154
155
156 read_input() /* read glare sources from stdin */
157 {
158 #define S_SEARCH 0
159 #define S_SOURCE 1
160 #define S_DIREC 2
161 int state = S_SEARCH;
162 char buf[128];
163 register struct glare_src *gs;
164 register struct glare_dir *gd;
165
166 while (fgets(buf, sizeof(buf), stdin) != NULL)
167 switch (state) {
168 case S_SEARCH:
169 if (!strcmp(buf, "BEGIN glare source\n"))
170 state = S_SOURCE;
171 else if (!strcmp(buf, "BEGIN indirect illuminance\n"))
172 state = S_DIREC;
173 break;
174 case S_SOURCE:
175 if (!strncmp(buf, "END", 3)) {
176 state = S_SEARCH;
177 break;
178 }
179 if ((gs = newp(struct glare_src)) == NULL)
180 goto memerr;
181 if (sscanf(buf, "%lf %lf %lf %lf %lf",
182 &gs->dir[0], &gs->dir[1], &gs->dir[2],
183 &gs->dom, &gs->lum) != 5)
184 goto readerr;
185 normalize(gs->dir);
186 gs->next = all_srcs;
187 all_srcs = gs;
188 break;
189 case S_DIREC:
190 if (!strncmp(buf, "END", 3)) {
191 state = S_SEARCH;
192 break;
193 }
194 if ((gd = newp(struct glare_dir)) == NULL)
195 goto memerr;
196 if (sscanf(buf, "%lf %lf",
197 &gd->ang, &gd->indirect) != 2)
198 goto readerr;
199 gd->ang *= PI/180.0; /* convert to radians */
200 gd->next = all_dirs;
201 all_dirs = gd;
202 break;
203 }
204 return;
205 memerr:
206 perror(progname);
207 exit(1);
208 readerr:
209 fprintf(stderr, "%s: read error on input\n", progname);
210 exit(1);
211 #undef S_SEARCH
212 #undef S_SOURCE
213 #undef S_DIREC
214 }
215
216
217 print_values(funp) /* print out calculations */
218 double (*funp)();
219 {
220 register struct glare_dir *gd;
221
222 for (gd = all_dirs; gd != NULL; gd = gd->next)
223 printf("%f\t%f\n", gd->ang*(180.0/PI), (*funp)(gd));
224 }
225
226
227 double
228 direct(gd) /* compute direct vertical illuminance */
229 struct glare_dir *gd;
230 {
231 FVECT mydir;
232 double d, dval;
233 register struct glare_src *gs;
234
235 spinvector(mydir, midview.vdir, midview.vup, gd->ang);
236 dval = 0.0;
237 for (gs = all_srcs; gs != NULL; gs = gs->next) {
238 d = DOT(mydir,gs->dir);
239 if (d > FTINY)
240 dval += d * gs->dom * gs->lum;
241 }
242 return(dval);
243 }
244
245
246 double
247 indirect(gd) /* return indirect vertical illuminance */
248 struct glare_dir *gd;
249 {
250 return(gd->indirect);
251 }
252
253
254 double
255 total(gd) /* return total vertical illuminance */
256 struct glare_dir *gd;
257 {
258 return(direct(gd)+gd->indirect);
259 }
260
261
262 /*
263 * posindex - compute glare position index from:
264 *
265 * Source Direction
266 * View Direction
267 * View Up Direction
268 *
269 * All vectors are assumed to be normalized.
270 * This function is an implementation of the method proposed by
271 * Robert Levin in his 1975 JIES article.
272 * This calculation presumes the view direction and up vectors perpendicular.
273 * We return a value less than zero for improper positions.
274 */
275
276 double
277 posindex(sd, vd, vu) /* compute position index */
278 FVECT sd, vd, vu;
279 {
280 double sigma, tau;
281 double d;
282
283 d = DOT(sd,vd);
284 if (d <= 0.0)
285 return(-1.0);
286 if (d >= 1.0)
287 return(1.0);
288 sigma = acos(d) * (180./PI);
289 d = DOT(sd,vu)/sqrt(1.0-d*d);
290 if (d >= 1.0)
291 tau = 0.0;
292 else
293 tau = acos(d) * (180./PI);
294 return( exp( sigma*( (35.2 - tau*.31889 - 1.22*exp(-.22222*tau))*1e-3
295 + sigma*(21. + tau*(.26667 + tau*-.002963))*1e-5 )
296 ) );
297 }
298
299
300 double
301 guth_dgr(gd) /* compute Guth discomfort glare rating */
302 struct glare_dir *gd;
303 {
304 #define q(w) (20.4*w+1.52*pow(w,.2)-.075)
305 register struct glare_src *gs;
306 FVECT mydir;
307 double p;
308 double sum;
309 double wtot, brsum;
310 int n;
311
312 spinvector(mydir, midview.vdir, midview.vup, gd->ang);
313 sum = wtot = brsum = 0.0; n = 0;
314 for (gs = all_srcs; gs != NULL; gs = gs->next) {
315 p = posindex(gs->dir, mydir, midview.vup);
316 if (p <= FTINY)
317 continue;
318 sum += gs->lum * q(gs->dom) / p;
319 brsum += gs->lum * gs->dom;
320 wtot += gs->dom;
321 n++;
322 }
323 if (n == 0)
324 return(0.0);
325
326 return( pow(.5*sum/pow((brsum+(5.-wtot)*gd->indirect/PI)/5.,.44),
327 pow((double)n, -.0914) ) );
328 #undef q
329 }
330
331
332 extern double erf(), erfc();
333
334 #ifndef M_SQRT2
335 #define M_SQRT2 1.41421356237309504880
336 #endif
337
338 #define norm_integral(z) (1.-.5*erfc((z)/M_SQRT2))
339
340
341 double
342 guth_vcp(gd) /* compute Guth visual comfort probability */
343 struct glare_dir *gd;
344 {
345 double dgr;
346
347 dgr = guth_dgr(gd);
348 if (dgr <= FTINY)
349 return(100.0);
350 return(100.*norm_integral(6.374-1.3227*log(dgr)));
351 }
352
353
354 double
355 cie_cgi(gd) /* compute CIE Glare Index */
356 struct glare_dir *gd;
357 {
358 register struct glare_src *gs;
359 FVECT mydir;
360 double dillum;
361 double p;
362 double sum;
363
364 spinvector(mydir, midview.vdir, midview.vup, gd->ang);
365 sum = 0.0;
366 for (gs = all_srcs; gs != NULL; gs = gs->next) {
367 p = posindex(gs->dir, mydir, midview.vup);
368 if (p <= FTINY)
369 continue;
370 sum += gs->lum*gs->lum * gs->dom / (p*p);
371 }
372 if (sum <= FTINY)
373 return(0.0);
374 dillum = direct(gd);
375 return(8.*log10(2.*sum*(1.+dillum/500.)/(dillum+gd->indirect)));
376 }