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

Comparing ray/src/util/glarendx.c (file contents):
Revision 2.3 by greg, Thu Nov 19 09:59:08 1992 UTC vs.
Revision 2.10 by schorsch, Fri Jan 2 12:48:36 2004 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1991 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Compute Glare Index given by program name or -t option:
6   *
7 + *      dgi -           Daylight Glare Index
8 + *      brs_gi -        Building Research Station Glare Index (Petherbridge
9 + *                                                             & Hopkinson)
10 + *      ugr -           Unified Glare Rating System (Fischer)
11   *      guth_dgr -      Guth discomfort glare rating
12   *      guth_vcp -      Guth visual comfort probability
13   *      cie_cgi -       CIE Glare Index (1983, due to Einhorn)
# Line 15 | Line 16 | static char SCCSid[] = "$SunId$ LBL";
16   *      vert_ill -      Total vertical illuminance
17   *
18   *              12 April 1991   Greg Ward       EPFL
19 + *              19 April 1993   R. Compagnon    EPFL (added dgi, brs_gi, ugr)
20   */
21  
22 + #include <string.h>
23 +
24   #include "standard.h"
25   #include "view.h"
26  
23 extern double   erfc();
27  
28 < double  posindex();
28 > struct glare_src {
29 >        FVECT   dir;            /* source direction */
30 >        double  dom;            /* solid angle */
31 >        double  lum;            /* average luminance */
32 >        struct glare_src        *next;
33 > } *all_srcs = NULL;
34  
35 < double  direct(), guth_dgr(), guth_vcp(), cie_cgi(),
36 <        indirect(), total();
35 > struct glare_dir {
36 >        double  ang;            /* angle (in radians) */
37 >        double  indirect;       /* indirect illuminance */
38 >        struct glare_dir        *next;
39 > } *all_dirs = NULL;
40  
41 + typedef double gdfun(struct glare_dir *gd);
42 +
43 + static gdfun dgi;
44 + static gdfun brs_gi;
45 + static gdfun ugr;
46 + static gdfun guth_dgr;
47 + static gdfun guth_vcp;
48 + static gdfun cie_cgi;
49 + static gdfun direct;
50 + static gdfun indirect;
51 + static gdfun total;
52 +
53 + static gethfunc headline;
54 + static void init(void);
55 + static void read_input(void);
56 + static void print_values(gdfun *func);
57 + static double posindex(FVECT sd, FVECT vd, FVECT vu);
58 +
59 +
60   struct named_func {
61          char    *name;
62 <        double  (*func)();
62 >        gdfun   *func;
63          char    *descrip;
64   } all_funcs[] = {
65 +        {"dgi", dgi, "Daylight Glare Index"},
66 +        {"brs_gi", brs_gi, "BRS Glare Index"},
67 +        {"ugr", ugr, "Unified Glare Rating"},
68          {"guth_vcp", guth_vcp, "Guth Visual Comfort Probability"},
69          {"cie_cgi", cie_cgi, "CIE Glare Index (Einhorn)"},
70          {"guth_dgr", guth_dgr, "Guth Disability Glare Rating"},
# Line 41 | Line 74 | struct named_func {
74          {NULL}
75   };
76  
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
77   #define newp(type)      (type *)malloc(sizeof(type))
78  
79   char    *progname;
# Line 64 | Line 84 | VIEW   midview = STDVIEW;
84   int     wrongformat = 0;
85  
86  
87 < main(argc, argv)
88 < int     argc;
89 < char    *argv[];
87 > int
88 > main(
89 >        int     argc,
90 >        char    *argv[]
91 > )
92   {
71        extern char     *rindex();
93          struct named_func       *funp;
94          char    *progtail;
95          int     i;
96                                          /* get program name */
97          progname = argv[0];
98 <        progtail = rindex(progname, '/');       /* final component */
98 >        progtail = strrchr(progname, '/');      /* final component */
99          if (progtail == NULL)
100                  progtail = progname;
101          else
# Line 120 | Line 141 | userr:
141   }
142  
143  
144 < headline(s)                     /* get line from header */
145 < char    *s;
144 > static int
145 > headline(                       /* get line from header */
146 >        char    *s,
147 >        void    *p
148 > )
149   {
150          char    fmt[32];
151  
# Line 133 | Line 157 | char   *s;
157                  formatval(fmt, s);
158                  wrongformat = strcmp(fmt, "ascii");
159          }
160 +        return(0);
161   }
162  
163  
164 < init()                          /* initialize calculation */
164 > static void
165 > init(void)                              /* initialize calculation */
166   {
167                                          /* read header */
168          getheader(stdin, headline, NULL);
# Line 153 | Line 179 | init()                         /* initialize calculation */
179   }
180  
181  
182 < read_input()                    /* read glare sources from stdin */
182 > static void
183 > read_input(void)                        /* read glare sources from stdin */
184   {
185   #define S_SEARCH        0
186   #define S_SOURCE        1
# Line 214 | Line 241 | readerr:
241   }
242  
243  
244 < print_values(funp)              /* print out calculations */
245 < double  (*funp)();
244 > static void
245 > print_values(           /* print out calculations */
246 >        gdfun *func
247 > )
248   {
249          register struct glare_dir       *gd;
250  
251          for (gd = all_dirs; gd != NULL; gd = gd->next)
252 <                printf("%f\t%f\n", gd->ang*(180.0/PI), (*funp)(gd));
252 >                printf("%f\t%f\n", gd->ang*(180.0/PI), (*func)(gd));
253   }
254  
255  
256 < double
257 < direct(gd)                      /* compute direct vertical illuminance */
258 < struct glare_dir        *gd;
256 > static double
257 > direct(                 /* compute direct vertical illuminance */
258 >        struct glare_dir        *gd
259 > )
260   {
261          FVECT   mydir;
262          double  d, dval;
# Line 243 | Line 273 | struct glare_dir       *gd;
273   }
274  
275  
276 < double
277 < indirect(gd)                    /* return indirect vertical illuminance */
278 < struct glare_dir        *gd;
276 > static double
277 > indirect(                       /* return indirect vertical illuminance */
278 >        struct glare_dir        *gd
279 > )
280   {
281          return(gd->indirect);
282   }
283  
284  
285 < double
286 < total(gd)                       /* return total vertical illuminance */
287 < struct glare_dir        *gd;
285 > static double
286 > total(                  /* return total vertical illuminance */
287 >        struct glare_dir        *gd
288 > )
289   {
290          return(direct(gd)+gd->indirect);
291   }
# Line 273 | Line 305 | struct glare_dir       *gd;
305   * We return a value less than zero for improper positions.
306   */
307  
308 < double
309 < posindex(sd, vd, vu)                    /* compute position index */
310 < FVECT   sd, vd, vu;
308 > static double
309 > posindex(                       /* compute position index */
310 >        FVECT   sd,
311 >        FVECT   vd,
312 >        FVECT   vu
313 > )
314   {
315          double  sigma, tau;
316          double  d;
# Line 286 | Line 321 | FVECT  sd, vd, vu;
321          if (d >= 1.0)
322                  return(1.0);
323          sigma = acos(d) * (180./PI);
324 <        d = DOT(sd,vu)/sqrt(1.0-d*d);
324 >        d = fabs(DOT(sd,vu)/sqrt(1.0-d*d));
325          if (d >= 1.0)
326                  tau = 0.0;
292        else if (d <= -1.0)
293                tau = 180.0;
327          else
328                  tau = acos(d) * (180./PI);
329          return( exp( sigma*( (35.2 - tau*.31889 - 1.22*exp(-.22222*tau))*1e-3
# Line 299 | Line 332 | FVECT  sd, vd, vu;
332   }
333  
334  
335 < double
336 < guth_dgr(gd)            /* compute Guth discomfort glare rating */
337 < struct glare_dir        *gd;
335 > static double
336 > dgi(            /* compute Daylight Glare Index */
337 >        struct glare_dir        *gd
338 > )
339   {
340 +        register struct glare_src       *gs;
341 +        FVECT   mydir,testdir[7],vhor;
342 +        double  r,posn,omega,p[7],sum;
343 +        int     i,n;
344 +
345 +        spinvector(mydir, midview.vdir, midview.vup, gd->ang);
346 +        sum = 0.0; n = 0;
347 +        for (gs = all_srcs; gs != NULL; gs = gs->next) {
348 +
349 +                /* compute 1/p^2 weighted solid angle of the source */
350 +                r = sqrt(1 - pow(1.-gs->dom/2./PI,2.));
351 +                fcross(vhor,gs->dir,midview.vup);
352 +                normalize(vhor);
353 +                VCOPY(testdir[0],gs->dir);
354 +                fvsum(testdir[1],gs->dir,vhor,r);
355 +                fvsum(testdir[2],gs->dir,vhor,0.5*r);
356 +                fvsum(testdir[5],testdir[2],midview.vup,-0.866*r);
357 +                fvsum(testdir[2],testdir[2],midview.vup,0.866*r);
358 +                fvsum(testdir[3],gs->dir,vhor,-r);
359 +                fvsum(testdir[4],gs->dir,vhor,-0.5*r);
360 +                fvsum(testdir[6],testdir[4],midview.vup,0.866*r);
361 +                fvsum(testdir[4],testdir[4],midview.vup,-0.866*r);
362 +                for (i = 0; i < 7; i++) {
363 +                        normalize(testdir[i]);
364 +                        posn = posindex(testdir[i],mydir,midview.vup);
365 +                        if (posn <= FTINY)
366 +                                p[i] = 0.0;
367 +                        else
368 +                                p[i] = 1./(posn*posn);
369 +                }
370 +                r = 1-gs->dom/2./PI;
371 +                omega = gs->dom*p[0];
372 +                omega += (r*PI*(1+1/r/r)-2*PI)*(-p[0]+(p[1]+p[2])*0.5);
373 +                omega += (2*PI-r*PI*(1+1/r/r))*(-p[0]-0.1667*(p[1]+p[3])
374 +                          +0.3334*(p[2]+p[4]+p[5]+p[6]));
375 +
376 +                sum += pow(gs->lum,1.6) * pow(omega,0.8) /
377 +                       (gd->indirect/PI + 0.07*sqrt(gs->dom)*gs->lum);
378 +                n++;
379 +        }
380 +        if (n == 0)
381 +                return(0.0);
382 +        return( 10*log10(0.478*sum) );
383 + }
384 +
385 +
386 + static double
387 + brs_gi(         /* compute BRS Glare Index */
388 +        struct glare_dir        *gd
389 + )
390 + {
391 +        register struct glare_src       *gs;
392 +        FVECT   mydir;
393 +        double  p;
394 +        double  sum;
395 +
396 +        spinvector(mydir, midview.vdir, midview.vup, gd->ang);
397 +        sum = 0.0;
398 +        for (gs = all_srcs; gs != NULL; gs = gs->next) {
399 +                p = posindex(gs->dir, mydir, midview.vup);
400 +                if (p <= FTINY)
401 +                        continue;
402 +                sum += pow(gs->lum/p,1.6) * pow(gs->dom,0.8);
403 +        }
404 +        if (sum <= FTINY)
405 +                return(0.0);
406 +        sum /= gd->indirect/PI;
407 +        return(10*log10(0.478*sum));
408 + }
409 +
410 +
411 + static double
412 + guth_dgr(               /* compute Guth discomfort glare rating */
413 +        struct glare_dir        *gd
414 + )
415 + {
416   #define q(w)    (20.4*w+1.52*pow(w,.2)-.075)
417          register struct glare_src       *gs;
418          FVECT   mydir;
# Line 324 | Line 434 | struct glare_dir       *gd;
434          }
435          if (n == 0)
436                  return(0.0);
327
437          return( pow(.5*sum/pow((brsum+(5.-wtot)*gd->indirect/PI)/5.,.44),
438                          pow((double)n, -.0914) ) );
439   #undef q
440   }
441  
442  
334 extern double   erf(), erfc();
335
443   #ifndef M_SQRT2
444   #define M_SQRT2 1.41421356237309504880
445   #endif
# Line 340 | Line 447 | extern double  erf(), erfc();
447   #define norm_integral(z)        (1.-.5*erfc((z)/M_SQRT2))
448  
449  
450 < double
451 < guth_vcp(gd)            /* compute Guth visual comfort probability */
452 < struct glare_dir        *gd;
450 > static double
451 > guth_vcp(               /* compute Guth visual comfort probability */
452 >        struct glare_dir        *gd
453 > )
454   {
455 +        extern double   erfc();
456          double  dgr;
457  
458          dgr = guth_dgr(gd);
# Line 353 | Line 462 | struct glare_dir       *gd;
462   }
463  
464  
465 < double
466 < cie_cgi(gd)             /* compute CIE Glare Index */
467 < struct glare_dir        *gd;
465 > static double
466 > cie_cgi(                /* compute CIE Glare Index */
467 >        struct glare_dir        *gd
468 > )
469   {
470          register struct glare_src       *gs;
471          FVECT   mydir;
# Line 375 | Line 485 | struct glare_dir       *gd;
485                  return(0.0);
486          dillum = direct(gd);
487          return(8.*log10(2.*sum*(1.+dillum/500.)/(dillum+gd->indirect)));
488 + }
489 +
490 +
491 + static double
492 + ugr(            /* compute Unified Glare Rating */
493 +        struct glare_dir        *gd
494 + )
495 + {
496 +        register struct glare_src       *gs;
497 +        FVECT   mydir;
498 +        double  p;
499 +        double  sum;
500 +
501 +        spinvector(mydir, midview.vdir, midview.vup, gd->ang);
502 +        sum = 0.0;
503 +        for (gs = all_srcs; gs != NULL; gs = gs->next) {
504 +                p = posindex(gs->dir, mydir, midview.vup);
505 +                if (p <= FTINY)
506 +                        continue;
507 +                sum += gs->lum*gs->lum * gs->dom / (p*p);
508 +        }
509 +        if (sum <= FTINY)
510 +                return(0.0);
511 +        return(8.*log10(0.25*sum*PI/gd->indirect));
512   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines