Class: Amaze::Formatter::Image::Polar
- Inherits:
-
Amaze::Formatter::Image
- Object
- Amaze::Formatter::Image
- Amaze::Formatter::Image::Polar
- Defined in:
- lib/amaze/formatter/image/polar.rb
Instance Attribute Summary
Attributes inherited from Amaze::Formatter::Image
Instance Method Summary collapse
- #center_coord(cell, unit = :degree) ⇒ Object
- #coord(cell, unit = :degree) ⇒ Object
- #image_center ⇒ Object
- #image_width ⇒ Object (also: #image_height)
- #outward_subdivided?(cell) ⇒ Boolean
- #path_outward(cell) ⇒ Object
- #polar2cartesian(radius, theta) ⇒ Object
- #radian2degree(value) ⇒ Object
- #render_background ⇒ Object
- #render_grid ⇒ Object
- #render_path ⇒ Object
- #render_wall ⇒ Object
Methods inherited from Amaze::Formatter::Image
#background_color, #border_width, #canvas, #cell_offset, #cell_width, colors, #distance_color, #distances, #distances_max, #gradient, #hide_walls?, #image, #initialize, #path?, #path_cell?, #path_cells, #path_color, #path_finish, #path_start, #path_width, #render, #show_grid?, #wall_color, #wall_width, #write
Constructor Details
This class inherits a constructor from Amaze::Formatter::Image
Instance Method Details
#center_coord(cell, unit = :degree) ⇒ Object
151 152 153 154 155 156 157 158 |
# File 'lib/amaze/formatter/image/polar.rb', line 151 def center_coord cell, unit=:degree radius = (cell.row + 0.5) * cell_width theta = 2 * Math::PI / grid.columns(cell.row).size angle = (cell.column + 0.5) * theta angle = radian2degree(angle) if unit == :degree [radius, angle] end |
#coord(cell, unit = :degree) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/amaze/formatter/image/polar.rb', line 130 def coord cell, unit=:degree inner_radius = cell.row * cell_width outer_radius = (cell.row + 1) * cell_width theta = 2 * Math::PI / grid.columns(cell.row).size theta_ccw = cell.column * theta theta_cw = (cell.column + 1) * theta # we need only the cartesian coords of the cw wall # ax, ay = polar2cartesian(inner_radius, theta_ccw) # bx, by = polar2cartesian(outer_radius, theta_ccw) cx, cy = polar2cartesian(inner_radius, theta_cw) dx, dy = polar2cartesian(outer_radius, theta_cw) if unit == :degree theta_ccw = radian2degree theta_ccw theta_cw = radian2degree theta_cw end [cx, cy, dx, dy, inner_radius, theta_ccw, theta_cw] end |
#image_center ⇒ Object
174 175 176 |
# File 'lib/amaze/formatter/image/polar.rb', line 174 def image_center image_width / 2 end |
#image_width ⇒ Object Also known as: image_height
168 169 170 |
# File 'lib/amaze/formatter/image/polar.rb', line 168 def image_width cell_width * grid.rows * 2 + wall_width + border_width * 2 + 3 # why? +3 end |
#outward_subdivided?(cell) ⇒ Boolean
121 122 123 124 |
# File 'lib/amaze/formatter/image/polar.rb', line 121 def outward_subdivided? cell return false if grid.rows == cell.row + 1 grid.columns(cell.row).size != grid.columns(cell.row+1).size end |
#path_outward(cell) ⇒ Object
126 127 128 |
# File 'lib/amaze/formatter/image/polar.rb', line 126 def path_outward cell cell.outward.select {|o| cell.linked?(o) && path_cell?(o) } end |
#polar2cartesian(radius, theta) ⇒ Object
160 161 162 |
# File 'lib/amaze/formatter/image/polar.rb', line 160 def polar2cartesian radius, theta [image_center + radius * Math.cos(theta), image_center + radius * Math.sin(theta)] end |
#radian2degree(value) ⇒ Object
164 165 166 |
# File 'lib/amaze/formatter/image/polar.rb', line 164 def radian2degree value 360 / (2 * Math::PI) * value end |
#render_background ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/amaze/formatter/image/polar.rb', line 4 def render_background canvas.stroke_antialias true canvas.stroke_linecap 'butt' canvas.stroke_width cell_width canvas.fill 'none' grid.each_cell do |cell| color = distance_color cell next unless color canvas.stroke color _, _, _, _, _, ccw, cw = coord cell radius, _ = center_coord cell canvas.ellipse image_center, image_center, radius, radius, ccw, cw end end |
#render_grid ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/amaze/formatter/image/polar.rb', line 20 def render_grid canvas.stroke_antialias true canvas.stroke_linecap 'square' canvas.stroke 'gray90' canvas.stroke_width 1 canvas.fill 'none' grid.each_cell do |cell| next if cell.row == 0 cx, cy, dx, dy, radius, ccw, cw = coord cell canvas.ellipse image_center, image_center, radius, radius, ccw, cw canvas.line cx, cy, dx, dy end canvas.ellipse(image_center, image_center, grid.rows * cell_width, grid.rows * cell_width, 0, 360) end |
#render_path ⇒ Object
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 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 113 114 115 116 117 118 119 |
# File 'lib/amaze/formatter/image/polar.rb', line 55 def render_path canvas.stroke_antialias true canvas.stroke_linecap 'square' canvas.fill 'none' canvas.stroke path_color canvas.stroke_width path_width grid.each_cell do |cell| next unless path_cell? cell unless path?(:cw, cell) || path?(:ccw, cell) # draw arc to close the gap if outward ring is subdivided # and cell is linked outwards but not cw and ccw # this can be the case even for cell(0,0) outward_cells = path_outward(cell) if outward_subdivided?(cell) && outward_cells.any? radius, angle = center_coord cell angles_outward_cells = outward_cells.map {|o| _, a = center_coord(o); a } # don't use cell(0,0) own angel, override with one of the outward cells angle = angles_outward_cells.first if cell.row == 0 angle1 = [angle, *angles_outward_cells].min angle2 = [angle, *angles_outward_cells].max canvas.ellipse image_center, image_center, radius, radius, angle1, angle2 unless angle1 == angle2 end end next if cell.row == 0 if path?(:inward, cell) radius, theta = center_coord cell, :radian # center of cell x1, y1 = polar2cartesian(radius, theta) # center of inward cell, but adjusted to the same angle of the current cell radius_inward, _ = center_coord cell.inward, :radian x2, y2 = polar2cartesian(radius_inward, theta) canvas.line x1, y1, x2, y2 end if path?(:cw, cell) radius1, angle1 = center_coord cell radius2, angle2 = center_coord cell.cw # adjust angle if outward ring is subdivided if outward_subdivided?(cell) outward_cells = path_outward(cell) _, angle1 = center_coord(outward_cells.first) if outward_cells.any? outward_cells_cw = path_outward(cell.cw) _, angle2 = center_coord(outward_cells_cw.first) if outward_cells_cw.any? end canvas.ellipse image_center, image_center, radius1, radius1, angle1, angle2 end end # draw start and finish canvas.stroke_antialias true canvas.stroke_linecap 'square' canvas.fill path_color canvas.stroke 'none' [path_start, path_finish].compact.each do |cell| radius, theta = center_coord cell, :radian # adjust the angle for cell(0,0) _, theta = center_coord path_outward(cell).first, :radian if cell.row.zero? x, y = polar2cartesian(radius, theta) canvas.ellipse x, y, path_width*2, path_width*2, 0, 360 end end |
#render_wall ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/amaze/formatter/image/polar.rb', line 37 def render_wall canvas.stroke_antialias true canvas.stroke_linecap 'square' canvas.stroke wall_color canvas.stroke_width wall_width canvas.fill 'none' grid.each_cell do |cell| next if cell.row == 0 cx, cy, dx, dy, radius, ccw, cw = coord cell canvas.ellipse image_center, image_center, radius, radius, ccw, cw unless cell.linked_to?(:inward) canvas.line cx, cy, dx, dy unless cell.linked_to?(:cw) end canvas.ellipse(image_center, image_center, grid.rows * cell_width, grid.rows * cell_width, 0, 360) end |