Class: PhotoUtils::SceneView
- Inherits:
-
Object
- Object
- PhotoUtils::SceneView
- Defined in:
- lib/photo_utils/scene_view.rb
Instance Attribute Summary collapse
-
#camera_height ⇒ Object
Returns the value of attribute camera_height.
-
#camera_width ⇒ Object
Returns the value of attribute camera_width.
-
#height ⇒ Object
Returns the value of attribute height.
-
#max_distance ⇒ Object
Returns the value of attribute max_distance.
-
#scale ⇒ Object
Returns the value of attribute scale.
-
#scene ⇒ Object
Returns the value of attribute scene.
-
#width ⇒ Object
Returns the value of attribute width.
Instance Method Summary collapse
- #draw_camera(xml) ⇒ Object
- #draw_dof(xml) ⇒ Object
- #draw_hyperfocal(xml) ⇒ Object
- #draw_subject(xml) ⇒ Object
-
#initialize(scene, options = {}) ⇒ SceneView
constructor
A new instance of SceneView.
- #to_svg ⇒ Object
Constructor Details
#initialize(scene, options = {}) ⇒ SceneView
Returns a new instance of SceneView.
15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/photo_utils/scene_view.rb', line 15 def initialize(scene, ={}) @scene = scene @width = [:width] || 900 @height = [:height] || 50 @max_distance = [:max_distance] || @scene.depth_of_field.far @camera_width = [:camera_width] || @scene.focal_length @camera_height = [:camera_height] || [@scene.absolute_aperture, @scene.format.height].max @scale = (@width.to_f - @height) / (@camera_width + @max_distance) @camera_scale = [ @height.to_f / @camera_width, @height.to_f / @camera_height ].min end |
Instance Attribute Details
#camera_height ⇒ Object
Returns the value of attribute camera_height.
12 13 14 |
# File 'lib/photo_utils/scene_view.rb', line 12 def camera_height @camera_height end |
#camera_width ⇒ Object
Returns the value of attribute camera_width.
11 12 13 |
# File 'lib/photo_utils/scene_view.rb', line 11 def camera_width @camera_width end |
#height ⇒ Object
Returns the value of attribute height.
9 10 11 |
# File 'lib/photo_utils/scene_view.rb', line 9 def height @height end |
#max_distance ⇒ Object
Returns the value of attribute max_distance.
10 11 12 |
# File 'lib/photo_utils/scene_view.rb', line 10 def max_distance @max_distance end |
#scale ⇒ Object
Returns the value of attribute scale.
13 14 15 |
# File 'lib/photo_utils/scene_view.rb', line 13 def scale @scale end |
#scene ⇒ Object
Returns the value of attribute scene.
7 8 9 |
# File 'lib/photo_utils/scene_view.rb', line 7 def scene @scene end |
#width ⇒ Object
Returns the value of attribute width.
8 9 10 |
# File 'lib/photo_utils/scene_view.rb', line 8 def width @width end |
Instance Method Details
#draw_camera(xml) ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/photo_utils/scene_view.rb', line 49 def draw_camera(xml) fh2 = (@scene.format.height / 2) * @camera_scale aa2 = (@scene.absolute_aperture / 2) * @camera_scale points = [ [0, -fh2], [@scene.focal_length * @camera_scale, -aa2], [@scene.focal_length * @camera_scale, aa2], [0, fh2], ] xml.g(transform: "translate(0,#{@height / 2})") do xml.polygon( x: -@height, y: 0, points: points.map { |p| p.join(',') }.join(' '), fill: 'black') end end |
#draw_dof(xml) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/photo_utils/scene_view.rb', line 67 def draw_dof(xml) # blur if true step = @max_distance / 20 step.step(@max_distance, step).map { |d| Length.new(d) }.each do |d| blur = @scene.blur_at_distance(d) if blur == 0 std_dev = 0 else ratio = @scene.circle_of_confusion / blur std_dev = [9 - (ratio * 10).to_i, 0].max end xml.circle( cx: d * @scale, cy: @height / 2, r: (step * @scale) / 2 / 2, fill: 'black', filter: (std_dev > 0) ? "url(\#gb#{std_dev})" : ()) end else step = (@max_distance / @width) * 10 0.step(@max_distance, step).map { |d| Length.new(d) }.each do |distance| blur = @scene.blur_at_distance(distance) opacity = [1, @scene.circle_of_confusion / blur].min xml.rect( x: distance * @scale, y: (@height - (@scene.field_of_view(distance).height * @scale)) / 2, width: step * @scale, height: @scene.field_of_view(distance).height * @scale, fill: 'blue', 'fill-opacity' => opacity) end end # depth of focus area xml.rect( x: @scene.depth_of_field.near * @scale, y: 0, width: @scene.total_depth_of_field * @scale, height: @height, stroke: 'blue', fill: 'none') end |
#draw_hyperfocal(xml) ⇒ Object
123 124 125 126 127 128 129 130 |
# File 'lib/photo_utils/scene_view.rb', line 123 def draw_hyperfocal(xml) xml.line( x1: @scene.hyperfocal_distance * scale, y1: 0, x2: @scene.hyperfocal_distance * scale, y2: @height, stroke: 'green') end |
#draw_subject(xml) ⇒ Object
114 115 116 117 118 119 120 121 |
# File 'lib/photo_utils/scene_view.rb', line 114 def draw_subject(xml) xml.rect( x: @scene.subject_distance * @scale, y: 0, width: 1, height: @height, fill: 'red') end |
#to_svg ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/photo_utils/scene_view.rb', line 29 def to_svg xml = Builder::XmlMarkup.new(indent: 2) xml.svg(width: @width, height: @height) do xml.defs do 1.upto(9).each do |std_dev| xml.filter(id: "gb#{std_dev}") do xml.feGaussianBlur(in: 'SourceGraphic', stdDeviation: std_dev) end end end xml.g(transform: "translate(#{@height},0)") do draw_camera(xml) draw_dof(xml) draw_subject(xml) # draw_hyperfocal(xml) end end xml.target! end |