Class: Raster
- Inherits:
-
Object
- Object
- Raster
- Defined in:
- lib/skrift/raster.rb
Defined Under Namespace
Instance Method Summary collapse
-
#draw_line(origin, goal) ⇒ Object
Draws a line into the buffer.
-
#initialize(width, height) ⇒ Raster
constructor
A new instance of Raster.
-
#post_process ⇒ Object
Integrate the values in the buffer to arrive at the final grayscale image.
Constructor Details
Instance Method Details
#draw_line(origin, goal) ⇒ Object
Draws a line into the buffer. Uses a custom 2D raycasting algorithm to do so.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/skrift/raster.rb', line 30 def draw_line(origin, goal) prev_distance = 0.0 num_steps = 0 delta = goal-origin dir_x = delta[0] <=> 0 dir_y = delta[1] <=> 0 next_crossing = Vector[0.0,0.0] pixel = Vector[0,0] return if dir_y == 0 crossing_incr_x = dir_x != 0 ? (1.0 / delta[0]).abs : 1.0 crossing_incr_y = (1.0 / delta[1]).abs if dir_x == 0 pixel[0] = origin[0].floor next_crossing[0] = 100.0 else if dir_x > 0 pixel[0] = origin[0].floor next_crossing[0] = crossing_incr_x - (origin[0] - pixel[0]) * crossing_incr_x num_steps += goal[0].ceil - origin[0].floor - 1 else pixel[0] = origin[0].ceil - 1 next_crossing[0] = (origin[0] - pixel[0]) * crossing_incr_x num_steps += origin[0].ceil - goal[0].floor - 1 end end if dir_y > 0 pixel[1] = origin[1].floor next_crossing[1] = crossing_incr_y - (origin[1] - pixel[1]) * crossing_incr_y num_steps += goal[1].ceil - origin[1].floor - 1 else pixel[1] = origin[1].ceil - 1 next_crossing[1] = (origin[1] - pixel[1]) * crossing_incr_y num_steps += origin[1].ceil - goal[1].floor - 1 end next_distance = next_crossing.min half_delta_x = 0.5 * delta[0] setcell = ->(nd) do x_average = origin[0] + (prev_distance + nd) * half_delta_x - pixel[0] y_difference = (nd - prev_distance).to_f * delta[1] cell = @cells[pixel[1] * @width + pixel[0]] cell.cover += y_difference cell.area += (1.0 - x_average) * y_difference end num_steps.times do setcell.call(next_distance) prev_distance = next_distance along_x = next_crossing[0] < next_crossing[1] pixel += along_x ? Vector[dir_x,0] : Vector[0,dir_y] next_crossing += along_x ? Vector[crossing_incr_x, 0.0] : [0.0, crossing_incr_y] next_distance = next_crossing.min end setcell.call(1.0) end |
#post_process ⇒ Object
Integrate the values in the buffer to arrive at the final grayscale image.
18 19 20 21 22 23 24 25 26 27 |
# File 'lib/skrift/raster.rb', line 18 def post_process accum = 0.0 (@width*@height).times.collect do |i| cell = @cells[i] value = (accum + cell.area).abs value = [value, 1.0].min * 255.0 + 0.5 accum += cell.cover value.to_i & 0xff end end |