amaze 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|