--- ray/src/util/glarendx.c 1991/04/18 15:18:20 1.4 +++ ray/src/util/glarendx.c 1991/05/02 13:17:41 1.8 @@ -9,6 +9,7 @@ static char SCCSid[] = "$SunId$ LBL"; * * guth_dgr - Guth discomfort glare rating * guth_vcp - Guth visual comfort probability + * cie_cgi - CIE Glare Index (1983) * * 12 April 1991 Greg Ward EPFL */ @@ -21,7 +22,7 @@ extern double erfc(); double posindex(); int headline(); -double direct(), guth_dgr(), guth_vcp(); +double direct(), guth_dgr(), guth_vcp(), cie_cgi(); struct named_func { char *name; @@ -30,6 +31,7 @@ struct named_func { {"direct", direct}, {"guth_dgr", guth_dgr}, {"guth_vcp", guth_vcp}, + {"cie_cgi", cie_cgi}, {NULL} }; @@ -134,7 +136,7 @@ char *s; sscanview(&midview, s+VIEWSTRL); else if (isformat(s)) { formatval(fmt, s); - wrongformat = strcmp(fmt, "ASCII"); + wrongformat = strcmp(fmt, "ascii"); } } @@ -239,6 +241,7 @@ struct glare_dir *gd; * All vectors are assumed to be normalized. * This function is an implementation of the method proposed by * Robert Levin in his 1975 JIES article. + * This calculation presumes the view direction and up vectors perpendicular. * We return a value less than zero for improper positions. */ @@ -252,8 +255,14 @@ FVECT sd, vd, vu; d = DOT(sd,vd); if (d <= 0.0) return(-1.0); + if (d >= 1.0) + return(1.0); sigma = acos(d) * (180./PI); - tau = acos(DOT(sd,vu)/sqrt(1.0-d*d)) * (180./PI); + d = DOT(sd,vu)/sqrt(1.0-d*d); + if (d >= 1.0) + tau = 0.0; + else + tau = acos(d) * (180./PI); return( exp( sigma*( (35.2 - tau*.31889 - 1.22*exp(-.22222*tau))*1e-3 + sigma*(21. + tau*(.26667 + tau*-.002963))*1e-5 ) ) ); @@ -266,14 +275,16 @@ struct glare_dir *gd; { #define q(w) (20.4*w+1.52*pow(w,.2)-.075) register struct glare_src *gs; + FVECT mydir; double p; double sum; double wtot, brsum; int n; + spinvector(mydir, midview.vdir, midview.vup, gd->ang); sum = wtot = brsum = 0.0; n = 0; for (gs = all_srcs; gs != NULL; gs = gs->next) { - p = posindex(gs->dir, midview.vdir, midview.vup); + p = posindex(gs->dir, mydir, midview.vup); if (p <= FTINY) continue; sum += gs->lum * q(gs->dom) / p; @@ -283,9 +294,8 @@ struct glare_dir *gd; } if (n == 0) return(0.0); - else - return( pow( - .5*sum/pow((brsum+(5.-wtot)*gd->indirect/PI)/5.,.44), + + return( pow(.5*sum/pow((brsum+(5.-wtot)*gd->indirect/PI)/5.,.44), pow((double)n, -.0914) ) ); #undef q } @@ -304,5 +314,35 @@ double guth_vcp(gd) /* compute Guth visual comfort probability */ struct glare_dir *gd; { - return(100.*norm_integral(6.374-1.3227*log(guth_dgr(gd)))); + double dgr; + + dgr = guth_dgr(gd); + if (dgr <= FTINY) + return(100.0); + return(100.*norm_integral(6.374-1.3227*log(dgr))); +} + + +double +cie_cgi(gd) /* compute CIE Glare Index */ +struct glare_dir *gd; +{ + register struct glare_src *gs; + FVECT mydir; + double dillum; + double p; + double sum; + + spinvector(mydir, midview.vdir, midview.vup, gd->ang); + sum = 0.0; + for (gs = all_srcs; gs != NULL; gs = gs->next) { + p = posindex(gs->dir, mydir, midview.vup); + if (p <= FTINY) + continue; + sum += gs->lum*gs->lum * gs->dom / (p*p); + } + if (sum <= FTINY) + return(0.0); + dillum = direct(gd); + return(8.*log10(2.*sum*(1.+dillum/500.)/(dillum+gd->indirect))); }