amaze 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +110 -0
- data/Rakefile +6 -0
- data/amaze.gemspec +30 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/exe/amaze +5 -0
- data/lib/amaze.rb +17 -0
- data/lib/amaze/algorithm.rb +44 -0
- data/lib/amaze/algorithm/aldous_border.rb +36 -0
- data/lib/amaze/algorithm/binary_tree.rb +20 -0
- data/lib/amaze/algorithm/growing_tree.rb +52 -0
- data/lib/amaze/algorithm/hunt_and_kill.rb +53 -0
- data/lib/amaze/algorithm/recursive_backtracker.rb +77 -0
- data/lib/amaze/algorithm/sidewinder.rb +42 -0
- data/lib/amaze/algorithm/wilson.rb +54 -0
- data/lib/amaze/cell.rb +63 -0
- data/lib/amaze/cell/hex.rb +10 -0
- data/lib/amaze/cell/octo.rb +10 -0
- data/lib/amaze/cell/polar.rb +16 -0
- data/lib/amaze/cell/square.rb +10 -0
- data/lib/amaze/distances.rb +53 -0
- data/lib/amaze/factory.rb +153 -0
- data/lib/amaze/formatter.rb +5 -0
- data/lib/amaze/formatter/ascii.rb +91 -0
- data/lib/amaze/formatter/ascii/delta.rb +180 -0
- data/lib/amaze/formatter/ascii/ortho.rb +105 -0
- data/lib/amaze/formatter/ascii/polar.rb +199 -0
- data/lib/amaze/formatter/ascii/sigma.rb +213 -0
- data/lib/amaze/formatter/ascii/upsilon.rb +281 -0
- data/lib/amaze/formatter/image.rb +127 -0
- data/lib/amaze/formatter/image/delta.rb +123 -0
- data/lib/amaze/formatter/image/ortho.rb +103 -0
- data/lib/amaze/formatter/image/polar.rb +173 -0
- data/lib/amaze/formatter/image/sigma.rb +122 -0
- data/lib/amaze/formatter/image/upsilon.rb +135 -0
- data/lib/amaze/grid.rb +66 -0
- data/lib/amaze/grid/delta.rb +87 -0
- data/lib/amaze/grid/ortho.rb +38 -0
- data/lib/amaze/grid/polar.rb +61 -0
- data/lib/amaze/grid/sigma.rb +61 -0
- data/lib/amaze/grid/upsilon.rb +74 -0
- data/lib/amaze/mask.rb +75 -0
- data/lib/amaze/masked_grid.rb +29 -0
- data/lib/amaze/script.rb +361 -0
- data/lib/amaze/shape.rb +23 -0
- data/lib/amaze/shape/diamond.rb +26 -0
- data/lib/amaze/shape/hexagon.rb +79 -0
- data/lib/amaze/shape/star.rb +114 -0
- data/lib/amaze/shape/triangle.rb +25 -0
- data/lib/amaze/version.rb +3 -0
- data/support/characters.txt +17 -0
- data/support/mask/mask1.txt +10 -0
- data/support/mask/mask2.txt +12 -0
- data/support/mask/mask3.txt +15 -0
- metadata +203 -0
@@ -0,0 +1,127 @@
|
|
1
|
+
|
2
|
+
require 'rmagick'
|
3
|
+
|
4
|
+
class Amaze::Formatter::Image
|
5
|
+
autoload :Ortho, 'amaze/formatter/image/ortho'
|
6
|
+
autoload :Sigma, 'amaze/formatter/image/sigma'
|
7
|
+
autoload :Delta, 'amaze/formatter/image/delta'
|
8
|
+
autoload :Upsilon, 'amaze/formatter/image/upsilon'
|
9
|
+
autoload :Polar, 'amaze/formatter/image/polar'
|
10
|
+
|
11
|
+
# The grid
|
12
|
+
attr_reader :grid
|
13
|
+
|
14
|
+
# Options for the Image renderer
|
15
|
+
attr_reader :options
|
16
|
+
|
17
|
+
def initialize grid, options={}
|
18
|
+
@grid = grid
|
19
|
+
@options = options
|
20
|
+
end
|
21
|
+
|
22
|
+
def path? direction, cell
|
23
|
+
cell.linked?(cell.send(direction)) && path_cell?(cell.send(direction))
|
24
|
+
end
|
25
|
+
|
26
|
+
def path_cell? cell
|
27
|
+
path_cells.include? cell
|
28
|
+
end
|
29
|
+
|
30
|
+
def path_cells
|
31
|
+
Array(options[:path_cells])
|
32
|
+
end
|
33
|
+
|
34
|
+
def path_start
|
35
|
+
options[:path_start]
|
36
|
+
end
|
37
|
+
|
38
|
+
def path_finish
|
39
|
+
options[:path_finish]
|
40
|
+
end
|
41
|
+
|
42
|
+
def render
|
43
|
+
render_background if distances
|
44
|
+
render_grid if show_grid?
|
45
|
+
render_wall unless hide_walls?
|
46
|
+
render_path if path_cells.any?
|
47
|
+
end
|
48
|
+
|
49
|
+
def image
|
50
|
+
@image ||= Magick::Image.new image_width, image_height, Magick::SolidFill.new(background_color)
|
51
|
+
end
|
52
|
+
|
53
|
+
def canvas
|
54
|
+
@canvas ||= Magick::Draw.new
|
55
|
+
end
|
56
|
+
|
57
|
+
def write filename
|
58
|
+
canvas.draw image
|
59
|
+
image.write(filename)
|
60
|
+
end
|
61
|
+
|
62
|
+
def cell_width
|
63
|
+
@options[:cell_width] || 100
|
64
|
+
end
|
65
|
+
|
66
|
+
def border_width
|
67
|
+
@options[:border_width] || 0
|
68
|
+
end
|
69
|
+
|
70
|
+
def wall_width
|
71
|
+
@options[:wall_width] || 5
|
72
|
+
end
|
73
|
+
|
74
|
+
def wall_color
|
75
|
+
@options[:wall_color].to_s || 'black'
|
76
|
+
end
|
77
|
+
|
78
|
+
def path_width
|
79
|
+
@options[:path_width] || 3
|
80
|
+
end
|
81
|
+
|
82
|
+
def path_color
|
83
|
+
@options[:path_color].to_s || 'red'
|
84
|
+
end
|
85
|
+
|
86
|
+
def background_color
|
87
|
+
@options[:background_color].to_s || 'white'
|
88
|
+
end
|
89
|
+
|
90
|
+
def show_grid?
|
91
|
+
@options[:show_grid]
|
92
|
+
end
|
93
|
+
|
94
|
+
def hide_walls?
|
95
|
+
@options[:hide_walls]
|
96
|
+
end
|
97
|
+
|
98
|
+
def cell_offset
|
99
|
+
wall_width / 2.0 + border_width
|
100
|
+
end
|
101
|
+
|
102
|
+
def distances
|
103
|
+
options[:distances]
|
104
|
+
end
|
105
|
+
|
106
|
+
def distances_max
|
107
|
+
@distances_max ||= distances.max[1]
|
108
|
+
end
|
109
|
+
|
110
|
+
# Returns the background color of a cell, depending on its distance from the origin
|
111
|
+
def distance_color cell
|
112
|
+
if distances && distances[cell]
|
113
|
+
intensity = (distances_max - distances[cell].to_f) / distances_max
|
114
|
+
'#' + gradient.at(intensity).color.hex
|
115
|
+
else
|
116
|
+
nil
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def gradient
|
121
|
+
options[:gradient_map]
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.colors
|
125
|
+
Magick.colors.map(&:name)
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
|
2
|
+
class Amaze::Formatter::Image::Delta < Amaze::Formatter::Image
|
3
|
+
|
4
|
+
def render_background
|
5
|
+
canvas.stroke_antialias true
|
6
|
+
canvas.stroke_linecap 'round'
|
7
|
+
canvas.stroke_linejoin 'round'
|
8
|
+
canvas.stroke 'none'
|
9
|
+
grid.each_cell do |cell|
|
10
|
+
color = distance_color cell
|
11
|
+
next unless color
|
12
|
+
canvas.fill color
|
13
|
+
canvas.polygon *coord(cell)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def render_grid
|
18
|
+
canvas.stroke_antialias true
|
19
|
+
canvas.stroke_linecap 'round'
|
20
|
+
canvas.stroke_linejoin 'round'
|
21
|
+
canvas.stroke 'gray90'
|
22
|
+
canvas.stroke_width 1
|
23
|
+
canvas.fill 'none'
|
24
|
+
|
25
|
+
grid.each_cell do |cell|
|
26
|
+
canvas.polygon *coord(cell)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def render_wall
|
31
|
+
canvas.stroke_antialias true
|
32
|
+
canvas.stroke_linecap 'round'
|
33
|
+
canvas.stroke_linejoin 'round'
|
34
|
+
canvas.stroke wall_color
|
35
|
+
canvas.stroke_width wall_width
|
36
|
+
canvas.fill 'none'
|
37
|
+
|
38
|
+
grid.each_cell do |cell|
|
39
|
+
ax, ay, bx, by, cx, cy = coord cell
|
40
|
+
|
41
|
+
canvas.line ax, ay, cx, cy unless cell.linked_to?(:west)
|
42
|
+
canvas.line bx, by, cx, cy unless cell.linked_to?(:east)
|
43
|
+
|
44
|
+
direction = (cell.row+cell.column).even? ? :north : :south
|
45
|
+
canvas.line ax, ay, bx, by unless cell.linked_to?(direction)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def render_path
|
50
|
+
canvas.stroke_antialias true
|
51
|
+
canvas.stroke_linecap 'round'
|
52
|
+
canvas.stroke_linejoin 'round'
|
53
|
+
canvas.fill 'none'
|
54
|
+
canvas.stroke path_color
|
55
|
+
canvas.stroke_width path_width
|
56
|
+
|
57
|
+
grid.each_cell do |cell|
|
58
|
+
next unless path_cell? cell
|
59
|
+
|
60
|
+
x1, y1 = center_coord cell
|
61
|
+
%i( north east ).each do |direction|
|
62
|
+
next unless path?(direction, cell)
|
63
|
+
x2, y2 = center_coord cell.send(direction)
|
64
|
+
canvas.line x1, y1, x2, y2
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# draw start and finish
|
69
|
+
canvas.stroke_antialias true
|
70
|
+
canvas.stroke_linecap 'round'
|
71
|
+
canvas.fill path_color
|
72
|
+
canvas.stroke 'none'
|
73
|
+
[path_start, path_finish].compact.each do |cell|
|
74
|
+
x, y = center_coord cell
|
75
|
+
canvas.ellipse x, y, path_width*2, path_width*2, 0, 360
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def coord cell
|
80
|
+
row, column = cell.row, cell.column
|
81
|
+
|
82
|
+
x1 = column * pattern_width + cell_offset
|
83
|
+
y1 = row * pattern_height + cell_offset
|
84
|
+
x2 = x1 + pattern_width
|
85
|
+
x3 = x2 + pattern_width
|
86
|
+
y2 = y1 + pattern_height
|
87
|
+
|
88
|
+
if (row+column).even?
|
89
|
+
[x1, y1, x3, y1, x2, y2]
|
90
|
+
else
|
91
|
+
[x1, y2, x3, y2, x2, y1]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def center_coord cell
|
96
|
+
row, column = cell.row, cell.column
|
97
|
+
|
98
|
+
x = (column+1) * pattern_width + cell_offset
|
99
|
+
y0 = row * pattern_height + cell_offset
|
100
|
+
|
101
|
+
dy = cell_width * Math.sqrt(3)
|
102
|
+
fraction = (row+column).even? ? 6.0 : 3.0
|
103
|
+
y = y0 + dy / fraction
|
104
|
+
|
105
|
+
[x, y]
|
106
|
+
end
|
107
|
+
|
108
|
+
def pattern_width
|
109
|
+
@pattern_width ||= cell_width / 2.0
|
110
|
+
end
|
111
|
+
|
112
|
+
def pattern_height
|
113
|
+
@pattern_height ||= cell_width * Math.sqrt(3) / 2.0
|
114
|
+
end
|
115
|
+
|
116
|
+
def image_width
|
117
|
+
pattern_width * (grid.columns + 1) + wall_width + border_width * 2 + 1
|
118
|
+
end
|
119
|
+
|
120
|
+
def image_height
|
121
|
+
pattern_height * grid.rows + wall_width + border_width * 2 + 1
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
|
2
|
+
class Amaze::Formatter::Image::Ortho < Amaze::Formatter::Image
|
3
|
+
|
4
|
+
def render_background
|
5
|
+
canvas.stroke_antialias true
|
6
|
+
canvas.stroke_linecap 'square'
|
7
|
+
canvas.stroke 'none'
|
8
|
+
grid.each_cell do |cell|
|
9
|
+
color = distance_color cell
|
10
|
+
next unless color
|
11
|
+
canvas.fill color
|
12
|
+
x1, x2, y1, y2 = coord cell
|
13
|
+
canvas.polygon x1, y1, x2, y1, x2, y2, x1, y2
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def render_grid
|
18
|
+
canvas.stroke_antialias true
|
19
|
+
canvas.stroke_linecap 'square'
|
20
|
+
canvas.stroke 'gray90'
|
21
|
+
canvas.stroke_width 1
|
22
|
+
canvas.fill 'none'
|
23
|
+
|
24
|
+
grid.each_cell do |cell|
|
25
|
+
x1, x2, y1, y2 = coord cell
|
26
|
+
canvas.polygon x1, y1, x2, y1, x2, y2, x1, y2
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def render_wall
|
31
|
+
canvas.stroke_antialias true
|
32
|
+
canvas.stroke_linecap 'square'
|
33
|
+
canvas.stroke wall_color
|
34
|
+
canvas.stroke_width wall_width
|
35
|
+
canvas.fill 'none'
|
36
|
+
|
37
|
+
grid.each_cell do |cell|
|
38
|
+
x1, x2, y1, y2 = coord cell
|
39
|
+
|
40
|
+
canvas.line x1, y1, x2, y1 unless cell.linked_to?(:north)
|
41
|
+
canvas.line x2, y1, x2, y2 unless cell.linked_to?(:east)
|
42
|
+
canvas.line x1, y2, x2, y2 unless cell.linked_to?(:south)
|
43
|
+
canvas.line x1, y1, x1, y2 unless cell.linked_to?(:west)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def render_path
|
48
|
+
canvas.stroke_antialias true
|
49
|
+
canvas.stroke_linecap 'square'
|
50
|
+
canvas.fill 'none'
|
51
|
+
canvas.stroke path_color
|
52
|
+
canvas.stroke_width path_width
|
53
|
+
|
54
|
+
grid.each_cell do |cell|
|
55
|
+
next unless path_cell? cell
|
56
|
+
|
57
|
+
x1, y1 = center_coord cell
|
58
|
+
%i( north east ).each do |direction|
|
59
|
+
next unless path?(direction, cell)
|
60
|
+
x2, y2 = center_coord cell.send(direction)
|
61
|
+
canvas.line x1, y1, x2, y2
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# draw start and finish
|
66
|
+
canvas.stroke_antialias true
|
67
|
+
canvas.stroke_linecap 'square'
|
68
|
+
canvas.fill path_color
|
69
|
+
canvas.stroke 'none'
|
70
|
+
[path_start, path_finish].compact.each do |cell|
|
71
|
+
x, y = center_coord cell
|
72
|
+
canvas.ellipse x, y, path_width*2, path_width*2, 0, 360
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def coord cell
|
77
|
+
row, column = cell.row, cell.column
|
78
|
+
|
79
|
+
x1 = column * cell_width + cell_offset
|
80
|
+
x2 = (column+1) * cell_width + cell_offset
|
81
|
+
y1 = row * cell_width + cell_offset
|
82
|
+
y2 = (row+1) * cell_width + cell_offset
|
83
|
+
|
84
|
+
[x1, x2, y1, y2]
|
85
|
+
end
|
86
|
+
|
87
|
+
def center_coord cell
|
88
|
+
row, column = cell.row, cell.column
|
89
|
+
|
90
|
+
x = (column+0.5) * cell_width + cell_offset
|
91
|
+
y = (row+0.5) * cell_width + cell_offset
|
92
|
+
|
93
|
+
[x, y]
|
94
|
+
end
|
95
|
+
|
96
|
+
def image_width
|
97
|
+
cell_width * grid.columns + wall_width + border_width * 2 + 1
|
98
|
+
end
|
99
|
+
|
100
|
+
def image_height
|
101
|
+
cell_width * grid.rows + wall_width + border_width * 2 + 1
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
|
2
|
+
class Amaze::Formatter::Image::Polar < Amaze::Formatter::Image
|
3
|
+
|
4
|
+
def render_background
|
5
|
+
canvas.stroke_antialias true
|
6
|
+
canvas.stroke_linecap 'butt'
|
7
|
+
canvas.stroke_width cell_width
|
8
|
+
canvas.fill 'none'
|
9
|
+
|
10
|
+
grid.each_cell do |cell|
|
11
|
+
color = distance_color cell
|
12
|
+
next unless color
|
13
|
+
canvas.stroke color
|
14
|
+
_, _, _, _, _, ccw, cw = coord cell
|
15
|
+
radius, _ = center_coord cell
|
16
|
+
canvas.ellipse image_center, image_center, radius, radius, ccw, cw
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def render_grid
|
21
|
+
canvas.stroke_antialias true
|
22
|
+
canvas.stroke_linecap 'square'
|
23
|
+
canvas.stroke 'gray90'
|
24
|
+
canvas.stroke_width 1
|
25
|
+
canvas.fill 'none'
|
26
|
+
|
27
|
+
grid.each_cell do |cell|
|
28
|
+
next if cell.row == 0
|
29
|
+
cx, cy, dx, dy, radius, ccw, cw = coord cell
|
30
|
+
|
31
|
+
canvas.ellipse image_center, image_center, radius, radius, ccw, cw
|
32
|
+
canvas.line cx, cy, dx, dy
|
33
|
+
end
|
34
|
+
canvas.ellipse(image_center, image_center, grid.rows * cell_width, grid.rows * cell_width, 0, 360)
|
35
|
+
end
|
36
|
+
|
37
|
+
def render_wall
|
38
|
+
canvas.stroke_antialias true
|
39
|
+
canvas.stroke_linecap 'square'
|
40
|
+
canvas.stroke wall_color
|
41
|
+
canvas.stroke_width wall_width
|
42
|
+
canvas.fill 'none'
|
43
|
+
|
44
|
+
grid.each_cell do |cell|
|
45
|
+
next if cell.row == 0
|
46
|
+
cx, cy, dx, dy, radius, ccw, cw = coord cell
|
47
|
+
|
48
|
+
canvas.ellipse image_center, image_center, radius, radius, ccw, cw unless cell.linked_to?(:inward)
|
49
|
+
canvas.line cx, cy, dx, dy unless cell.linked_to?(:cw)
|
50
|
+
end
|
51
|
+
|
52
|
+
canvas.ellipse(image_center, image_center, grid.rows * cell_width, grid.rows * cell_width, 0, 360)
|
53
|
+
end
|
54
|
+
|
55
|
+
def render_path
|
56
|
+
canvas.stroke_antialias true
|
57
|
+
canvas.stroke_linecap 'square'
|
58
|
+
canvas.fill 'none'
|
59
|
+
canvas.stroke path_color
|
60
|
+
canvas.stroke_width path_width
|
61
|
+
|
62
|
+
grid.each_cell do |cell|
|
63
|
+
next unless path_cell? cell
|
64
|
+
|
65
|
+
unless path?(:cw, cell) || path?(:ccw, cell)
|
66
|
+
# draw arc to close the gap if outward ring is subdivided
|
67
|
+
# and cell is linked outwards but not cw and ccw
|
68
|
+
# this can be the case even for cell(0,0)
|
69
|
+
outward_cells = path_outward(cell)
|
70
|
+
if outward_subdivided?(cell) && outward_cells.any?
|
71
|
+
radius, angle = center_coord cell
|
72
|
+
angles_outward_cells = outward_cells.map {|o| _, a = center_coord(o); a }
|
73
|
+
# don't use cell(0,0) own angel, override with one of the outward cells
|
74
|
+
angle = angles_outward_cells.first if cell.row == 0
|
75
|
+
angle1 = [angle, *angles_outward_cells].min
|
76
|
+
angle2 = [angle, *angles_outward_cells].max
|
77
|
+
canvas.ellipse image_center, image_center, radius, radius, angle1, angle2 unless angle1 == angle2
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
next if cell.row == 0
|
82
|
+
|
83
|
+
if path?(:inward, cell)
|
84
|
+
radius, theta = center_coord cell, :radian
|
85
|
+
# center of cell
|
86
|
+
x1, y1 = polar2cartesian(radius, theta)
|
87
|
+
# center of inward cell, but adjusted to the same angle of the current cell
|
88
|
+
x2, y2 = polar2cartesian(radius - cell_width, theta)
|
89
|
+
canvas.line x1, y1, x2, y2
|
90
|
+
end
|
91
|
+
|
92
|
+
if path?(:cw, cell)
|
93
|
+
radius1, angle1 = center_coord cell
|
94
|
+
radius2, angle2 = center_coord cell.cw
|
95
|
+
# adjust angle if outward ring is subdivided
|
96
|
+
if outward_subdivided?(cell)
|
97
|
+
outward_cells = path_outward(cell)
|
98
|
+
_, angle1 = center_coord(outward_cells.first) if outward_cells.any?
|
99
|
+
outward_cells_cw = path_outward(cell.cw)
|
100
|
+
_, angle2 = center_coord(outward_cells_cw.first) if outward_cells_cw.any?
|
101
|
+
end
|
102
|
+
canvas.ellipse image_center, image_center, radius1, radius1, angle1, angle2
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# draw start and finish
|
107
|
+
canvas.stroke_antialias true
|
108
|
+
canvas.stroke_linecap 'square'
|
109
|
+
canvas.fill path_color
|
110
|
+
canvas.stroke 'none'
|
111
|
+
[path_start, path_finish].compact.each do |cell|
|
112
|
+
x, y = polar2cartesian(*center_coord(cell, :radian))
|
113
|
+
canvas.ellipse x, y, path_width*2, path_width*2, 0, 360
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def outward_subdivided? cell
|
118
|
+
return false if grid.rows == cell.row + 1
|
119
|
+
grid.columns(cell.row).size != grid.columns(cell.row+1).size
|
120
|
+
end
|
121
|
+
|
122
|
+
def path_outward cell
|
123
|
+
cell.outward.select {|o| cell.linked?(o) && path_cell?(o) }
|
124
|
+
end
|
125
|
+
|
126
|
+
def coord cell, unit=:degree
|
127
|
+
inner_radius = cell.row * cell_width
|
128
|
+
outer_radius = (cell.row + 1) * cell_width
|
129
|
+
theta = 2 * Math::PI / grid.columns(cell.row).size
|
130
|
+
theta_ccw = cell.column * theta
|
131
|
+
theta_cw = (cell.column + 1) * theta
|
132
|
+
|
133
|
+
# we need only the cartesian coords of the cw wall
|
134
|
+
# ax, ay = polar2cartesian(inner_radius, theta_ccw)
|
135
|
+
# bx, by = polar2cartesian(outer_radius, theta_ccw)
|
136
|
+
cx, cy = polar2cartesian(inner_radius, theta_cw)
|
137
|
+
dx, dy = polar2cartesian(outer_radius, theta_cw)
|
138
|
+
|
139
|
+
if unit == :degree
|
140
|
+
theta_ccw = radian2degree theta_ccw
|
141
|
+
theta_cw = radian2degree theta_cw
|
142
|
+
end
|
143
|
+
|
144
|
+
[cx, cy, dx, dy, inner_radius, theta_ccw, theta_cw]
|
145
|
+
end
|
146
|
+
|
147
|
+
def center_coord cell, unit=:degree
|
148
|
+
radius = (cell.row + 0.5) * cell_width
|
149
|
+
theta = 2 * Math::PI / grid.columns(cell.row).size
|
150
|
+
angle = (cell.column + 0.5) * theta
|
151
|
+
angle = radian2degree(angle) if unit == :degree
|
152
|
+
|
153
|
+
[radius, angle]
|
154
|
+
end
|
155
|
+
|
156
|
+
def polar2cartesian radius, theta
|
157
|
+
[image_center + radius * Math.cos(theta), image_center + radius * Math.sin(theta)]
|
158
|
+
end
|
159
|
+
|
160
|
+
def radian2degree value
|
161
|
+
360 / (2 * Math::PI) * value
|
162
|
+
end
|
163
|
+
|
164
|
+
def image_width
|
165
|
+
cell_width * grid.rows * 2 + wall_width + border_width * 2 + 3 # why? +3
|
166
|
+
end
|
167
|
+
|
168
|
+
alias_method :image_height, :image_width
|
169
|
+
|
170
|
+
def image_center
|
171
|
+
image_width / 2
|
172
|
+
end
|
173
|
+
end
|