Class: PhotoUtils::Scene
- Inherits:
-
Object
- Object
- PhotoUtils::Scene
- Defined in:
- lib/photo_utils/scene.rb
Instance Attribute Summary collapse
-
#background_distance ⇒ Object
Returns the value of attribute background_distance.
-
#brightness ⇒ Object
Returns the value of attribute brightness.
-
#camera ⇒ Object
Returns the value of attribute camera.
-
#description ⇒ Object
Returns the value of attribute description.
-
#sensitivity ⇒ Object
Returns the value of attribute sensitivity.
-
#subject_distance ⇒ Object
Returns the value of attribute subject_distance.
Instance Method Summary collapse
- #absolute_aperture ⇒ Object
- #aperture_for_depth_of_field(near_limit, far_limit) ⇒ Object
- #blur_at_distance(d) ⇒ Object
- #circle_of_confusion ⇒ Object
- #depth_of_field ⇒ Object
- #exposure ⇒ Object
- #far_distance_from_subject ⇒ Object
- #field_of_view(distance) ⇒ Object
- #hyperfocal_distance ⇒ Object
-
#initialize ⇒ Scene
constructor
A new instance of Scene.
- #magnification ⇒ Object
- #near_distance_from_subject ⇒ Object
- #print(io = STDOUT) ⇒ Object
- #print_camera(io = STDOUT) ⇒ Object
- #print_depth_of_field(io = STDOUT) ⇒ Object
- #print_exposure(io = STDOUT) ⇒ Object
- #set_exposure ⇒ Object
- #subject_distance_for_field_of_view(fov) ⇒ Object
- #total_depth_of_field ⇒ Object
-
#working_aperture ⇒ Object
AKA bellows factor.
Constructor Details
#initialize ⇒ Scene
Returns a new instance of Scene.
12 13 14 15 16 17 18 |
# File 'lib/photo_utils/scene.rb', line 12 def initialize { background_distance: Math::Infinity, sensitivity: 100, brightness: 100, }.each { |k, v| send("#{k}=", v) } end |
Instance Attribute Details
#background_distance ⇒ Object
Returns the value of attribute background_distance.
7 8 9 |
# File 'lib/photo_utils/scene.rb', line 7 def background_distance @background_distance end |
#brightness ⇒ Object
Returns the value of attribute brightness.
10 11 12 |
# File 'lib/photo_utils/scene.rb', line 10 def brightness @brightness end |
#camera ⇒ Object
Returns the value of attribute camera.
8 9 10 |
# File 'lib/photo_utils/scene.rb', line 8 def camera @camera end |
#description ⇒ Object
Returns the value of attribute description.
5 6 7 |
# File 'lib/photo_utils/scene.rb', line 5 def description @description end |
#sensitivity ⇒ Object
Returns the value of attribute sensitivity.
9 10 11 |
# File 'lib/photo_utils/scene.rb', line 9 def sensitivity @sensitivity end |
#subject_distance ⇒ Object
Returns the value of attribute subject_distance.
6 7 8 |
# File 'lib/photo_utils/scene.rb', line 6 def subject_distance @subject_distance end |
Instance Method Details
#absolute_aperture ⇒ Object
120 121 122 |
# File 'lib/photo_utils/scene.rb', line 120 def absolute_aperture @camera.lens.aperture.absolute(@camera.lens.focal_length) end |
#aperture_for_depth_of_field(near_limit, far_limit) ⇒ Object
41 42 43 44 |
# File 'lib/photo_utils/scene.rb', line 41 def aperture_for_depth_of_field(near_limit, far_limit) a = ((@camera.lens.focal_length ** 2) / circle_of_confusion) * ((far_limit - near_limit) / (2 * near_limit * far_limit)) Aperture.new(a) end |
#blur_at_distance(d) ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/photo_utils/scene.rb', line 107 def blur_at_distance(d) # http://en.wikipedia.org/wiki/Depth_of_field#Foreground_and_background_blur xd = (d - subject_distance).abs b = (@camera.lens.focal_length * magnification) / @camera.lens.aperture if d < subject_distance b *= xd / (subject_distance - xd) else b *= xd / (subject_distance + xd) end # diameter of blur disk, in mm Length.new(b.mm) end |
#circle_of_confusion ⇒ Object
36 37 38 39 |
# File 'lib/photo_utils/scene.rb', line 36 def circle_of_confusion # http://en.wikipedia.org/wiki/Circle_of_confusion @camera.format.frame.diagonal / 1750 end |
#depth_of_field ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/photo_utils/scene.rb', line 54 def depth_of_field h = hyperfocal_distance s = subject_distance dof = HashStruct.new dof.near = (h * s) / (h + s) if s < h dof.far = (h * s) / (h - s) else dof.far = Math::Infinity end dof.near = Length.new(dof.near) dof.far = Length.new(dof.far) dof end |
#exposure ⇒ Object
124 125 126 127 128 129 130 |
# File 'lib/photo_utils/scene.rb', line 124 def exposure Exposure.new( light: @brightness, sensitivity: @sensitivity, aperture: @camera.lens.aperture, time: @camera.shutter) end |
#far_distance_from_subject ⇒ Object
74 75 76 77 |
# File 'lib/photo_utils/scene.rb', line 74 def far_distance_from_subject d = (depth_of_field.far == Math::Infinity) ? Math::Infinity : (depth_of_field.far - subject_distance) Length.new(d) end |
#field_of_view(distance) ⇒ Object
84 85 86 87 |
# File 'lib/photo_utils/scene.rb', line 84 def field_of_view(distance) raise "Need focal length and format size to determine field of view" unless @camera.lens.focal_length && @camera.format @camera.format.field_of_view(@camera.lens.focal_length, distance) end |
#hyperfocal_distance ⇒ Object
46 47 48 49 50 51 52 |
# File 'lib/photo_utils/scene.rb', line 46 def hyperfocal_distance # http://en.wikipedia.org/wiki/Hyperfocal_distance raise "Need focal length, aperture, and circle of confusion to determine hyperfocal distance" \ unless @camera.lens.focal_length && @camera.lens.aperture && circle_of_confusion h = ((@camera.lens.focal_length ** 2) / (@camera.lens.aperture * circle_of_confusion)) + @camera.lens.focal_length Length.new(h) end |
#magnification ⇒ Object
89 90 91 92 |
# File 'lib/photo_utils/scene.rb', line 89 def magnification # http://en.wikipedia.org/wiki/Depth_of_field#Hyperfocal_magnification @camera.lens.focal_length / (subject_distance - @camera.lens.focal_length) end |
#near_distance_from_subject ⇒ Object
69 70 71 72 |
# File 'lib/photo_utils/scene.rb', line 69 def near_distance_from_subject d = subject_distance - depth_of_field.near Length.new(d) end |
#print(io = STDOUT) ⇒ Object
173 174 175 176 |
# File 'lib/photo_utils/scene.rb', line 173 def print(io=STDOUT) print_depth_of_field(io) print_exposure(io) end |
#print_camera(io = STDOUT) ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/photo_utils/scene.rb', line 138 def print_camera(io=STDOUT) io.puts "CAMERA:" io.puts " name: #{@camera.name}" io.puts " format: #{@camera.format} (35mm crop factor: #{@camera.format.crop_factor.format(10)})" io.puts " shutter range: #{@camera.max_shutter} ~ #{@camera.min_shutter}" io.puts " aperture range: #{@camera.lens.max_aperture} ~ #{@camera.lens.min_aperture}" io.puts " lens: #{@camera.lens.name} - #{@camera.lens.focal_length} (#{ %w{35 6x4.5 6x6 6x7 5x7}.map { |f| "#{f}: #{@camera.format.focal_length_equivalent(@camera.lens.focal_length, Format[f])}" }.join(', ') })" io.puts " angle of view: #{@camera.angle_of_view}" io.puts " shutter: #{@camera.shutter}" io.puts " aperture: #{@camera.lens.aperture}" io.puts end |
#print_depth_of_field(io = STDOUT) ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/photo_utils/scene.rb', line 157 def print_depth_of_field(io=STDOUT) io.puts "FIELD:" io.puts " subject dist: #{subject_distance.to_s(:imperial)}" io.puts " subject FOV: #{field_of_view(subject_distance).to_s(:imperial)}" io.puts " subject mag: #{'%.2f' % magnification}x" io.puts " subject DOF: #{total_depth_of_field.to_s(:imperial)} (-#{near_distance_from_subject.to_s(:imperial)}/+#{far_distance_from_subject.to_s(:imperial)})" io.puts " background dist: #{background_distance.to_s(:imperial)}" if background_distance != Math::Infinity io.puts " background FOV: #{field_of_view(background_distance).to_s(:imperial)}" io.puts " background blur: #{blur_at_distance(background_distance).to_s(:metric)}" end io.puts " hyperfocal dist: #{hyperfocal_distance.to_s(:imperial)}" io.puts " working aperture: #{working_aperture}" io.puts end |
#print_exposure(io = STDOUT) ⇒ Object
153 154 155 |
# File 'lib/photo_utils/scene.rb', line 153 def print_exposure(io=STDOUT) exposure.print(io) end |
#set_exposure ⇒ Object
132 133 134 135 136 |
# File 'lib/photo_utils/scene.rb', line 132 def set_exposure exp = exposure @camera.lens.aperture = exp.aperture @camera.shutter = exp.time end |
#subject_distance_for_field_of_view(fov) ⇒ Object
94 95 96 97 98 |
# File 'lib/photo_utils/scene.rb', line 94 def subject_distance_for_field_of_view(fov) d_w = fov.width / @camera.format.frame.width * @camera.lens.focal_length d_h = fov.height / @camera.format.frame.height * @camera.lens.focal_length [d_w, d_h].max end |
#total_depth_of_field ⇒ Object
79 80 81 82 |
# File 'lib/photo_utils/scene.rb', line 79 def total_depth_of_field d = (depth_of_field.far == Math::Infinity) ? Math::Infinity : (depth_of_field.far - depth_of_field.near) Length.new(d) end |
#working_aperture ⇒ Object
AKA bellows factor
102 103 104 105 |
# File 'lib/photo_utils/scene.rb', line 102 def working_aperture # http://en.wikipedia.org/wiki/F-number#Working_f-number Aperture.new((1 - magnification) * @camera.lens.aperture) end |