=180-f-1E-4 then
{all the cone surface of dispersed light goes downwards}
part:=0
else
begin
part:=sf*cx/sx;
part:=0.5+arctan(part/sqrt(1-sqr(part)))/pi;
end;
if part<1 then
begin
if Sky=0 then
if i<=i1 then
y:=7.5*exp(-0.1249*y/(1+0.04996*y))
else
if i<=i2 then
y:=1.88*exp(-0.07226*xd+0.0002406*y)
else y:=0.025 + 0.015*sin(2.25*x-c369)
else
y:=1+cSky[Sky]*(exp(dSky[Sky]*x)-exp(dSky[Sky]*pi/2))
+ eSky[Sky]*sqr(cx);
FluxX:=FluxX+y*sx*(1-part);
end;
end;
FluxX:=2*pi*FluxX*D2r/InDegree/FluxXInt;
end;
*)
procedure FluxDownForm(a:real; var FluxX:real);
begin
case Sky of
0: FluxX:=(0.08+0.4*exp(-a/24))*AerosFr + 0.5*(1-AerosFr);
4: FluxX:= 0.342+0.158*exp(-a/27);
5: FluxX:= 0.275+0.225*exp(-a/27);
6: FluxX:= 0.184+0.316*exp(-a/29);
end;
end;
procedure LambDownNorm;
var {i:integer;} j:byte; {xd,x,cx,sx,}y:real;
begin
{indicatrix integral:}
{Not computed any more, as the values are needed
just in the FluxDownVertAng procedure using non-normalized indicatrices.
The functions in FluxDownForm are normalized already. }
{
if Sky>0 then
begin
Flux:=0;
for i:=1 to UpLimit do
begin
xd:=(1.0/InDegree)*i;
x:=D2r*xd;
cx:=cos(x);
sx:=sin(x);
y:=1+cSky[Sky]*(exp(dSky[Sky]*x)-exp(dSky[Sky]*pi/2)) + eSky[Sky]*sqr(cx);
Flux:=Flux+y*sx;
end;
FluxXInt:=2*pi*Flux*D2r/InDegree;
end
else
FluxXInt:=1.0027;
}
{4: 19.6061, 5: 22.0707, 6: 26.5463 would be the results for Sky 4, 5 or 6}
LambDown:=0;
LambDownLow:=0;
for j:=0 to 90 do
begin
y:=j;
cf:=cos(D2r*y);
sf:=sin(D2r*y);
{FluxDownVertAng(y,Flux);}
FluxDownForm(y,Flux); {the approximated curves, instead of computing them}
h2air_mass(y);
y:=(1-1/exp(LnM*ZenExt*Air_Mass)) {dispersed fraction}
*sf*cf;
{sf: projection of the size of the source,
cf: length of the horizontal projection of the unit vector}
{if Sky=0 then
Flux:= Flux*AerosFr + 0.5*(1-AerosFr);} {adding the gaseous dispersion
when using FluxDownVertAng instead of
FluxDownForm only}
y:=y*Flux;
LambDown:=LambDown + y;
if j<=LowAngle then
LambDownLow:=LambDownLow + y;
end;
LambDown:=2*LambDown*D2r;
LambDownLow:=2*LambDownLow*D2r;
{writeln(LambDown:8:4);
} {the line is here for testing purposes only}
{writeln(LambDownLow:8:4);}
{the line is here for testing purposes only}
end;
procedure VertAngDown(b:byte;a:real);
var DispFr, FluxD:real;
{ function f2b(r:real):real;
begin
f2b:=exp(r*LnM)
end;
}
begin
a:=a-90;
h2air_mass(a);
DispFr:=(1-1/exp(LnM*ZenExt*Air_Mass));
{ if DefaultSky then
if Sky=0 then
VertAngDownR[b]:=DispFr*((0.08+0.4*exp(-a/24))*AerosFr + 0.5*(1-AerosFr))
else
VertAngDownR[b]:=DispFr*(0.275+0.225*exp(-a/27))
else
begin
FluxDownVertAng(a,Flux);}
FluxDownForm(a,FluxD);
{ if Sky=0 then
VertAngDownR[b]:=DispFr*(Flux*AerosFr + 0.5*(1-AerosFr))
else }
VertAngDownR[b]:=DispFr*FluxD
{ end }
end;
procedure FillELD;
procedure keywcoded(s:string; var so:string);
var p,ls:byte;
begin
p:=pos('['+s+']',Iline);
ls:=length(s);
if p>0 then
so:=LTrim(copy(ILine,p+ls+2,length(ILine)-(p+ls+1)))
else so:='';
end;
begin
if MakeELD then
begin
keywcoded('MANUFAC',mess); if mess<>'' then MANUFAC:=mess;
keywcoded('TEST',mess); if mess<>'' then TEST:=mess;
keywcoded('LUMINAIRE',mess); if mess<>'' then LUMINAIRE:=mess;
keywcoded('LUMCAT',mess); if mess<>'' then LUMCAT:=mess;
keywcoded('DATE',mess); if mess<>'' then DATE:=mess;
keywcoded('LAMP',mess); if mess<>'' then LAMP:=mess;
end;
end;
procedure WriteEulumdat;
const
EqdV:boolean=true;
EqdH:boolean=true;
IntPianiC:byte=0;
IntGamma:byte=0;
var tomm,Hint,Vint:real; Mc: byte;
laLen,laWid: word; {redefined here to be integers}
begin
Mc:=HoriAngCount;
case SegmentsI of
1: if HoriAngCount=1 then EuSym:=1 else EuSym:=0;
2: begin EuSym:=3; Mc:=2*(Mc-1); end;
4: begin EuSym:=4; Mc:=4*(Mc-1); end;
else EuSym:=5; {incompatible with both true IES and ELD format,
all angles should be computed and EuSym:=0 set}
{I'm not sure which IES case corresponds to EuSym=2}
end;
if ELDallAngles then EuSym:=0;
{testing if planes are equidistant:}
Hint:=360.0/Mc;
if not (HoriAng[1]=0) then EqdH:=false;
if (HoriAngCount>1) and EqdH then
begin
for j:=3 to HoriAngCount do
if round(10*(HoriAng[j]-HoriAng[j-1]))<> round(10*Hint) then EqdH:=false;
end;
if not (VertAng[1]=0) then EqdV:=false;
if (VertAngCount>2) and EqdV then
begin
Vint:=VertAng[2];
for j:=3 to VertAngCount do
if round(10*(VertAng[j]-VertAng[j-1])) <> round(10*Vint) then EqdV:=false;
end;
if EqdH and (10*round(Hint)=round(10*Hint)) and (EuSym<>1) then
IntPianiC:= round(Hint);
if EqdV and (10*round(Vint)=round(10*Vint)) then
IntGamma:= round(Vint);
{... and setting ev. the increments if yes}
if round(PrFiel[7])=2 then tomm:=1e3
else tomm:=304.8;
laLen:=round(abs(PrFiel[9]*tomm));
laWid:=round(abs(PrFiel[8]*tomm));
if laLen=0 then begin laLen:=laWid; laWid:=0; end;
if LUMCAT='' then LUMCAT:='number_unknown';
write
(OutF,
MANUFAC,cl, {1}
'3',cl,
{2 type 1 2 3}
EuSym,cl, {3 symmetry type}
{HoriAngCount}Mc,cl, {4 horiz. angles}
IntPianiC,cl, {5 interval}
VertAngCount,cl, {6 vert. angles}
IntGamma,cl, {7 interval}
TEST,cl, {8 measurement report number 78}
LUMINAIRE,cl, {9 luminaire name 78}
LUMCAT,cl, {10 luminaire number 78}
InpFi,cl, {11 file name 8}
DATE,cl, {12 date/user .le. 78 }
'0',cl, {13 length or diam./mm 4 }
'0',cl, {14 width/mm 4, 0 for circ.}
'0',cl, {15 height/mm 4 }
laLen,cl, {16 length or diam. of luminous area /mm 4 }
laWid,cl, {17 width/mm 4, 0 for circ.}
{laHei0}round(abs(PrFiel[10]*tomm)),cl, {18 height 0 /mm 4 }
{laHei90}'0',cl, {19 height 90 /mm 4 }
{laHei180}'0',cl, {20 height 180 /mm 4 }
{laHei270}'0',cl, {21 height 270 /mm 4 }
round(100*(Flux-Flux90)/Flux),cl, {22 down flux ratio /% 4 }
Flux/LumFluxDklm/10:4:1,cl, {23 light out /% 4 }
'1',cl, {24 conv. factor 6 }
OTHERtilt,cl, {25 tilt 6 }
'1',cl, {26 bulb(lamp) sets 4 }
{writeln(i); sets 4 }
round(PrFiel[1]),cl, {a lamps}
LAMP,cl, {b lamp type}
round(PrFiel[2]*PrFiel[1]),cl, {c flux}
'0',cl, {d temperature}
'0',cl, {e rendering}
round(PrFiel[13]),cl {f watts}
);
for j:=1 to 10 do write(OutF,'0',cl); {DR}
if ELDallAngles then
begin
for i:= 1 to HoriAngCount do
if HoriAng[i]=90 then EuSym3i:=i;
for i:= EuSym3i downto 1 do
write(OutF,90-HoriAng[i]:5:1,cl);
for i:=2 to HoriAngCount do
write(OutF,90+HoriAng[i]:5:1,cl);
for i:= HoriAngCount-1 downto EuSym3i+1 do
write(OutF,270+180-HoriAng[i]:5:1,cl);
end
else
for i:=1 to HoriAngCount do
write(OutF,HoriAng[i] + 90 :5:1, cl); {damned C=0 conventions...}
if EuSym>0 then {filling in the symmetry-dictated remaining angles,
to obey the stupid Eulumdat convention}
case EuSym of
{ 1: for i:=1 to 35 do
write(OutF,'0',cl);
}
2,3: for i:={1 to 17} HoriAngCount+1 to Mc do
if EqdH then
write(OutF,{'0'} {round(HoriAng[1+i-HoriAngCount])+180}
90 + 180+(i-HoriAngCount)*IntPianiC ,cl)
{EulumDat assumes equidistant planes, so the two
expressions should give identic result}
else
write(OutF,{'0'} sre(5,1,90 + 360 - HoriAng[2*HoriAngCount - i ])
{180+(i-HoriAngCount)*IntPianiC} ,cl);
{EulumDat assumes equidistant planes, so the two
expressions should give identic result}
4: for i:={1 to 26} HoriAngCount+1 to Mc do
if EqdH then
write(OutF,{'0'} 90 +(i-HoriAngCount)*IntPianiC,cl)
else {blabla}
write(OutF,{'0'} HoriAng[HoriAngCount-(i mod HoriAngCount)]
+90*(i mod HoriAngCount),cl);
end;
for j:=1 to VertAngCount do write(OutF,VertAng[j]:5:1,cl);
end;
{of WriteEuLumDat}
procedure ReadEulumdat;
begin
if MakeIES then
write(OutF,'IESNA:LM-63-1995',cl,
'[MANUFAC] ',Iline,cl);
if IncludeComments then
writeln(
'# [MANUFAC] ',Iline);
readln(Inpt);
{2 type 1 2 3}
readln(Inpt,EuSym); {3 symmetry type}
readln(Inpt,HoriAngCount {PrFiel[5]}); {4 horiz. angles};
{writeln(HoriAngCount); horiz. angles}
readln(Inpt); {5 interval}
readln(Inpt,VertAngCount {PrFiel[4]}); {6 vert. angles}
{writeln(VertAngCount); vert. angles}
readln(Inpt); {7 interval}
readln(Inpt,Iline); {8 measurement report number}
if MakeIES then write(OutF,
'[TEST] ',Iline,cl);
if IncludeComments then
writeln(
'# [TEST] ',Iline);
readln(Inpt,Iline); {9 luminaire name 78}
if MakeIES then write(OutF,
'[LUMINAIRE] ',Iline,cl);
if IncludeComments then writeln(
'# [LUMINAIRE] ',Iline);
readln(Inpt,Iline); {10 luminaire number 78}
if MakeIES then write(OutF,
'[LUMCAT] ',Iline,cl);
if IncludeComments then writeln(
'# [LUMCAT] ',Iline);
readln(Inpt); {11 file name 8}
readln(Inpt,Iline); {12 date/user <=78 }
if MakeIES then write(OutF,
'[DATE] ',Iline,cl);
if IncludeComments then writeln(
'# [DATE] ',Iline);
readln(Inpt); {13 length or diam./mm 4 }
readln(Inpt); {14 width/mm 4, 0 for circ.}
readln(Inpt); {15 height/mm 4 }
readln(Inpt,laLen); {16 length or diam. of luminous area /mm 4 }
readln(Inpt,laWid); {17 width/mm 4, 0 for circ.}
readln(Inpt,laHei0); {18 height 0 /mm 4 }
readln(Inpt,laHei90); {19 height 90 /mm 4 }
readln(Inpt,laHei180); {20 height 180 /mm 4 }
readln(Inpt,laHei270); {21 height 270 /mm 4 }
if MakeIES then
begin
laHei:=laHei0;
if laHei90>laHei then laHei:=laHei90;
if laHei180>laHei then laHei:=laHei180;
if laHei270>laHei then laHei:=laHei270;
end;
readln(Inpt,Iline); {22 down flux ratio /% 4 }
if IncludeComments then
writeln('# down given: ',Iline, '%');
readln(Inpt,Iline); {23 light out /% 4 }
if IncludeComments then
writeln('# out given: ',Iline, '%');
readln(Inpt); {24 conv. factor 6 }
readln(Inpt,Iline); {25 tilt 6 }
if MakeIES then write(OutF,
'[OTHER] tilt: ',Iline,cl);
if IncludeComments then writeln(
'# tilt: ',Iline);
readln(Inpt,i); {26 bulb(lamp) sets 4 }
{writeln(i); sets 4 }
if i>0 then for j:=1 to i do
begin
(*
for j:=1 to i do readln(Inpt,PrFiel[1]); {lamps}
for j:=1 to i do readln(Inpt,Iline); {lamp type}
if MakeIES then write(OutF,
'[LAMP] ',Iline,cl);
if IncludeComments then writeln(
'# [LAMP] ',Iline);
for j:=1 to i do readln(Inpt,PrFiel[2]); {flux}
for j:=1 to i do readln(Inpt); {temperature}
for j:=1 to i do readln(Inpt); {rendering}
for j:=1 to i do readln(Inpt,PrFiel[13]); {watts}
PrFiel[3]:=PrFiel[2]/1000; {bulb flux / klm}
*)
readln(Inpt,PrFiel[1]); {lamps}
if PrFiel[1]=0 then
begin
ZeroLamps:='?';
PrFiel[1]:=1;
end;
readln(Inpt,Iline); {lamp type}
if MakeIES then write(OutF,
'[LAMP] ',Iline,cl);
if IncludeComments then writeln(
'# [LAMP] ',Iline);
readln(Inpt,PrFiel[2]); {flux}
if PrFiel[2]=0 then
begin
ZeroLampFlux:='?';
PrFiel[2]:=1000;
end;
if IncludeComments then
writeln('# Bulbs:', PrFiel[1]:2:0,ZeroLamps,',',
PrFiel[2]:7:0,ZeroLampFlux,' lm each');
readln(Inpt); {temperature}
readln(Inpt); {rendering}
readln(Inpt,PrFiel[13]); {watts}
PrFiel[3]:=PrFiel[2]/1000; {bulb flux / klm;
but is it not to be multiplied by PrFiel[1], the lamps number?}
end;
for j:=1 to 10 do readln(Inpt); {DR}
read(Inpt,HoriAng[1]);
if HoriAngCount>1 then
for i:=2 to HoriAngCount do
begin
readln(Inpt,HoriAng[i]);
if HoriAng[i]<=HoriAng[i-1] then
begin
writeln('Not rising horizontal angles.'); halt;
end;
if HoriAng[i]=90 then EuSym3i:=i;
end;
if EuSym=3 then { to make some Phillips files work --
their data start at 90 degrees }
if EuSym3i>0 then
for i:=1 to (HoriAngCount div 2 + 1) do
HoriAng[i]:=HoriAng[EuSym3i+i-1]-90;
for j:=1 to VertAngCount do readln(Inpt,VertAng[j]);
if EuSym>0 then
begin
HoriAngCount:=HoriAngCount div 2;
if EuSym>3 then HoriAngCount:=HoriAngCount div 2;
HoriAngCount:=HoriAngCount + 1;
if EuSym=1 then HoriAngCount:=1;
end;
if MakeIES then
begin
write(OutF,
'[OTHER] Eulumdat file:',InpFi,cl,
'TILT=NONE',cl,
PrFiel[1]:1:0, PrFiel[2]/PrFiel[1]:7:0, PrFiel[3]:5:1,
VertAngCount:3, HoriAngCount:3, ' 1 2 ');
if laWid<1 then {circular}
write(OutF,
-laLen/1e3:5:2, ' 0', laHei/1e3:5:2,cl)
else
write(OutF,
laWid/1e3:5:2, laLen/1e3:5:2, laHei/1e3:5:2,cl);
write(OutF,
'1 1 ',PrFiel[13]:4:0,cl);
for i:=1 to VertAngCount do write(OutF, VertAng[i]:6:1);
write(OutF,cl);
for i:=1 to HoriAngCount do write(OutF, HoriAng[i]:4:0);
write(OutF,cl);
end;
end;
{of ReadEuLumDat}
procedure GroundIllum; {computes illuminance pixel per pixel}
var xlH, ylH, xhH, yhH: integer; HAi:real;
LogCol : array [0..diamC+10,1..3] of byte;
ix, iy: integer; ix0: word;
r,p : real;
iM1:word;
LogImFile : file;
VAng, VAngTrue, VAngD, LumI1, LumI0, lnStep, LogLR, LogBase: real;
auxstr: string; LogL: byte;
LumI: array [-diamC..diamC] of real;
LumIc: array [-radC..radC] of real;
LumIcc: array [-radC..radC] of real;
diamH: word;
begin
xlH:=round(xl*Hpix);
ylH:=round(yl*Hpix);
xhH:=round(xh*Hpix);
yhH:=round(yh*Hpix);
lnstep:=ln(10)/StepsTo10;
LogBase:=ln(BaseLum);
if TrueIllum then
LogBase:=LogBase - ln(LampFluxForce) + 2*ln(Height);
BaseLumMin:=exp(ln(BaseLum)-lnstep/2);
diamH:=2*radH;
if LogImage='' then
begin
FSplit(InpFi,Fdir,Fname,Fext);
LogImage:=Fdir+Fname+'.ppm'
end;
assign(LogImFile,LogImage);
rewrite(LogImFile,1);
if add_scale then
auxstr:='P6'+#10+SI(4,diam +11 )+SI(5,diam+1)+#10+'255'+#10
else
auxstr:='P6'+#10+SI(4,diam +1 )+SI(5,diam+1)+#10+'255'+#10;
BlockWrite(LogImFile,auxstr[1],length(auxstr));
for iy:= rad downto -rad do
begin
for ix:=-diam to diam do {12 pole heights to both sides included}
begin
{point illuminance}
C2_to_Pd (ix,iy,r,p);
p:=p - rotAvert; while p>360 do p:=p-360; while p<0 do p:=p+360;
VAng:=arctan(r/Hpix); {r becomes an auxiliary variable further on}
VAngTrue:=VAng;
if Tilt then
begin {perhaps transforming Vang and p will do...}
{bringing the VertAn to latitude temporarily:}
VAng:=VAng-pi/2;
p:=p*D2r;
P3s_Vector(p,VAng,Ve); {V[3] to max F, V[1] to 0 L}
mat_vect(MaF,Ve);
{vector:= matrix * vector}
Vector_P3s(Ve,p,VAng);
p:=p/D2r;
VAng:=VAng+pi/2;
end;
VAngD:=rad_to_deg(VAng);
i:=1; iM1:=0;
if HoriAng[HoriAngCount]=180 then if p>180 then p:=360-p;
if HoriAng[HoriAngCount]=90 then if p>90 then p:=180-p;
while (iM1=0) and (HoriAng[i]HoriAngCount then
begin
i:=1; iM1:=HoriAngCount;
end;
end;
if i>1 then iM1:=i-1 else if iM1<>HoriAngCount then iM1:=1;
j:=1;
while (VertAng[j]<=VangD) and (VertAng[j]i then
begin
if i=1 then HAi:=HoriAng[i]+360 else HAi:=HoriAng[i];
r:=(HAi-p)/(HAi-HoriAng[iM1]);
LumI[ix]:= LumI0 * r
+ LumI1 * (1-r);
end
else
LumI[ix]:=LumI1;
end
else
LumI[ix]:=-1;
r:=cos(VAngTrue);
LumI[ix]:=LumI[ix]*(sqr(r)*r)/LumFluxDklm;
{if (3 diam) then {r/h<12, adding one luminaire to the left}
LumIc[ix]:=LumIc[ix] +LumI[ix+radH];
if not (radH > rad) then {r/h<6, further one to the left, and one to the right}
LumIc[ix]:=LumIc[ix] +LumI[ix+diamH] +LumI[ix-radH];
if not (radH > rad div 2) then {r/h<3, including futher two luminaires}
LumIc[ix]:=LumIc[ix] +LumI[ix+diamH+radH] +LumI[ix-diamH];
LumIcc[ix]:=LumIc[ix]
end;
for ix:=-rad to rad do
begin
{point illuminance}
ix0:=ix+rad;
if (ix>0) then
if not (radH > rad+ix) then LumIcc[ix]:=LumIc[ix-radH]
else LumIcc[ix]:=LumI[ix]; {single light used...}
if (ix>0) or (not continuous) then LumIc[ix]:=LumI[ix];
if (LumIc[ix]=0 then
fillchar(LogCol[ix0][1],3,0)
else
fillchar(LogCol[ix0][1],3,128)
else
begin
LogLR:=(ln(LumIc[ix])-LogBase)/lnstep;
if LogLR>stepsNm1 then LogLR:=stepsNm1;
LogL:=round(LogLR);
for j:=1 to 3 do
LogCol[ix0][j]:=
colorLog[LogL div shadesN][j] * pow2m1[LogL mod shadesN] div 2;
end;
{marks each height:}
if (iy mod Hpix = 0) then if (ix mod Hpix = 0) then
fillchar(LogCol[ix0][1],3,255);
{marks on axes each 0.2 height:}
if (iy = 0) and (ix mod Hpix2 = 0) then
fillchar(LogCol[ix0][1],3,255);
if (ix = 0) and (iy mod Hpix2 = 0) then
fillchar(LogCol[ix0][1],3,255);
{useful rectangle}
if CalcUseful then
begin
if (iy=yhH) or (iy=ylH) then if (xlH<=ix) and (ix<=xhH) then
fillchar(LogCol[ix0][1],3,128);
if (ix=xhH) or (ix=xlH) then if (ylH=xlH) and (ylH<=iy) and (iy<=yhH) then
if continuous then
begin
FluxUI:=FluxUI + LumIcc[ix];
inc(FluxUIn);
if IllumMaxILumIcc[ix] then IllumMinI:=LumIcc[ix];
end
else
begin
FluxUI:=FluxUI + LumI[ix];
inc(FluxUIn);
if IllumMaxILumI[ix] then IllumMinI:=LumI[ix];
end;
end;
end;
{adding scale at right}
if add_scale then
begin
ix0:=diam+1;
LogL:=stepsNm1 - (((stepsNm1+1)*(rad-iy))-1) div (diam+1);
for j:=1 to 3 do
begin
LogCol[ix0][j]:=
colorLog[LogL div shadesN][j] * pow2m1[LogL mod shadesN] div 2;
for i:=1 to 9 do
LogCol[ix0+i][j]:=LogCol[ix0][j];
if ScaleChanged then {black strip in the middle of the scale}
LogCol[ix0+5][j]:=0;
end;
BlockWrite(LogImFile,LogCol,3*(diam +11 ));
end
else
begin
BlockWrite(LogImFile,LogCol,3*(diam +1 ));
end
end;
close(LogImFile);
end; {of GroundIllum}
begin {of Main Programme}
D2r:=pi/180;
c369:=369*D2r;
LnM:=Ln(10)/2.5;
Mess:='';
if ParamCount=0 then Help;
process_parameters;
xlt:=xl+t;
xht:=xh-t;
ylt:=yl+t;
yht:=yh-t;
xlo:=xl-t;
xho:=xh+t;
ylo:=yl-t;
yho:=yh+t;
if (MakeIES or MakeELD) and (OutFIES='') then
begin
FSplit(InpFi,Fdir,Fname,Fext);
if MakeELD then
OutFIES:=Fdir+Fname+'.ldt'
else
OutFIES:=Fdir+Fname+'.ies';
if FSearch(OutFIES,'')<>'' then
begin
writeln(OutFIES,' exists!');
MakeIES:=false;
MakeELD:=false;
end
end;
if AngInRad then AngUnit:=180/pi else AngUnit:=1;
AerosFr:=(ZenExt-0.1)/ZenExt;
UpLimit:=InDegree*180-1;
if CalcUseful then
begin
PolesAt80:=sin(80*D2r)/cos(80*D2r);
TooLong:=
(abs(xl)>PolesAt80)
or (abs(xh)>PolesAt80)
or (abs(yl)>PolesAt80)
or (abs(xh)>PolesAt80);
end;
if LineOnly then
if Heading then
begin
if not FS_only then
begin
if not Distant then
writeln(
'# % of Increase of Sky Luminance')
else
writeln(
'# % of Increase of Sky Luminance in Distant Places by light below',
LowAngle:5:1,' degrees',cl,
'# (for the zenith luminance such an angle suits places up to',
5/sin(LowAngle*D2r):4:0,' km distance)');
writeln(
'# due to light going from the luminaire above horizon, as compared',cl,
'# with the luminance produced by the light dispersed from the ground',cl,
'# concerns the following situation:',cl,
'# Albedo =', Albedo:5:2,cl,
'# Zenith Extinction =', ZenExt:5:2,' mag',
' (i.e., direct light remaining', 100/exp(LnM*ZenExt):4:0,' %)',cl,
'# Indicatrix type =', Sky:1,' (0: acc. to P.Cinzano, 4..6: CIE sky types)',cl);
end; {of (not FS_only)}
if CalcUseful then
begin
if MakeLogImage and Continuous then
writeln(
'# Calculation of the useful fraction of the outcoming luminous flux',cl,
'# concerns a rectangle of ',xl:4:2,':',xh:4:2,':',yl:4:2,':',yh:4:2,' pole heights',cl,
'# illuminated by a row of luminaires spaced ',1.0*radH/Hpix:4:2,' pole heights;',cl,
'# just luminaires closer than ', 2*Hpix2c,' pole heights are considered.',cl,
'# Grid is the same as for the illuminance plot, 1 point each 1/',Hpix,' pole height.')
else
begin
writeln(
'# Calculation of the useful fraction of the outcoming luminous flux',cl,
'# concerns a rectangle of ',xl:4:2,':',xh:4:2,':',yl:4:2,':',yh:4:2,' pole heights.');
if MakeLogImage then
writeln(
'# Grid is the same as for the illuminance plot, 1 point each 1/',Hpix,' pole height.')
else
begin
write(
'# Just those tabelled specific iluminances are used whose rays hit the rectangle,',cl,
'# the average is per ray rather than per area; at rectangle margins, a strip of',cl,
'# +- ',t:4:2,' pole heights is included with a half weight');
if TooLong then write(';',cl,
'# just hits within',PolesAt80:5:2,
' pole heights (< 80 degrees from nadir) are included.',cl2)
else
write('.',cl2);
end
end;
if rotA then writeln(
'# The luminaire is rotated by', rotAvert:6:1,' degrees around vertical.')
else writeln;
end;
write(
'#FiOut',
' 75-90',
' >= 80degrees ');
if FS_only then
write(
' 65 70 abs.')
else
begin
write(
' >= 90degrees ');
if mInt then
write(
' 65 70 abs.')
else write(' ')
end;
write(
' CutOff? ');
if CalcUseful then
if TrueIllum then
if LampFluxForce=0 then
write(
' useful/Out ',
'Illum/lx (',Height:4:1,' m, file-given lm)')
else
write(
' useful/Out ',
'Illum/lx (',Height:4:1,' m,', LampFluxForce*1000:6:0,' lm)')
else
write(
' useful/Out ',
'Illum/lx(1m,1klm)');
writeln(' filename');
write(
'# % ',
' % ',
' cd/klm',
' % Out');
if FS_only then
write(
' maxima cd/klm ')
else
begin
write(
' cd/klm',
' % Out');
if mInt then
begin
if not Distant then
write(
' % ILP. ')
else
write(
' % IDLP.');
write(
' max. cd/klm ')
end
else
if not Distant then
write(
' % I.L.P. ')
else
write(
' % I.D.L.P.');
end;
if CalcUseful then
writeln(
' %',
' max av min av/min')
else
writeln;
if InpFi='' then halt;
end;
AsResT(Inpt,InpFi);
if MakeIES or MakeELD then
begin
assign(OutF,OutFIES);
rewrite(OutF);
end;
readln(Inpt,ILine);
if eof(Inpt) then begin close(Inpt); halt(20) end
{served for DOS version in case of a LF-only ended lines in the ies file}
else
if not EuLumDat then
begin
if IncludeComments then writeln('# ',Iline);
FillELD;
if not (copy(ILine,1,5)='TILT=') then
repeat
readln(Inpt,ILine); FillELD;
if IncludeComments then writeln('# ',Iline);
until (copy(ILine,1,5)='TILT=') or eof(Inpt);
end
else {if EuLumDat} ReadEulumdat;
if eof(Inpt) then
begin
writeln(InpFi,': No TILT= line, probably no ies file.');
halt(1);
end;
if copy(ILine,1,12)='TILT=INCLUDE' then
for i:=1 to 4 do readln(Inpt); {
skipping 16 numbers}
if not EuLumDat then
begin
for i:=1 to 13 do read(Inpt,PrFiel[i]);
if PrFiel[1]=0 then
begin
ZeroLamps:='?';
PrFiel[1]:=1;
end;
if PrFiel[2]=0 then
begin
ZeroLampFlux:='?';
PrFiel[2]:=1000;
end;
if PrFiel[3]=0 then
begin
ZeroCandMult:='?';
PrFiel[3]:=1;
end;
if ForceCandMultiplier then
begin
LumFluxDklm:=1;
PrFiel[3]:=PrFiel[1]*PrFiel[2]/1000;
end
else
LumFluxDklm:=PrFiel[1]*PrFiel[2]/1000/PrFiel[3];
{PrFiel[3] is 1, mostly. Some ies files report it as 1 in spite of
giving not luminous intensities / cd, but specific luminous intensities
/ cd/klm (which is the only possibility for Eulumdat). For the given
bulb(s), this can be cured by ForceCandMultiplier which sets PrFiel[3]
to luminous flux / klm. By PrFiel[3], the tabelled luminous intensities
are then multiplied as usually to get cd (real luminous intensity).
LumFluxDklm is a quantity by which the tabelled values are to be
divided to get cd/klm.
}
VertAngCount:=round(PrFiel[4]);
if VertAngCount<>PrFiel[4] then
begin writeln('Non-integer vert. angles count:',PrFiel[4]:6:1); halt end
else if VertAngCount<1 then
begin writeln('Non-positive vert. angles count:',PrFiel[4]:6:1); halt end;
HoriAngCount:=round(PrFiel[5]);
if HoriAngCount<>PrFiel[5] then
begin writeln('Non-integer hori. angles count:',PrFiel[5]:6:1); halt end
else if HoriAngCount<1 then
begin writeln('Non-positive hori. angles count:',PrFiel[5]:6:1); halt end;
end
else {if EuLumDat}
LumFluxDklm:=1;
if HoriAngCount>HoriAngMax then
begin writeln('Too many horizontal angles,',
HoriAngCount:4,'>',HoriAngMax:4); halt end;
if VertAngCount>VertAngMax then
begin writeln('Too many vertical angles,',
VertAngCount:4,'>',VertAngMax); halt end;
if not EuLumDat then
begin
if IncludeComments then
begin
writeln('# Bulbs:', PrFiel[1]:2:0,ZeroLamps,',',
PrFiel[2]:7:0,ZeroLampFlux,' lm each');
if PrFiel[3]<>1 then
writeln('# (luminous intensites divided by',
PrFiel[3]:6:2,ZeroCandMult,
' in the original ies file)');
writeln('# Number of measured angles:', PrFiel[4]:4:0,' vertical,',
PrFiel[5]:4:0,' horizontal ones');
writeln('# Photometric type:', PrFiel[6]:2:0,
', Units type:', PrFiel[7]:2:0);
if PrFiel[8]<0 then
writeln('# Luminous opening diameter (and height?):',
-1*PrFiel[8]:8:3,' (', PrFiel[10]:8:3,' )')
else
writeln('# Luminous openig width, length and height:',
PrFiel[8]:8:3, PrFiel[9]:8:3, PrFiel[10]:8:3);
writeln('# Ballast factor:', PrFiel[11]:2:0,
', Input power:', PrFiel[13]:5:0,' W');
writeln(cl);
end;
for j:=1 to VertAngCount do read(Inpt,VertAng[j]);
if PrFiel[6]>=2 then {changing latitudes to polar distances}
begin
for j:=1 to VertAngCount do VertAng[j]:=VertAng[j]+90;
if not Tilt then
begin
CalcUseful:=false;
CT:=7;
end;
end;
end;
if not DefaultSky then {downward fraction of the lambertian upward emission}
LambDownNorm;
{is to be computed}
Last:=VertAng[1];
CosLast:=cos(Last*D2r);
CosBefLast:=1;
for j:=2 to VertAngCount-1 do
begin
if VertAng[j]<=VertAng[j-1] then
begin
writeln('Not rising vertical angles.'); halt;
end;
Now:=VertAng[j-1]+(VertAng[j]-VertAng[j-1])/2;
CosNow:=cos(Now*D2r);
VertCosInt[j-1]:=CosLast-CosNow;
if VertAng[j-1]=90 then
begin
if CosBefLast=1 then CosBefLast:=-CosNow;
VertCosInt90d:=CosBefLast;
{down to the glare zone}
VertCosInt90:=-CosNow;
VertAngDown(j-1,(Now+90)/2)
end
else
if VertAng[j-1]=80 then
VertCosInt80:=cos(80*D2r)-CosNow
else
if VertAng[j-1]=75 then
VertCosInt75:=cos(75*D2r)-CosNow
else if VertAng[j-1]>90 then
VertAngDown(j-1,VertAng[j-1]);
Last:=Now;
CosBefLast:=CosLast;
CosLast:=CosNow;
end;
j:=VertAngCount;
Now:=VertAng[j];
CosNow:=cos(Now*D2r);
VertCosInt[j]:=CosLast-CosNow;
if VertAng[j-1]>90 then
VertAngDown(j-1,VertAng[j-1]);
if VertAng[j]>90 then
VertAngDown(j,VertAng[j]);
if not EuLumDat then
begin
read(Inpt,HoriAng[1]);
{hack: HoriAng[1]:=HoriAng[1]-90;}
if HoriAngCount>1 then
for i:=2 to HoriAngCount do
begin
read(Inpt,HoriAng[i]);
{hack: HoriAng[i]:=HoriAng[i]-90;}
if HoriAng[i]<=HoriAng[i-1] then
begin
writeln('Not rising horizontal angles.'); halt;
end;
end;
end; {of if not EuLumDat then}
if HoriAng[HoriAngCount]=360 then dec(HoriAngCount);
{this obsolete angle was found by Siteco ies files from 2007-01}
if CalcUseful then
begin
for j:=1 to VertAngCount do
if VertAng[j]<89 then
VertTan[j]:=sin(VertAng[j]*D2r)/cos(VertAng[j]*D2r);
if HoriAngCount=1 then
for j:=1 to 180 do
begin
HoriSin[j]:=sin((j-1)*2*D2r);
HoriCos[j]:=cos((j-1)*2*D2r);
end
else
for j:=1 to HoriAngCount do
begin
HoriSin[j]:=sin((HoriAng[j]+rotAvert)*D2r);
HoriCos[j]:=cos((HoriAng[j]+rotAvert)*D2r);
if rotA and (not Tilt) then
begin
HoriSin2[j]:=sin((-HoriAng[j]+rotAvert)*D2r);
HoriCos2[j]:=cos((-HoriAng[j]+rotAvert)*D2r);
HoriSin3[j]:=sin((180-HoriAng[j]+rotAvert)*D2r);
HoriCos3[j]:=cos((180-HoriAng[j]+rotAvert)*D2r);
HoriSin4[j]:=sin((HoriAng[j]-180+rotAvert)*D2r);
HoriCos4[j]:=cos((HoriAng[j]-180+rotAvert)*D2r);
end;
end;
AsymY:=abs(yl+yh)>0.01; {the Useful rectangle is not symmetric in Y,
that is, in direction along the street}
AsymX:=abs(xl+xh)>0.01; {is not symmetric perpendicularly to the street}
if (HoriAngCount>1) and rotA then
begin AsymY:=true; AsymX:=true end;
end;
if TrueIllum then
if LampFluxForce=0 then LampFluxForce:=LumFluxDklm*PrFiel[3];
{$I-}
for i:=1 to HoriAngCount do
begin
for j:=1 to VertAngCount do
begin
read(Inpt,LumInt[i,j]);
if ioresult=106 then begin close(inpt); halt(106); end;
{served for the case of commas-ended numbers in the ies file}
if MakeIES then write(OutF,LumInt[i,j]:6:1);
end;
{hack: writeln(HoriAng[i]);}
if MakeIES then write(OutF,cl);
end;
if MakeIES then close(OutF);
close(inpt);
{$I+}
{Flux integration and luminous intensity maxima:}
if HoriAngCount>1 then
begin
HoriAng[HoriAngCount+1]:=HoriAng[HoriAngCount]+
(HoriAng[HoriAngCount]-HoriAng[HoriAngCount-1]);
HoriAng[0]:=HoriAng[1]-
(HoriAng[2]-HoriAng[1])
end
else
begin
HoriAng[2]:=HoriAng[1]+180;
HoriAng[0]:=HoriAng[1]-180;
end;
if HoriAng[HoriAngCount+1]-HoriAng[0]>=359.9 then
begin
SegmentSize:=360;
JustSegment:=false;
end;
if JustSegment then
begin
SegmentSize:=HoriAng[HoriAngCount]-HoriAng[1];
if PrFiel[6]=2 then {if (SegmentSize<90+1E-4) and (SegmentSize>90-1E-4)}
if HoriAng[1]=0 then SegmentSize:=180
else SegmentSize:=360;
end;
if SegmentSize<89.9 then CalcUseful:=false;
SegmentsI:=round(360/SegmentSize);
if abs(360/SegmentSize - SegmentsI) >0.1 then
begin
JustSegment:=false;
SegmentSize:=360;
SegmentsI:=1;
end;
if (SegmentsI>1) and (not(SegmentsI in [2,4])) then
CalcUseful:=false;
if VertAng[1]>80 then CalcUseful:=false; {for uplights}
if Tilt then
begin
{ mat(Ma,2,Tilt2*D2r);}
SegmentsTilt:=SegmentsI;
if HoriAngCount=1 then
begin
SegmentsTilt:=36;
SegmentSize:=10;
end;
end;
Last:=HoriAng[0]+(HoriAng[1]-HoriAng[0])/2;
for i:=1 to HoriAngCount do
begin
Now:=HoriAng[i]+(HoriAng[i+1]-HoriAng[i])/2;
HoriAngInt:=Now-Last;
if HoriAngCount=1 then
if Tilt then
HoriAngInt:=10
else
HoriAngInt:=360;
Last:=Now;
if JustSegment and ((i=1) or (i=HoriAngCount)) then
HoriAngInt:=HoriAngInt / 2;
for segment:=1 to SegmentsTilt do
for j:=1 to VertAngCount do
begin
if not Tilt then
begin
VertAn:=VertAng[j];
end
else
begin
{rotation around horizontal axis,
bringing the VertAn to latitude temporarily:}
VertAn:=(VertAng[j]-90)*D2r;
if {Tilt and (-Tilt holds here...-)} (SegmentsI<6) then
HoriAn:=(HoriAng[i]*(2*(segment mod 2)-1)
+ 180 * (segment div 3)
+ rotAvert)*D2r
else {no plane symmetry, just repeating segments}
HoriAn:=(HoriAng[i]+SegmentSize*(segment-1)+rotAvert)*D2r;
{writeln(HoriAn/D2r:5:1, VertAn/D2r:5:1); }
P3s_Vector(HoriAn,VertAn,Ve); {V[3] to max F, V[1] to 0 L}
mat_vect(MaF,Ve);
{vector:= matrix * vector}
Vector_P3s(Ve,HoriAn,VertAn);
if CalcUseful then
begin
HoriSin[i]:=sin(HoriAn);
HoriCos[i]:=cos(HoriAn);
if VertAn < -0.02 then
VertTan[j]:=-cos(VertAn)/sin(VertAn)
else VertTan[j]:=1000;
end;
HoriAn:=HoriAn/D2r;
VertAn:=90+VertAn/D2r;
{writeln(HoriAn:5:1, VertAn:5:1); }
end {of if Tilt};
FluxElement:=LumInt[i,j] * HoriAngInt * VertCosInt[j];
FluxElementHalf:=FluxElement/2;
Flux:=Flux + FluxElement;
if LumInt[i,j]>MaxLumInt then MaxLumInt:=LumInt[i,j];
if (VertAn>=62.5) and (VertAn<67.5) then
if LumInt[i,j]>MaxLumInt65 then MaxLumInt65:=LumInt[i,j];
if (VertAn>=67.5) and (VertAn<76) then
if LumInt[i,j]>MaxLumInt70 then MaxLumInt70:=LumInt[i,j];
if VertAn>=75 then
if VertAn<=90 then
begin {glare part}
FluxElementGlare:=FluxElement;
if VertAn=75 then {taking just the part above 75 degrees}
if Tilt then
FluxElementGlare:=FluxElementHalf
else
FluxElementGlare:=LumInt[i,j] * HoriAngInt * VertCosInt75
else
if VertAn=90 then
if Tilt then
FluxElementGlare:=FluxElementHalf
else
FluxElementGlare:=LumInt[i,j] * HoriAngInt * VertCosInt90d
else FluxElementGlare:=FluxElement;
if VertAn<=90 then
FluxGlare:=FluxGlare + FluxElementGlare;
end {of glare part};
if VertAn>=80 then
begin
if VertAn=80 then {taking just the part above 80 degrees}
if Tilt then
FluxElement:=FluxElementHalf
else
FluxElement:=LumInt[i,j] * HoriAngInt * VertCosInt80;
Flux80:=Flux80 + FluxElement;
if LumInt[i,j]>MaxLumInt80 then MaxLumInt80:=LumInt[i,j];
if VertAn>=90 then
begin
if VertAn=90 then
if Tilt then
FluxElement:=FluxElementHalf
else
FluxElement:=LumInt[i,j] * HoriAngInt * VertCosInt90;
Flux90:=Flux90 + FluxElement;
if Tilt then
if VertAn=90 then
begin
if jMaxLumInt90 then MaxLumInt90:=LumInt[i,j];
if j=VertAngCount then
if LumInt[i,j]>MaxLumIntM then MaxLumIntM:=LumInt[i,j];
end;
end
else if (CalcUseful and not MakeLogImage) then
{assuming no useful illum above 80 degrees}
if (HoriAngCount=1) and (not Tilt) then
begin
FluxElement:=FluxElement/180;
for k:=1 to 180 do Useful(HoriCos[k],HoriSin[k])
end
else
Useful(HoriCos[i],HoriSin[i]);
end;
end;
if SegmentsTilt>1 then SegmentSize:=360;
Flux :=Flux *360*D2r/SegmentSize;
Flux80:=Flux80*360*D2r/SegmentSize;
Flux90:=Flux90*360*D2r/SegmentSize;
FluxGlare:=FluxGlare*360*D2r/SegmentSize;
FluxDown:=FluxDown*360*D2r/SegmentSize;
FluxDownLow:=FluxDownLow*360*D2r/SegmentSize;
MaxLumInt80:=MaxLumInt80/LumFluxDklm;
MaxLumInt90:=MaxLumInt90/LumFluxDklm;
MaxLumInt65:=MaxLumInt65/LumFluxDklm;
MaxLumInt70:=MaxLumInt70/LumFluxDklm;
MaxLumInt :=MaxLumInt /LumFluxDklm;
if CalcUseful then
begin
FluxU :=FluxUq[1];
if not Tilt then
case SegmentsI of
2: if AsymY then
FluxU :=FluxU+FluxUq[4]
else FluxU:=2*FluxU;
4: begin
if AsymY then
FluxU :=FluxU+FluxUq[4]
else FluxU:=2*FluxU;
if AsymX then
FluxU :=FluxU+FluxUq[2]
else FluxU:=2*FluxU;
if AsymX and AsymY then
FluxU :=FluxU+FluxUq[3]
end;
end;
FluxU :=FluxU*D2r;
end;
if CT<>7 then
if (MaxLumInt90<0.5) and (MaxLumInt80<100) then CT:=0
else
if MaxLumInt90<0.5 then CT:=1
else
if (MaxLumInt90<=10) and (MaxLumInt80<=30) then CT:=2
else
if (MaxLumInt90<=25) and (MaxLumInt80<=100) then CT:=3
else
if (MaxLumInt90<=50) and (MaxLumInt80<=100) then CT:=4
else
if (MaxLumInt90<=50) and (MaxLumInt80<=200) then CT:=5
else CT:=6;
if (VertAng[VertAngCount]<90) and (MaxLumInt80>0) then QM8:='?';
if (VertAng[VertAngCount]=90) and (MaxLumInt90>0) then QM9:='?';
if (VertAng[VertAngCount]<179.9) and (MaxLumIntM>0) then QMM:='?';
if select_cutoff then
if CT<=SC then
begin
{$I-}
assign(outt,OutFi);
append(outt);
if ioresult<>0 then
rewrite(outt);
{$I+}
write(outt,InpFi,' ');
close(outt);
end;
if Flux/LumFluxDklm/10>100 then
writeln(
'# NONSENSE SUMMARY RESULTS of ies2tab: output flux is to be under 100 %!');
if MakeELD then
begin
WriteEulumdat;
if ELDreverseAngles then
for i:= HoriAngCount downto 1 do
for j:=1 to VertAngCount do
write(OutF,sre(5,1,LumInt[i,j]/LumFluxDklm),cl)
else if ELDallAngles then
begin
for i:= 1 to HoriAngCount do
if HoriAng[i]=90 then EuSym3i:=i;
for i:= EuSym3i downto 1 do
for j:=1 to VertAngCount do
write(OutF,sre(5,1,LumInt[i,j]/LumFluxDklm),cl);
for i:=2 to HoriAngCount do
for j:=1 to VertAngCount do
write(OutF,sre(5,1,LumInt[i,j]/LumFluxDklm),cl);
for i:= HoriAngCount-1 downto EuSym3i+1 do
for j:= 1 to VertAngCount do
write(OutF,sre(5,1,LumInt[i,j]/LumFluxDklm),cl);
end
else
for i:=1 to HoriAngCount do
for j:=1 to VertAngCount do
write(OutF,sre(5,1,LumInt[i,j]/LumFluxDklm),cl);
if MakeELD then close(OutF);
end;
{ground illuminance:}
if MakeLogImage then
GroundIllum;
if LineOnly then
begin
write(
Flux/LumFluxDklm/10:6:1,
100*FluxGlare/Flux:5:1,
MaxLumInt80:7:1,QM8,
100*Flux80/Flux:5:1);
if FS_only then
write
(MaxLumInt65:6:0, MaxLumInt70:5:0)
else
write
(MaxLumInt90:7:1,QM9,
100*Flux90/Flux:5:1,QMM);
if FS_only then
if MaxLumInt<10000 then
write
(MaxLumInt:5:0)
else
write
(MaxLumInt:6:0)
else
if not Distant then
write(
100*FluxDown/((Flux-Flux90)*Albedo*LambDown):4:0,QMM)
else
write(
100*FluxDownLow/((Flux-Flux90)*Albedo*LambDownLow):4:0,QMM);
if mInt and (not FS_only) then
begin
write
(MaxLumInt65:6:0, MaxLumInt70:5:0);
if MaxLumInt<10000 then
write
(MaxLumInt:5:0)
else
write
(MaxLumInt:6:0)
end;
write(
' ',CutoffType[CT]{,' ',InpFi});
{if length(InpFi)<12 then
for j:=1 to 12-length(InpFi) do write(' ');}
if CalcUseful then
if MakeLogImage then {write perhaps a bit better estimate...}
begin
write(
100*(FluxUI*LumFluxDklm/sqr(Hpix))/Flux:5:1);
if TrueIllum then
write(
LampFluxForce*IllumMaxI/sqr(Height):7:1,
LampFluxForce*FluxUI/(FluxUIn * sqr(Height)):6:1,
LampFluxForce*IllumMinI/sqr(Height):5:1)
else
write(
IllumMaxI:7:1,
FluxUI/FluxUIn:6:1,
IllumMinI:5:1);
if IllumMinI>0.1 then write(
FluxUI/FluxUIn/IllumMinI:6:1)
else write(' huge.')
end
else
begin
if TrueIllum then
write(
100*FluxU/Flux:5:1,
LampFluxForce*IllumMax/(LumFluxDklm * sqr(Height)):7:1,
LampFluxForce*FluxU/(LumFluxDklm * sqr(Height))/((xh-xl)*(yh-yl)):6:1,
LampFluxForce*IllumMin/(LumFluxDklm * sqr(Height)):5:1)
else
write(
100*FluxU/Flux:5:1,
IllumMax/LumFluxDklm:7:1,
FluxU/LumFluxDklm/((xh-xl)*(yh-yl)):6:1,
IllumMin/LumFluxDklm:5:1);
if IllumMin/LumFluxDklm>0.1 then write(
FluxU/((xh-xl)*(yh-yl))/IllumMin:6:1)
else write(' huge.');
end;
writeln(' ',InpFi);
halt
end {of LineOnly, which exited the programme}
else
write(
'# Source file: ',InpFi,cl,
'# Luminaire flux =',Flux:6:0);
if PrFiel[3]<>1 then
writeln(' raw, for the given bulb(s) it would be',
Flux*PrFiel[3]:6:0,ZeroCandMult,' lm,')
else writeln(' lm,');
writeln(
'# ',Flux/LumFluxDklm/10:6:1,' % of the bulb flux',cl,
'# between 75 and 90: ',100*FluxGlare/Flux:4:1,' % of the luminaire flux',cl,
'# - this part causes just GLARE in case of road lighting and similar purposes',cl,
'# 80deg and above: max',MaxLumInt80:6:1,QM8,'cd / 1000 lm ,',
100*Flux80/Flux:5:1,' % of the luminaire flux', cl,
'# 90deg and above: max',MaxLumInt90:6:1,QM9,'cd / 1000 lm ,',
100*Flux90/Flux:5:1,QMM,'% of the luminaire flux',cl,
'# CutOff Type: ',CutoffType[CT],cl);
if CT>1 then
writeln(
'# Increase of Sky Luminance due to light going',cl,
'# from the luminaire difectly above horizon, as compared with the',cl,
'# luminance produced by the light dispersed from the ground:',
{100*FluxDown/((Flux-FluxDown)*Albedo*LambDown):4:0,QMM,'%',cl,}
{queer, Flux90 should be here and elsewhere
instead of FluxDown? For globes, there is a difference
-- this error was present before Oct 18, 2002}
{'# no, this is more accurate:',}
100*FluxDown/((Flux-Flux90)*Albedo*LambDown):4:0,QMM,'%',cl,
'# Increase of Sky Luminance in Distant Places by light below',
LowAngle:5:1,' degrees',cl,
'# due to light going from the luminaire directly above horizon:',
100*FluxDownLow/((Flux-Flux90)*Albedo*LambDownLow):4:0,QMM,'%',cl,
'# (for the zenith luminance such an angle suits places up to',
5/sin(LowAngle*D2r):4:0,' km distance)',cl,
'# The increases concern the following situation:',cl,
'# Albedo =', Albedo:5:2,cl,
'# Zenith Extinction =', ZenExt:5:2,' mag',
' (i.e., direct light remaining', 100/exp(LnM*ZenExt):4:0,' %)',cl,
'# Indicatrix type =', Sky:1,' (0: acc. to P.Cinzano, 4..6: CIE sky types)',cl,
'# (the downward-scattered part of lambertian uplight is',
LambDown:7:4, ' then)',cl);
writeln(
'# 62.5 deg to <67.5 deg: max',MaxLumInt65:6:0,' cd / 1000 lm,',cl,
'# 67.5 deg to < 76 deg: max',MaxLumInt70:6:0,' cd / 1000 lm,',cl,
'# maximum spec. lum. intensity',MaxLumInt:6:0,' cd / 1000 lm',cl);
if CalcUseful then
begin
write(
'# Illumination of a rectangle of ',
xl:3:1,':',xh:3:1,':',yl:3:1,':',yh:3:1,' pole heights');
if rotA then writeln(cl,
'# to which the luminaire is rotated by', rotAvert:6:1,' degrees around vertical:')
else writeln(':');
if MakeLogImage then {write perhaps a bit better estimate...}
begin
if Continuous then
write(
'# A row of luminaires is spaced ',1.0*radH/Hpix:4:2,' pole heights;',cl,
'# just luminaires closer than ', 2*Hpix2c,' pole heights are considered.',cl,
'# Grid is the same as for the illuminance plot, 1 point each 1/',Hpix,' pole height.',cl2,
'# Per cent of luminaires output to a row of such rectangles:')
else
write(
'# Grid is the same as for the illuminance plot, 1 point each 1/',Hpix,' pole height.',cl2,
'# Per cent of luminaire output falling there:');
write(
100*(FluxUI*LumFluxDklm/sqr(Hpix))/Flux:7:1,cl);
if TrueIllum then
write(
'# For the given case (glass at ',Height:4:1,' m height, ',
LampFluxForce*1000:5:0,' lm light source), the illuminances:',cl)
else
write(
'# For a unit case (glass at 1 m height, 1000 lm bulb), the illuminances:',cl);
write(
'# Maximum: ', IllumMaxI:7:1,' lx',cl,
'# Average: ', FluxUI/FluxUIn:7:1,' lx',cl,
'# Minimum: ', IllumMinI:7:1,' lx',cl);
if IllumMinI>0.1 then writeln(
'# Average/Minimum: ',FluxUI/FluxUIn/IllumMinI:6:1,cl)
else writeln(' huge.')
end
else {not MakeLogImage, simpler computation}
begin
write(
'# Just those tabelled specific iluminances are used whose rays hit the rectangle,',cl,
'# the average is per ray rather than per area; at rectangle margins, a strip of',cl,
'# +- ',t:4:2,' pole heights is included with a half weight');
if TooLong then write(';',cl,
'# just hits within',PolesAt80:5:2,
' pole heights (< 80 degrees from nadir) are included.',cl2)
else
write('.',cl2);
if not TrueIllum then
write(
'# Per cent of luminaire output falling there:', 100*FluxU/Flux:7:1,cl,
'# For a unit case (glass at 1 m height, 1000 lm bulb), the illuminances:',cl,
'# Maximum: ', IllumMax/LumFluxDklm:7:1,' lx',cl,
'# Average: ', FluxU/LumFluxDklm/((xh-xl)*(yh-yl)):7:1,' lx',cl,
'# Minimum: ', IllumMin/LumFluxDklm:7:1,' lx',cl)
else
write(
'# Per cent of luminaire output falling there:', 100*FluxU/Flux:7:1,cl,
'# For the given case (glass at ',Height:4:1,' m height, ',
LampFluxForce*1000:5:0,' lm light source), the illuminances:',cl,
'# Maximum: ',
LampFluxForce*IllumMax/(LumFluxDklm * sqr(Height)):7:1,' lx',cl,
'# Average: ',
LampFluxForce*FluxU/(LumFluxDklm * sqr(Height))/((xh-xl)*(yh-yl)):6:1,' lx',cl,
'# Minimum: ',
LampFluxForce*IllumMin/(LumFluxDklm * sqr(Height)):6:1,' lx',cl);
if IllumMin/LumFluxDklm>0.1 then writeln(
'# Average/Minimum: ',FluxU/((xh-xl)*(yh-yl))/IllumMin:6:1,cl)
else writeln(cl);
end
end;
writeln(
'# The following table gives luminous intensities which would be produced',cl,
'# using a hypothetic bulb giving a luminous flux of 1000 lm (i.e., cd/klm):',cl);
if HoriAngCount>1 then
begin
write('# H:'); for i:=1 to HoriAngCount do write(HoriAng[i]:6:1); writeln;
write('#V: '); writeln;
end;
for j:=1 to VertAngCount do
begin
write(VertAng[j]/AngUnit:5:1);
for i:=1 to HoriAngCount do
begin
x:=LumInt[i,j]/LumFluxDklm;
if x<100 then
write(x:6:1)
else
write(x:6:0);
end;
writeln;
end;
end.