aboutsummaryrefslogtreecommitdiff
path: root/lib/camera.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/camera.rb')
-rw-r--r--lib/camera.rb63
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/camera.rb b/lib/camera.rb
new file mode 100644
index 0000000..f8721bb
--- /dev/null
+++ b/lib/camera.rb
@@ -0,0 +1,63 @@
+class Camera
+ def initialize(width = 100, aspect = 1.0, aliasing = 10)
+ @width = width
+ @aspect = aspect
+ @aliasing = aliasing
+
+ # Height
+ @height = (@width / @aspect).to_i
+ @height = @height < 1 ? 1 : @height
+
+ # Camera
+ c_focallength = 1.0
+ @c_centre = Point.new(0,0,0)
+
+ # Viewport
+ @v_height = 2.0
+ @v_width = @v_height * @width.to_f / @height
+ v_u = Vec3.new(@v_width, 0, 0)
+ v_v = Vec3.new(0, -@v_height, 0)
+
+ # Pixel deltas
+ @pd_u = v_u / @width
+ @pd_v = v_v / @height
+
+ # Upper left pixel
+ v_upperleft = @c_centre - v_u / 2 - v_v / 2 -
+ Vec3.new(0, 0, c_focallength)
+ @p00_loc = v_upperleft + (@pd_u + @pd_v) / 2
+ end
+
+ def render(world)
+ start = Time.now.to_f
+
+ puts "P3"
+ puts "#{@width} #{@height}"
+ puts "255"
+
+ @height.times do |row|
+ $stderr.print "Scanlines remaining: %4d" % (@height - row)
+ @width.times do |col|
+ p_colour = Colour.new
+ @aliasing.times do
+ p_colour += get_ray(row, col).colour(world)
+ end
+ puts (p_colour / @aliasing).to_ppm
+ end
+ puts
+ end
+
+ finish = Time.now.to_f
+ took = finish - start
+
+ $stderr.puts "Done. Took %4.2f seconds. " % took
+ end
+
+ def get_ray(row, col)
+ p_sample = @p00_loc +
+ @pd_u * (col + rand - 0.5) +
+ @pd_v * (row + rand - 0.5)
+
+ Ray.new(@c_centre, p_sample - @c_centre)
+ end
+end