Difference between revisions of "Photography exposure"
(→Source code) |
(→Source code) |
||
(32 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | |||
{{Infobox_general | {{Infobox_general | ||
| name = Photography exposure | | name = Photography exposure | ||
Line 8: | Line 7: | ||
== Theory and background == | == Theory and background == | ||
+ | This example illustrates how exposure in photography depends on factors: latitude, time of day, day of year, weather, composition. It relates these to camera settings: film speed (e.g. ISO 100), aperture and shutter speed. The mathematical approach and model is taken from book written by V. Setälä.<ref name="setala"> Vilho Setälä: "Valokuvaus", Otava 1940.</ref> This book illustrates the approach as nomographs but they are different compared with the one generetated here. Book uses shadow length, but we break shadow length into | ||
+ | time, date and latitude via solar zenith angle. | ||
+ | |||
+ | The basic equation in Setälä<ref name="setala">a</ref>(pp.492-494) can be extracted and written as | ||
+ | |||
+ | <math>FS-L-A-W+C+T=0 \,</math>, | ||
+ | |||
+ | where | ||
+ | {| style="background:wihte; color:black" border="1" cellpadding="5" cellspacing="0" | ||
+ | |- | ||
+ | | <math>FS\,</math> || Film speed || DIN value that equals <math>10 \log (S) +1 \, </math>,where S is ISO FILM speed | ||
+ | |- | ||
+ | | <math>T\,</math> || shutter time || <math>10 \log \left( \frac{t}{1/10}\right) </math> | ||
+ | |- | ||
+ | | <math>A\,</math> || aperture || <math> 10 \log \left(\frac{N^2}{3.2^2}\right)</math> | ||
+ | |- | ||
+ | | <math>L\,</math> || shadow length (in steps) || two times (shadow length)/(person length) <math> = 2 \arctan ( \phi) \,</math>, where <math>\phi \,</math> is solar zenith angle. | ||
+ | |- | ||
+ | | <math>W\,</math> || weather || | ||
+ | {| style="background:white; color:black; margin: 1em auto 1em auto" border="1" cellpadding="5" cellspacing="0" | ||
+ | |- | ||
+ | |Clear sky, Cumulus clouds || 0 | ||
+ | |- | ||
+ | |Clear sky || 1 | ||
+ | |- | ||
+ | |Sun through clouds || 3 | ||
+ | |- | ||
+ | |Sky light gray || 6 | ||
+ | |- | ||
+ | |Sky dark gray || 9 | ||
+ | |- | ||
+ | |Thunder-clouds cover sky || 12 | ||
+ | |} | ||
+ | |- | ||
+ | | <math>C\,</math> || composition || | ||
+ | {| style="background:white; color:black; margin: 1em auto 1em auto" border="1" cellpadding="5" cellspacing="0" | ||
+ | |- | ||
+ | |Person under trees || -6 | ||
+ | |- | ||
+ | |Inside forest || -4 | ||
+ | |- | ||
+ | |Person in shadow of wall || -1 | ||
+ | |- | ||
+ | |Person at open place; alley under trees || 2 | ||
+ | |- | ||
+ | |Buildings; street || 5 | ||
+ | |- | ||
+ | |Landscape and front matter || 7 | ||
+ | |- | ||
+ | |Open landscape || 9 | ||
+ | |- | ||
+ | |Snow landscape and front matter; beach || 11 | ||
+ | |- | ||
+ | |Snow field; open sea || 13 | ||
+ | |- | ||
+ | |Clouds || 15 | ||
+ | |} | ||
+ | |} | ||
+ | It is to be noted that Setälä has stops ten times base-10 logarithmic. Today we think stops in base-2 logarithmic. | ||
+ | |||
+ | ==== Shadow lenght ==== | ||
+ | Calculation of shadow length as a function of day of year, time of day and latitude is according to <ref>http://www.srrb.noaa.gov/highlights/sunrise/solareqns.PDF</ref>. Following equations are used. For fractional year (without time information) we take | ||
+ | |||
+ | <math> \gamma = (day-1+0.5)2\pi/365. \,</math> | ||
+ | |||
+ | For time offset (eqtime) we use equation (in minutes) | ||
+ | |||
+ | <math> TO = 229.18(0.000075+0.001868\cos(\gamma)-0.032077\sin(´\gamma)-0.014615\cos(2\gamma)-0.040849\sin(2\gamma)) \,</math> | ||
+ | |||
+ | to calculate that error is below 17 minutes for time axis. We assume that sun is at heightest point at noon and this is the error and approximation. We calculate stops in logarithmic scale and in this case we do not need very accurate equations for time. For declination we use equation | ||
+ | |||
+ | <math> D=0.006918-0.399912\cos(\gamma)+0.070257\sin(\gamma)-0.006758\cos(2\gamma)+0.000907\sin(2\gamma)-0.002697\cos(3\gamma)+0.00148\sin(3\gamma).\,</math> | ||
+ | |||
+ | Hour angle is | ||
+ | |||
+ | <math>ha=(60h+\overline{TO})/4-180. \,</math>. | ||
+ | |||
+ | Finally solar zenith angle (<math>\phi \,</math>), latitude (LAT), declination (D) and hour angle (ha) are connected with equation: | ||
+ | |||
+ | <math> \cos (\phi ) = \sin(LAT)sin(D)+\cos(LAT)\cos(D)\cos(ha). \,</math> | ||
+ | |||
+ | This is in our desired form as a function of hour (h), day (day), latitude (LAT), solar zenith angle (<math>\phi \,</math>): | ||
+ | |||
+ | <math> \cos (\phi ) = \sin(LAT)sin(D(\gamma(day)))+\cos(LAT)\cos(D(\gamma(day)))\cos(ha(h)) \,</math>. | ||
+ | |||
+ | In practice illuminance of flat surface on earth depends on solar zenith angle as <math>\cos(\phi)\,</math>. Setälä<ref name="setala">a</ref> uses shadow length that is easily measurable, but scales incorrectly, as value is propotional to | ||
+ | <math>\tan(\phi)\,</math>. Also Setälä<ref name="setala">a</ref> sums linear value with logarithmic ones as a practical approximation. | ||
+ | To correct these assumptions, I assume that | ||
+ | values for shadow length 1 and 10 for Setälä are reasonable, and I find equation that scales logarithmically. I find | ||
+ | equation: | ||
+ | |||
+ | <math> L = 0.33766 - 13.656 \log10 (\cos(\phi)) \,</math> | ||
+ | |||
+ | that gives | ||
+ | |||
+ | <math>L=1\,</math> | ||
+ | |||
+ | for | ||
+ | |||
+ | <math>\phi = 26.565 =\arctan(1/2)\,</math> | ||
+ | |||
+ | and | ||
+ | |||
+ | <math>L=10\,</math> | ||
+ | |||
+ | for | ||
+ | |||
+ | <math>\phi = 78.69 =\arctan(10/2).\,</math> | ||
==== References ==== | ==== References ==== | ||
Line 13: | Line 120: | ||
== Construction of the nomograph == | == Construction of the nomograph == | ||
+ | The presented equation is the following: | ||
+ | <math>FS-\{0.33766 - 13.656 \log10 \left[\sin(LAT)sin(D(\gamma(day)))+\cos(LAT)\cos(D(\gamma(day)))\cos(ha(h))\right]\}-A-W+C+T=0 \,</math> | ||
+ | |||
+ | In order to construct the nomograph, we split equation into four blocks and an additional block to present values as EV100. The equations are presented in the following table. | ||
+ | |||
+ | {| style="background:white; color:black" border="1" cellpadding="5" cellspacing="0" | ||
+ | |- | ||
+ | | <math>x_1 \equiv \cos(\phi)=\sin(LAT)sin(D(\gamma(day)))+\cos(LAT)\cos(D(\gamma(day)))\cos(ha(h))\,</math> | ||
+ | |||
+ | formed into determinant | ||
+ | |||
+ | <math> | ||
+ | \begin{vmatrix} | ||
+ | 0 & \cos(\phi) & 1\\ | ||
+ | \frac{\cos(LAT)\cos(D(\gamma(day)))}{1+(\cos(LAT)\cos(D(\gamma(day))))} & \frac{\sin(LAT)\sin(D(\gamma(day)))}{1+(\cos(LAT)\cos(D(\gamma(day))))} &1\\ | ||
+ | 1 & -\cos(ha(h)) &1 \\ | ||
+ | |||
+ | \end{vmatrix} | ||
+ | =0. | ||
+ | </math> | ||
+ | |||
+ | || [[type 9]] | ||
+ | |- | ||
+ | | <math>C_1 \equiv L+W = 0.006918-13.656 \log_{10}(x_1)+W \,</math> | ||
+ | |||
+ | split into two equations for contour construction: | ||
+ | |||
+ | <math>y_1 = C_1 \,</math> | ||
+ | |||
+ | <math>y_1 = 0.006918-13.656 \log_{10}(x_1)+W \,</math> | ||
+ | |||
+ | || [[type 5]] | ||
+ | |||
+ | |- | ||
+ | | <math>C_2 \equiv L+W+C = C_1+C \,</math> | ||
+ | |||
+ | split into two equations for contour construction: | ||
+ | |||
+ | <math>y_2 = C_2 \,</math> | ||
+ | |||
+ | <math>y_2 = C_1+C \,</math> | ||
+ | |||
+ | || [[type 5]] | ||
+ | |||
+ | |- | ||
+ | | <math>C_2 = FS-A+T \,</math> | ||
+ | |||
+ | equals | ||
+ | |||
+ | <math> C_2 -(10 \log_{10}(S)+1.0)+10 \log_{10}\left(\frac{N^2}{3.2^2} \right)-10 \log_{10}\left( \frac{1/t_i}{1/10}\right)=0, \,</math> | ||
+ | |||
+ | where <math>t_i\equiv 1/t \,</math> is inverse shutter time. | ||
+ | |||
+ | || [[type 3]] | ||
+ | |||
+ | |- | ||
+ | |Additional EV100 scale by using relation | ||
+ | |||
+ | <math> C_2 =(-EV_{100}+13.654)/0.3322 \,</math> | ||
+ | |||
+ | || [[type 8]] | ||
+ | |||
+ | |- | ||
+ | | Maximum focal length calculator according to equation | ||
+ | |||
+ | <math> t_i / f = FL \,</math> | ||
+ | |||
+ | written as | ||
+ | |||
+ | <math>-10 \log_{10}\left( \frac{1/t_i}{1/10}\right)-10 \log_{10}\left( \frac{f}{10} \right) -10 \log_{10}\left( FL \right)=0\,</math> | ||
+ | |||
+ | in order to align correctly with previous equation. The values for the factor <math>f\,</math>are: | ||
+ | {| style="background:white; color:black; margin: 1em auto 1em auto" border="1" cellpadding="5" cellspacing="0" | ||
+ | |- | ||
+ | | '''Sensor type, image stabilization''' || <math>f\,</math> | ||
+ | |- | ||
+ | |- | ||
+ | | DSLR || 3/2 | ||
+ | |- | ||
+ | | 35mm || 1 | ||
+ | |- | ||
+ | | DSLR image stabilization || 3/8 | ||
+ | |- | ||
+ | | 35mm image stabilization || 1/8 | ||
+ | |- | ||
+ | |} | ||
+ | || [[type 1]] | ||
+ | |||
+ | |- | ||
+ | |} | ||
== Generated nomograph == | == Generated nomograph == | ||
{{Infobox_nomogram1 | {{Infobox_nomogram1 | ||
− | | name = | + | | name = Photography exposure |
| image = [[Image:ex_photo_exposure.png]] | | image = [[Image:ex_photo_exposure.png]] | ||
| file = [[Image:ex_photo_exposure.pdf]] | | file = [[Image:ex_photo_exposure.pdf]] | ||
}} | }} | ||
+ | See an [[Basics#Example2|example]] how to use this nomograph. | ||
== Source code == | == Source code == | ||
Line 28: | Line 226: | ||
Photgraph exposure. | Photgraph exposure. | ||
− | Copyright (C) 2007- | + | Copyright (C) 2007-2009 Leif Roschier |
This program is free software: you can redistribute it and/or modify | This program is free software: you can redistribute it and/or modify | ||
Line 43: | Line 241: | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
""" | """ | ||
− | from nomographer import * | + | from pynomo.nomographer import * |
""" | """ | ||
functions for solartime taken from solareqns.pdf from | functions for solartime taken from solareqns.pdf from | ||
Line 57: | Line 255: | ||
-0.014615*cos(2*gamma0)-0.040849*sin(2*gamma0)) | -0.014615*cos(2*gamma0)-0.040849*sin(2*gamma0)) | ||
− | # mean correction, with constant correction we make less than | + | # mean correction, with constant correction we make less than 17 minutes error |
# in time axis | # in time axis | ||
− | temp_a=arange(0, | + | temp_a=arange(0,365.0,0.1) |
temp_b=eq_time(temp_a) | temp_b=eq_time(temp_a) | ||
− | correction=mean(temp_b) # this is | + | correction=mean(temp_b) # this is 0.0171885 minutes |
+ | #print "maximum time errors: %g %g"%(min(temp_b),max(temp_b)) | ||
# declination | # declination | ||
Line 94: | Line 293: | ||
#times=linspace(0,350,10) | #times=linspace(0,350,10) | ||
− | times=arange(0.0,360.0,10.0,dtype=double).tolist() | + | #times=arange(0.0,360.0,10.0,dtype=double).tolist() |
time_titles=['January','February','March','April','May','June', | time_titles=['January','February','March','April','May','June', | ||
'July','August','September','October','November','December'] | 'July','August','September','October','November','December'] | ||
− | |||
phi_params={ | phi_params={ | ||
Line 110: | Line 308: | ||
'title_x_shift':0.0, | 'title_x_shift':0.0, | ||
'title_y_shift':0.25, | 'title_y_shift':0.25, | ||
− | 'scale_type':'linear', | + | 'scale_type':'linear smart', |
− | 'tick_levels': | + | 'tick_levels':4, |
− | 'tick_text_levels': | + | 'tick_text_levels':2, |
'tick_side':'right', | 'tick_side':'right', | ||
'tag':'phi', | 'tag':'phi', | ||
'grid':False, | 'grid':False, | ||
− | + | # 'extra_params':[{'u_min':20.0, | |
− | + | # 'u_max':90.0, | |
− | + | # 'tick_levels':4, | |
− | + | # 'tick_text_levels':2, | |
− | + | # }] | |
} | } | ||
Line 179: | Line 377: | ||
'f3_params':time_params, | 'f3_params':time_params, | ||
'transform_ini':True, | 'transform_ini':True, | ||
+ | 'isopleth_values':[['x',[60,times1[4]],14.0]], | ||
} | } | ||
+ | # limiting functions are to avoid NaN in contour construction that uses optimization | ||
def limit_xx(x): | def limit_xx(x): | ||
x1=x | x1=x | ||
− | + | # if x1>1.0: # don't need in 0.2.2 | |
− | + | # x1=1.0 | |
− | + | # if x1<-1.0: | |
− | + | # x1=-1.0 | |
return x1 | return x1 | ||
def limit_x(x): | def limit_x(x): | ||
x1=x | x1=x | ||
− | + | # if not x1>0.0: # don't need in 0.2.2 | |
− | + | # x1=0.0001 | |
return x1 | return x1 | ||
Line 239: | Line 439: | ||
'u_tag':'AA', | 'u_tag':'AA', | ||
'horizontal_guides':True, | 'horizontal_guides':True, | ||
+ | 'isopleth_values':[['x',9.0,'x']], | ||
} | } | ||
Line 273: | Line 474: | ||
'horizontal_guides':True, | 'horizontal_guides':True, | ||
'u_align_y_offset':-0.9, | 'u_align_y_offset':-0.9, | ||
+ | 'isopleth_values':[['x',2.0,'x']], | ||
} | } | ||
Line 287: | Line 489: | ||
camera_params_2={ | camera_params_2={ | ||
'u_min':10.0, | 'u_min':10.0, | ||
− | 'u_max': | + | 'u_max':25600.0, |
'function':lambda S:-(10*log10(S)+1.0), | 'function':lambda S:-(10*log10(S)+1.0), | ||
'title':r'Film speed', | 'title':r'Film speed', | ||
Line 302: | Line 504: | ||
6400.0:'ISO 6400', | 6400.0:'ISO 6400', | ||
12800.0:'ISO 12800', | 12800.0:'ISO 12800', | ||
+ | 25600.0:'ISO 25600', | ||
}, | }, | ||
'scale_type':'manual line' | 'scale_type':'manual line' | ||
Line 338: | Line 541: | ||
'scale_type':'manual line', | 'scale_type':'manual line', | ||
'title':r't (s)', | 'title':r't (s)', | ||
− | 'text_format':r"1/%3.0f s" | + | 'text_format':r"1/%3.0f s", |
+ | 'tag':'shutter', | ||
+ | 'tick_side':'left', | ||
} | } | ||
− | + | ||
camera_params_4={ | camera_params_4={ | ||
'u_min':1.0, | 'u_min':1.0, | ||
'u_max':22.0, | 'u_max':22.0, | ||
'function':lambda N:10*log10((N/3.2)**2)+30, | 'function':lambda N:10*log10((N/3.2)**2)+30, | ||
− | 'manual_axis_data': {1.0:'f/1', | + | 'manual_axis_data': {1.0:'$f$/1', |
− | 1.2:'f/1.2', | + | 1.2:'$f$/1.2', |
− | 1.4:'f/1.4', | + | 1.4:'$f$/1.4', |
− | 1.7:'f/1.7', | + | 1.7:'$f$/1.7', |
− | 2.0:'f/2', | + | 2.0:'$f$/2', |
− | 2.4:'f/2.4', | + | 2.4:'$f$/2.4', |
− | 2.8:'f/2.8', | + | 2.8:'$f$/2.8', |
− | 3.3:'f/3.3', | + | 3.3:'$f$/3.3', |
− | 4.0:'f/4', | + | 4.0:'$f$/4', |
− | 4.8:'f/4.8', | + | 4.8:'$f$/4.8', |
− | 5.6:'f/5.6', | + | 5.6:'$f$/5.6', |
− | 6.7:'f/6.7', | + | 6.7:'$f$/6.7', |
− | 8.0:'f/8', | + | 8.0:'$f$/8', |
− | 9.5:'f/9.5', | + | 9.5:'$f$/9.5', |
− | 11.0:'f/11', | + | 11.0:'$f$/11', |
− | 13.0:'f/13', | + | 13.0:'$f$/13', |
− | 16.0:'f/16', | + | 16.0:'$f$/16', |
− | 19.0:'f/19', | + | 19.0:'$f$/19', |
− | 22.0:'f/22', | + | 22.0:'$f$/22', |
}, | }, | ||
'scale_type':'manual line', | 'scale_type':'manual line', | ||
Line 376: | Line 581: | ||
camera_params_4], | camera_params_4], | ||
'mirror_x':True, | 'mirror_x':True, | ||
+ | 'isopleth_values':[['x',100.0,'x',4.0]], | ||
} | } | ||
− | def old_EV(EV): | + | def old_EV(EV): # C2(EV100) in wiki |
return (-EV+13.654)/0.3322 | return (-EV+13.654)/0.3322 | ||
Line 395: | Line 601: | ||
EV_block={ | EV_block={ | ||
'block_type':'type_8', | 'block_type':'type_8', | ||
− | 'f_params':EV_para | + | 'f_params':EV_para, |
+ | 'isopleth_values':[['x']], | ||
} | } | ||
+ | |||
+ | # maximum focal length | ||
+ | FL_t_para={ | ||
+ | 'u_min':0.1, | ||
+ | 'u_max':10000.0, | ||
+ | 'function':lambda t:-10*log10((1.0/t)/(1.0/10.0))-30, | ||
+ | 'scale_type':'linear', | ||
+ | 'tick_levels':0, | ||
+ | 'tick_text_levels':0, | ||
+ | 'title':r't (s)', | ||
+ | 'text_format':r"1/%3.0f s", | ||
+ | 'tag':'shutter', | ||
+ | } | ||
+ | |||
+ | FL_factor_params_2={ | ||
+ | 'u_min':1.0/4.0, | ||
+ | 'u_max':3.0/2.0, | ||
+ | 'function':lambda factor:-10*log10(factor/10.0)+0, | ||
+ | 'title':r'Sensor, IS', | ||
+ | 'scale_type':'manual point', | ||
+ | 'manual_axis_data': {1.0/(2.0/3.0):'DSLR', | ||
+ | 1.0/(1.0):'35mm', | ||
+ | 1.0/(8.0/3.0):'DSLR IS', | ||
+ | 1.0/(4.0):'35mm IS', | ||
+ | }, | ||
+ | 'tick_side':'left', | ||
+ | 'text_size_manual':text.size.footnotesize, # pyx directive | ||
+ | } | ||
+ | |||
+ | FL_fl_params={ | ||
+ | 'u_min':20.0, | ||
+ | 'u_max':1000.0, | ||
+ | 'function':lambda FL:-10*log10(FL)+30, | ||
+ | 'title':r'Max focal length', | ||
+ | 'tick_levels':3, | ||
+ | 'tick_text_levels':2, | ||
+ | 'tick_side':'left', | ||
+ | 'scale_type':'manual line', | ||
+ | 'manual_axis_data': {20.0:'20mm', | ||
+ | 35.0:'35mm', | ||
+ | 50.0:'50mm', | ||
+ | 80.0:'80mm', | ||
+ | 100.0:'100mm', | ||
+ | 150.0:'150mm', | ||
+ | 200.0:'200mm', | ||
+ | 300.0:'300mm', | ||
+ | 400.0:'400mm', | ||
+ | 500.0:'500mm', | ||
+ | 1000.0:'1000mm'} | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | FL_block_params={ | ||
+ | 'block_type':'type_1', | ||
+ | 'width':12.0, | ||
+ | 'height':10.0, | ||
+ | 'f1_params':FL_t_para, | ||
+ | 'f2_params':FL_factor_params_2, | ||
+ | 'f3_params':FL_fl_params, | ||
+ | 'mirror_x':True, | ||
+ | 'proportion':0.5, | ||
+ | 'isopleth_values':[['x',1.0/(8.0/3.0),'x']], | ||
+ | } | ||
main_params={ | main_params={ | ||
− | 'filename':'ex_photo_exposure.pdf', | + | 'filename':['ex_photo_exposure.pdf','ex_photo_exposure.eps'], |
'paper_height':35.0, | 'paper_height':35.0, | ||
'paper_width':35.0, | 'paper_width':35.0, | ||
− | 'block_params':[block_params,block_params_weather,block_params_scene,block_params_camera,EV_block], | + | 'block_params':[block_params,block_params_weather,block_params_scene,block_params_camera,EV_block,FL_block_params], |
− | #'block_params':[block_params_weather,block_params_scene,block_params_camera,EV_block], | + | #'block_params':[block_params_weather,block_params_scene,block_params_camera,EV_block,FL_block_params], |
'transformations':[('rotate',0.01),('scale paper',)], | 'transformations':[('rotate',0.01),('scale paper',)], | ||
'title_x': 7, | 'title_x': 7, | ||
'title_y': 34, | 'title_y': 34, | ||
'title_box_width': 10, | 'title_box_width': 10, | ||
− | 'title_str':r'Photography exposure (Setala 1940) \copyright Leif Roschier | + | 'title_str':r'\LARGE Photography exposure (Setala 1940) \par \copyright Leif Roschier 2009 ' |
} | } | ||
b=Nomographer(main_params) | b=Nomographer(main_params) | ||
</source> | </source> |
Latest revision as of 18:30, 21 October 2009
Photography exposure | |
![]() | |
author | Leif Roschier |
---|
Contents
Theory and background
This example illustrates how exposure in photography depends on factors: latitude, time of day, day of year, weather, composition. It relates these to camera settings: film speed (e.g. ISO 100), aperture and shutter speed. The mathematical approach and model is taken from book written by V. Setälä.[1] This book illustrates the approach as nomographs but they are different compared with the one generetated here. Book uses shadow length, but we break shadow length into time, date and latitude via solar zenith angle.
The basic equation in Setälä[1](pp.492-494) can be extracted and written as
[math]FS-L-A-W+C+T=0 \,[/math],
where
[math]FS\,[/math] | Film speed | DIN value that equals [math]10 \log (S) +1 \, [/math],where S is ISO FILM speed | ||||||||||||||||||||
[math]T\,[/math] | shutter time | [math]10 \log \left( \frac{t}{1/10}\right) [/math] | ||||||||||||||||||||
[math]A\,[/math] | aperture | [math] 10 \log \left(\frac{N^2}{3.2^2}\right)[/math] | ||||||||||||||||||||
[math]L\,[/math] | shadow length (in steps) | two times (shadow length)/(person length) [math] = 2 \arctan ( \phi) \,[/math], where [math]\phi \,[/math] is solar zenith angle. | ||||||||||||||||||||
[math]W\,[/math] | weather |
| ||||||||||||||||||||
[math]C\,[/math] | composition |
|
It is to be noted that Setälä has stops ten times base-10 logarithmic. Today we think stops in base-2 logarithmic.
Shadow lenght
Calculation of shadow length as a function of day of year, time of day and latitude is according to [2]. Following equations are used. For fractional year (without time information) we take
[math] \gamma = (day-1+0.5)2\pi/365. \,[/math]
For time offset (eqtime) we use equation (in minutes)
[math] TO = 229.18(0.000075+0.001868\cos(\gamma)-0.032077\sin(´\gamma)-0.014615\cos(2\gamma)-0.040849\sin(2\gamma)) \,[/math]
to calculate that error is below 17 minutes for time axis. We assume that sun is at heightest point at noon and this is the error and approximation. We calculate stops in logarithmic scale and in this case we do not need very accurate equations for time. For declination we use equation
[math] D=0.006918-0.399912\cos(\gamma)+0.070257\sin(\gamma)-0.006758\cos(2\gamma)+0.000907\sin(2\gamma)-0.002697\cos(3\gamma)+0.00148\sin(3\gamma).\,[/math]
Hour angle is
[math]ha=(60h+\overline{TO})/4-180. \,[/math].
Finally solar zenith angle ([math]\phi \,[/math]), latitude (LAT), declination (D) and hour angle (ha) are connected with equation:
[math] \cos (\phi ) = \sin(LAT)sin(D)+\cos(LAT)\cos(D)\cos(ha). \,[/math]
This is in our desired form as a function of hour (h), day (day), latitude (LAT), solar zenith angle ([math]\phi \,[/math]):
[math] \cos (\phi ) = \sin(LAT)sin(D(\gamma(day)))+\cos(LAT)\cos(D(\gamma(day)))\cos(ha(h)) \,[/math].
In practice illuminance of flat surface on earth depends on solar zenith angle as [math]\cos(\phi)\,[/math]. Setälä[1] uses shadow length that is easily measurable, but scales incorrectly, as value is propotional to [math]\tan(\phi)\,[/math]. Also Setälä[1] sums linear value with logarithmic ones as a practical approximation. To correct these assumptions, I assume that values for shadow length 1 and 10 for Setälä are reasonable, and I find equation that scales logarithmically. I find equation:
[math] L = 0.33766 - 13.656 \log10 (\cos(\phi)) \,[/math]
that gives
[math]L=1\,[/math]
for
[math]\phi = 26.565 =\arctan(1/2)\,[/math]
and
[math]L=10\,[/math]
for
[math]\phi = 78.69 =\arctan(10/2).\,[/math]
References
- ↑ 1.0 1.1 1.2 1.3 Vilho Setälä: "Valokuvaus", Otava 1940.
- ↑ http://www.srrb.noaa.gov/highlights/sunrise/solareqns.PDF
Construction of the nomograph
The presented equation is the following: [math]FS-\{0.33766 - 13.656 \log10 \left[\sin(LAT)sin(D(\gamma(day)))+\cos(LAT)\cos(D(\gamma(day)))\cos(ha(h))\right]\}-A-W+C+T=0 \,[/math]
In order to construct the nomograph, we split equation into four blocks and an additional block to present values as EV100. The equations are presented in the following table.
[math]x_1 \equiv \cos(\phi)=\sin(LAT)sin(D(\gamma(day)))+\cos(LAT)\cos(D(\gamma(day)))\cos(ha(h))\,[/math]
formed into determinant [math] \begin{vmatrix} 0 & \cos(\phi) & 1\\ \frac{\cos(LAT)\cos(D(\gamma(day)))}{1+(\cos(LAT)\cos(D(\gamma(day))))} & \frac{\sin(LAT)\sin(D(\gamma(day)))}{1+(\cos(LAT)\cos(D(\gamma(day))))} &1\\ 1 & -\cos(ha(h)) &1 \\ \end{vmatrix} =0. [/math] |
type 9 | ||||||||||
[math]C_1 \equiv L+W = 0.006918-13.656 \log_{10}(x_1)+W \,[/math]
split into two equations for contour construction: [math]y_1 = C_1 \,[/math] [math]y_1 = 0.006918-13.656 \log_{10}(x_1)+W \,[/math] |
type 5 | ||||||||||
[math]C_2 \equiv L+W+C = C_1+C \,[/math]
split into two equations for contour construction: [math]y_2 = C_2 \,[/math] [math]y_2 = C_1+C \,[/math] |
type 5 | ||||||||||
[math]C_2 = FS-A+T \,[/math]
equals [math] C_2 -(10 \log_{10}(S)+1.0)+10 \log_{10}\left(\frac{N^2}{3.2^2} \right)-10 \log_{10}\left( \frac{1/t_i}{1/10}\right)=0, \,[/math] where [math]t_i\equiv 1/t \,[/math] is inverse shutter time. |
type 3 | ||||||||||
Additional EV100 scale by using relation
[math] C_2 =(-EV_{100}+13.654)/0.3322 \,[/math] |
type 8 | ||||||||||
Maximum focal length calculator according to equation
[math] t_i / f = FL \,[/math] written as [math]-10 \log_{10}\left( \frac{1/t_i}{1/10}\right)-10 \log_{10}\left( \frac{f}{10} \right) -10 \log_{10}\left( FL \right)=0\,[/math] in order to align correctly with previous equation. The values for the factor [math]f\,[/math]are:
|
type 1 |
Generated nomograph
Photography exposure | |
---|---|
![]() |
|
Generated portable document file (pdf): | File:Ex photo exposure.pdf |
See an example how to use this nomograph.
Source code
""" ex_photo_exposure.py Photgraph exposure. Copyright (C) 2007-2009 Leif Roschier This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. """ from pynomo.nomographer import * """ functions for solartime taken from solareqns.pdf from http://www.srrb.noaa.gov/highlights/sunrise/solareqns.PDF """ # fractional year def gamma(day): return 2*pi/365.0*(day-1+0.5) # equation of time def eq_time(day): gamma0=gamma(day) return 229.18*(0.000075+0.001868*cos(gamma0)-0.032077*sin(gamma0)\ -0.014615*cos(2*gamma0)-0.040849*sin(2*gamma0)) # mean correction, with constant correction we make less than 17 minutes error # in time axis temp_a=arange(0,365.0,0.1) temp_b=eq_time(temp_a) correction=mean(temp_b) # this is 0.0171885 minutes #print "maximum time errors: %g %g"%(min(temp_b),max(temp_b)) # declination def eq_declination(day): g0=gamma(day) return 0.006918-0.399912*cos(g0)+0.070257*sin(g0)-0.006758*cos(2*g0)\ +0.000907*sin(2*g0)-0.002697*cos(3*g0)+0.00148*sin(3*g0) def f1(dummy): return 0.0 def g1(fii): return cos(fii*pi/180.0) def f2(lat,day): dec=eq_declination(day) return (cos(lat*pi/180.0)*cos(dec))/(1.0+(cos(lat*pi/180.0)*cos(dec))) def g2(lat,day): dec=eq_declination(day) # in radians return (sin(lat*pi/180.0)*sin(dec))/(1.0+(cos(lat*pi/180.0)*cos(dec))) def f3(dummy): return 1 def g3(h): hr=(h*60.0+correction)/4.0-180.0 return -1.0*cos(hr*pi/180.0) days_in_month = (31,28,31,30,31,30,31,31,30,31,30,31) times1=[] for idx in range(0,12): times1.append(sum(days_in_month[0:idx])+1) #times=linspace(0,350,10) #times=arange(0.0,360.0,10.0,dtype=double).tolist() time_titles=['January','February','March','April','May','June', 'July','August','September','October','November','December'] phi_params={ 'u_min':0.0, 'u_max':90.0, 'u_min_trafo':0.0, 'u_max_trafo':90.0, 'f':f1, 'g':g1, 'h':lambda u:1.0, 'title':r'Solar zenith angle $\phi$', 'title_x_shift':0.0, 'title_y_shift':0.25, 'scale_type':'linear smart', 'tick_levels':4, 'tick_text_levels':2, 'tick_side':'right', 'tag':'phi', 'grid':False, # 'extra_params':[{'u_min':20.0, # 'u_max':90.0, # 'tick_levels':4, # 'tick_text_levels':2, # }] } time_params={ 'u_min':0.0, 'u_max':23.0, 'u_min_trafo':0.0, 'u_max_trafo':12.0, 'f':f3, 'g':g3, 'h':lambda u:1.0, 'title':r'Hour (h)', 'title_x_shift':0.0, 'title_y_shift':0.25, 'scale_type':'linear', 'tick_levels':2, 'tick_text_levels':1, 'tick_side':'right', 'tag':'none', 'grid':False, } lat_day_params={ 'ID':'none', # to identify the axis 'tag':'none', # for aligning block wrt others 'title':'Grid', 'title_x_shift':0.0, 'title_y_shift':0.25, 'title_distance_center':0.5, 'title_opposite_tick':True, 'u_min':20.0, # for alignment 'u_max':80.0, # for alignment 'f_grid':f2, 'g_grid':g2, 'h_grid':lambda u,v:1.0, 'u_start':30.0, 'u_stop':80.0, 'v_start':times1[0], # day 'v_stop':times1[-1], 'u_values':[30.0,40.0,50.0,60.0,70.0,80.0], 'u_texts':['30','40','50','Latitude = 60','70','80'], 'v_values':times1, 'v_texts':time_titles, 'grid':True, 'text_prefix_u':r'', 'text_prefix_v':r'', 'text_distance':0.5, 'v_texts_u_start':False, 'v_texts_u_stop':True, 'u_texts_v_start':False, 'u_texts_v_stop':True, } block_params={ 'block_type':'type_9', 'f1_params':phi_params, 'f2_params':lat_day_params, 'f3_params':time_params, 'transform_ini':True, 'isopleth_values':[['x',[60,times1[4]],14.0]], } # limiting functions are to avoid NaN in contour construction that uses optimization def limit_xx(x): x1=x # if x1>1.0: # don't need in 0.2.2 # x1=1.0 # if x1<-1.0: # x1=-1.0 return x1 def limit_x(x): x1=x # if not x1>0.0: # don't need in 0.2.2 # x1=0.0001 return x1 const_A=0.33766 const_B=-13.656 block_params_weather={ 'block_type':'type_5', 'u_func':lambda u:u, 'v_func':lambda x,v:const_A+const_B*log10(limit_x(x))+v, #'u_values':[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,15.0,20,25], 'u_values':[1.0,25.0], 'u_manual_axis_data':{1.0:'', 25.0:''}, 'v_values':[0.0,1.0,3.0,6.0,9.0,12.0], 'v_manual_axis_data': {0.0:['Clear sky, Cumulus clouds',{'x_corr':0.5, 'y_corr':0.0, 'draw_line':False}], 1.0:'Clear sky', 3.0:'Sun through clouds', 6.0:'Sky light gray', 9.0:'Sky dark gray', 12.0:'Thunder-clouds cover sky', }, 'v_text_distance':0.5, 'wd_tick_levels':0, 'wd_tick_text_levels':0, 'wd_tick_side':'right', 'wd_title':'', 'manual_x_scale':True, 'x_min':0.06, 'x_max':0.99, 'u_title':'', 'v_title':'', 'wd_title_opposite_tick':True, 'wd_title_distance_center':2.5, 'wd_align_func':lambda L:acos(limit_xx(10.0**((L-const_A)/const_B)))*180.0/pi, # phi as L 'wd_func':lambda L:10.0**((L-const_A)/const_B), # x as L 'wd_func_inv':lambda x:const_A+const_B*log10(x), # L as x 'wd_tag':'phi', 'mirror_y':True, 'mirror_x':False, 'width':10.0, 'height':10.0, 'u_scale_opposite':True, 'u_tag':'AA', 'horizontal_guides':True, 'isopleth_values':[['x',9.0,'x']], } block_params_scene={ 'block_type':'type_5', 'u_func':lambda u:u, 'v_func':lambda x,v:x+v, 'u_values':[1.0,25.0], 'u_manual_axis_data':{1.0:'', 25.0:''}, 'u_tag':'AA', 'wd_tag':'EV', 'v_values':[-4.0,-1.0,2.0,5.0,7.0,9.0,11.0,13.0,15.0], 'v_manual_axis_data': {-6.0:'Person under trees', -4.0:'Inside forest', -1.0:'Person in shadow of wall', 2.0:'Person at open place; alley under trees', 5.0:'Buildings; street', 7.0:'Landscape and front matter', 9.0:'Open landscape', 11.0:'Snow landscape and front matter; beach', 13.0:'Snow field; open sea', 15.0:'Clouds', }, 'wd_tick_levels':0, 'wd_tick_text_levels':0, 'wd_tick_side':'right', 'wd_title':'', 'u_title':'', 'v_title':'', 'wd_title_opposite_tick':True, 'wd_title_distance_center':2.5, 'mirror_x':True, 'horizontal_guides':True, 'u_align_y_offset':-0.9, 'isopleth_values':[['x',2.0,'x']], } camera_params_1={ 'u_min':-10.0, 'u_max':15.0, 'function':lambda u:u, 'title':r'', 'tick_levels':0, 'tick_text_levels':0, 'tag':'EV', } camera_params_2={ 'u_min':10.0, 'u_max':25600.0, 'function':lambda S:-(10*log10(S)+1.0), 'title':r'Film speed', 'manual_axis_data': {10.0:'ISO 10', 20.0:'ISO 20', #40.0:'ISO 40', 50.0:'ISO 50', 100.0:'ISO 100', 200.0:'ISO 200', 400.0:'ISO 400', 800.0:'ISO 800', 1600.0:'ISO 1600', 3200.0:'ISO 3200', 6400.0:'ISO 6400', 12800.0:'ISO 12800', 25600.0:'ISO 25600', }, 'scale_type':'manual line' } camera_params_3={ 'u_min':0.1, 'u_max':10000.0, 'function':lambda t:-10*log10((1.0/t)/(1.0/10.0))-30, 'manual_axis_data': {1/10.0:'10', 1/7.0:'7', 1/5.0:'5', 1/3.0:'3', 1/2.0:'2', 1.0:'1', 2.0:'1/2', 3.0:'1/3', 5.0:'1/5', 7.0:'1/7', 10.0:'1/10', 20.0:'1/20', 30.0:'1/30', 50.0:'1/50', 70.0:'1/70', 100.0:'1/100', 200.0:'1/200', 300.0:'1/300', 500.0:'1/500', 700.0:'1/700', 1000.0:'1/1000', 2000.0:'1/2000', 3000.0:'1/3000', 5000.0:'1/5000', 7000.0:'1/7000', 10000.0:'1/10000', }, 'scale_type':'manual line', 'title':r't (s)', 'text_format':r"1/%3.0f s", 'tag':'shutter', 'tick_side':'left', } camera_params_4={ 'u_min':1.0, 'u_max':22.0, 'function':lambda N:10*log10((N/3.2)**2)+30, 'manual_axis_data': {1.0:'$f$/1', 1.2:'$f$/1.2', 1.4:'$f$/1.4', 1.7:'$f$/1.7', 2.0:'$f$/2', 2.4:'$f$/2.4', 2.8:'$f$/2.8', 3.3:'$f$/3.3', 4.0:'$f$/4', 4.8:'$f$/4.8', 5.6:'$f$/5.6', 6.7:'$f$/6.7', 8.0:'$f$/8', 9.5:'$f$/9.5', 11.0:'$f$/11', 13.0:'$f$/13', 16.0:'$f$/16', 19.0:'$f$/19', 22.0:'$f$/22', }, 'scale_type':'manual line', 'title':r'Aperture', } block_params_camera={ 'block_type':'type_3', 'width':10.0, 'height':10.0, 'f_params':[camera_params_1,camera_params_2,camera_params_3, camera_params_4], 'mirror_x':True, 'isopleth_values':[['x',100.0,'x',4.0]], } def old_EV(EV): # C2(EV100) in wiki return (-EV+13.654)/0.3322 EV_para={ 'tag':'EV', 'u_min':4.0, 'u_max':19.0, 'function':lambda u:old_EV(u), 'title':r'EV$_{100}$', 'tick_levels':1, 'tick_text_levels':1, 'align_func':old_EV, 'title_x_shift':0.5, 'tick_side':'right', } EV_block={ 'block_type':'type_8', 'f_params':EV_para, 'isopleth_values':[['x']], } # maximum focal length FL_t_para={ 'u_min':0.1, 'u_max':10000.0, 'function':lambda t:-10*log10((1.0/t)/(1.0/10.0))-30, 'scale_type':'linear', 'tick_levels':0, 'tick_text_levels':0, 'title':r't (s)', 'text_format':r"1/%3.0f s", 'tag':'shutter', } FL_factor_params_2={ 'u_min':1.0/4.0, 'u_max':3.0/2.0, 'function':lambda factor:-10*log10(factor/10.0)+0, 'title':r'Sensor, IS', 'scale_type':'manual point', 'manual_axis_data': {1.0/(2.0/3.0):'DSLR', 1.0/(1.0):'35mm', 1.0/(8.0/3.0):'DSLR IS', 1.0/(4.0):'35mm IS', }, 'tick_side':'left', 'text_size_manual':text.size.footnotesize, # pyx directive } FL_fl_params={ 'u_min':20.0, 'u_max':1000.0, 'function':lambda FL:-10*log10(FL)+30, 'title':r'Max focal length', 'tick_levels':3, 'tick_text_levels':2, 'tick_side':'left', 'scale_type':'manual line', 'manual_axis_data': {20.0:'20mm', 35.0:'35mm', 50.0:'50mm', 80.0:'80mm', 100.0:'100mm', 150.0:'150mm', 200.0:'200mm', 300.0:'300mm', 400.0:'400mm', 500.0:'500mm', 1000.0:'1000mm'} } FL_block_params={ 'block_type':'type_1', 'width':12.0, 'height':10.0, 'f1_params':FL_t_para, 'f2_params':FL_factor_params_2, 'f3_params':FL_fl_params, 'mirror_x':True, 'proportion':0.5, 'isopleth_values':[['x',1.0/(8.0/3.0),'x']], } main_params={ 'filename':['ex_photo_exposure.pdf','ex_photo_exposure.eps'], 'paper_height':35.0, 'paper_width':35.0, 'block_params':[block_params,block_params_weather,block_params_scene,block_params_camera,EV_block,FL_block_params], #'block_params':[block_params_weather,block_params_scene,block_params_camera,EV_block,FL_block_params], 'transformations':[('rotate',0.01),('scale paper',)], 'title_x': 7, 'title_y': 34, 'title_box_width': 10, 'title_str':r'\LARGE Photography exposure (Setala 1940) \par \copyright Leif Roschier 2009 ' } b=Nomographer(main_params)