module Polygon
Public Instance Methods
fill_polygon(vertices)
click to toggle source
# File lib/curses/geometry/polygon.rb, line 55 def fill_polygon (vertices) # Clearing the rasterizer's buffers : @left_scan = Array.new(lines) { 1000000 } @right_scan = Array.new(lines) { 0 } # Finding the top and bottom of the polygon : # Initializing the loop with the first point y value : max_y_index = 0 min_y_index = 0 max_y = vertices[max_y_index][1].to_i min_y = vertices[min_y_index][1].to_i vertices.each.with_index do |vertex,i| # Find the bottom index : if (vertex[1] < min_y) then min_y = vertex[1].to_i min_y_index = i end # Find the top index : if vertex[1] > max_y then max_y = vertex[1].to_i max_y_index = i end end # Discard null height polygons : return if min_y == max_y # Devise the winding order : previous_point_x = vertices[(max_y_index - 1 + vertices.length) % vertices.length][0].to_i next_point_x = vertices[(max_y_index + 1) % vertices.length][0].to_i winding_order = previous_point_x < next_point_x ? -1 : 1 # Scan the left and right edges of the polygon : # Left : i = 0 while( vertices[( ( max_y_index + i * winding_order ) + vertices.length) % vertices.length][1] != min_y ) do index = ( ( max_y_index + i * winding_order ) + vertices.length ) % vertices.length next_index = ( ( max_y_index + ( i + 1 ) * winding_order ) + vertices.length ) % vertices.length scan_polygon_left_edge( vertices[index][0], vertices[index][1], vertices[next_index][0], vertices[next_index][1] ) i += 1 end # Right : i = 0; while ( vertices[( ( max_y_index - i * winding_order ) + vertices.length ) % vertices.length][1] != min_y ) do index = ( ( max_y_index - i * winding_order ) + vertices.length ) % vertices.length next_index = ( ( max_y_index - ( i + 1 ) * winding_order ) + vertices.length ) % vertices.length scan_polygon_right_edge( vertices[index][0], vertices[index][1], vertices[next_index][0], vertices[next_index][1] ) i += 1 end # Draw the polygon : min_y.upto(max_y) do |y| @left_scan[y].upto(@right_scan[y]) do |x| setpos(y, x) addch(get_fill_glyph) end end end
scan_polygon_left_edge(x1, y1, x2, y2)
click to toggle source
Methods :
# File lib/curses/geometry/polygon.rb, line 8 def scan_polygon_left_edge(x1, y1, x2, y2) # Escape horizontal lines : return if (y1 - y2).abs < 0.75 # Calculating useful values for the scanning loop : islope = ( x2 - x1 ).to_f / ( y2 - y1 ).to_f #islope = ( x2 - x1 ) / ( y2 - y1 ) y_top = y1 > 0.5 ? ( y1 - 0.5 ).floor.to_i : 0.0 y_bottom = ( y2 + 0.5 ).floor.to_i x = ( y_top + 0.5 - y1 ) * islope + x1 # + 0.5 : the scan line goes through the middle of the pixel # Scan converting : y_top.downto(y_bottom) do |y| @left_scan[y] = ( x + 0.5 ).floor.to_i x -= islope end end
scan_polygon_right_edge(x1, y1, x2, y2)
click to toggle source
# File lib/curses/geometry/polygon.rb, line 32 def scan_polygon_right_edge(x1, y1, x2, y2) # Escape horizontal lines : return if ( y1 - y2 ).abs < 0.75 # Calculating useful values for the scanning loop : islope = ( x2 - x1 ).to_f / ( y2 - y1 ).to_f #islope = ( x2 - x1 ) / ( y2 - y1 ) y_top = y1 > 0.5 ? ( y1 - 0.5 ).floor.to_i : 0.0 y_bottom = ( y2 + 0.5 ).floor.to_i x = ( y_top + 0.5 - y1 ) * islope + x1 # + 0.5 : the scan line goes through the middle of the pixel # Scan converting : y_top.downto(y_bottom) do |y| @right_scan[y] = x > 0.5 ? ( x - 0.5 ).floor.to_i : 0.0 x -= islope end end