waxy 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,62 @@
1
+ module Waxy
2
+ module Geometry
3
+
4
+ class FractionalHex
5
+
6
+ attr_accessor :q, :r, :mq, :mr
7
+
8
+ # Ints
9
+ def initialize(_q, _r, _mq, _mr)
10
+ @q = _q
11
+ @r = _r
12
+ @mq = _mq
13
+ @mr = _mr
14
+ end
15
+
16
+ # def == (b)
17
+ # q == b.q && r == b.r && s == b.s
18
+ # end
19
+
20
+ # def != (b)
21
+ # !(self == b)
22
+ # end
23
+
24
+ # def + (b)
25
+ # Hex.new(q + b.q, r + b.r, s + b.s)
26
+ # end
27
+
28
+ # def - (b)
29
+ # Hex.new(q - b.q, r - b.r, s - b.s)
30
+ # end
31
+
32
+ # # @param a [Hex]
33
+ # # @param k [Int]
34
+ # def * (k)
35
+ # Hex.new(q * k, r * k, s * k)
36
+ # end
37
+
38
+ # def hex_length(hex)
39
+ # ((hex.q.abs + hex.r.abs + hex.s.abs) / 2).to_i
40
+ # end
41
+
42
+ # def distance(b)
43
+ # hex_length(self - b)
44
+ # end
45
+
46
+ # def hex_direction(i)
47
+ # raise if !(0..5).include?(i)
48
+ # HEX_DIRECTIONS[i]
49
+ # end
50
+
51
+ # # (0..5, requires modulo prior)
52
+ # def hex_neighbor(i)
53
+ # self + hex_direction(i)
54
+ # end
55
+
56
+ # def polygon_corners(layout)
57
+
58
+ # end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,93 @@
1
+ module Waxy
2
+ module Geometry
3
+ class Hex
4
+
5
+ attr_accessor :q, :r, :s
6
+
7
+ # Vector of 6 x (0.0 - 1.0)
8
+ # Used to scale the pie slices
9
+ # !! @size is typically set during render through a Waxy::Meta
10
+
11
+ attr_accessor :size
12
+
13
+ # All params are Int
14
+ def initialize(_q, _r, _s = nil)
15
+ @q = _q
16
+ @r = _r
17
+ @s = _s
18
+ end
19
+
20
+ # @return [Array]
21
+ # initialized here for foreseable geometry calculations,
22
+ # but in general this should be handled through a Meta
23
+ def size
24
+ @size ||= [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
25
+ @size
26
+ end
27
+
28
+ def == (b)
29
+ q == b.q && r == b.r && s == b.s
30
+ end
31
+
32
+ def != (b)
33
+ !(self == b)
34
+ end
35
+
36
+ def + (b)
37
+ Hex.new(q + b.q, r + b.r, ( s ? s + b.s : nil))
38
+ end
39
+
40
+ def - (b)
41
+ Hex.new(q - b.q, r - b.r, (s ? s - b.s : nil))
42
+ end
43
+
44
+ # @param a [Hex]
45
+ # @param k [Int]
46
+ def * (k)
47
+ Hex.new(q * k, r * k, (s ? s * k : nil))
48
+ end
49
+
50
+ def hex_length(hex)
51
+ ((hex.q.abs + hex.r.abs + hex.s.abs) / 2).to_i
52
+ end
53
+
54
+ def distance(b)
55
+ hex_length(self - b)
56
+ end
57
+
58
+ def hex_direction(i)
59
+ raise if !(0..5).include?(i)
60
+ HEX_DIRECTIONS_FLAT[i]
61
+ end
62
+
63
+ # (0..5, requires modulo prior)
64
+ def hex_neighbor(i)
65
+ self + hex_direction(i)
66
+ end
67
+ end
68
+
69
+ #TODO(mjy) fix
70
+ def self.point(center, size, i)
71
+ angle_deg = 60.0 * i
72
+ angle_rad = Math::PI / 180 * angle_deg
73
+ Waxy::Geometry::Point.new(
74
+ ((center.x + size) * Math.cos(angle_rad)),
75
+ ((center.y + size ) * Math.sin(angle_rad))
76
+ )
77
+ end
78
+
79
+ def self.hexagon(center, size)
80
+ Hexagon.new(
81
+ outer_coords: (1..6).collect{|i| point(center, size, i)}
82
+ )
83
+ end
84
+
85
+ def self.triangle(center, size, i)
86
+ points = [[0,0]]
87
+ points.push point(center, size, i)
88
+ points.push point(center, size, (i + 1 == 7 ? 1 : i + 1))
89
+ points
90
+ end
91
+
92
+ end
93
+ end
@@ -0,0 +1,130 @@
1
+ module Waxy
2
+ module Geometry
3
+
4
+ class Layout
5
+
6
+ # Waxy::Geometry::Orientation
7
+ attr_accessor :orientation
8
+
9
+ # Waxy::Geometry::Point
10
+ attr_accessor :size
11
+
12
+ # Waxy::Geometry::Point
13
+ attr_accessor :origin
14
+
15
+ # pixels between hexes
16
+ # !! Padding is applied at render time, not geometry compute time, i.e. using this will currently
17
+ # !! break things like pixel_to_hex
18
+ attr_accessor :padding
19
+
20
+ attr_reader :pad_h_offset, :pad_w_offset
21
+
22
+ def initialize(_orientation, _size, _origin, _padding = 0.0)
23
+ @orientation = _orientation
24
+ @size = _size
25
+ @origin = _origin
26
+ @padding = _padding
27
+ reset_padding
28
+ end
29
+
30
+ def hex_to_pixel(hex)
31
+ m = orientation
32
+ x = (m.f0 * hex.q + m.f1 * hex.r) * size.x
33
+ y = (m.f2 * hex.q + m.f3 * hex.r) * size.y
34
+
35
+ Waxy::Geometry::Point.new(x + origin.x, y + origin.y)
36
+ end
37
+
38
+ def pixel_to_hex(p)
39
+ m = orientation
40
+ pt = Waxy::Geometry::Point.new((p.x - origin.x) / size.x,
41
+ (p.y - origin.y) / size.y)
42
+ q = m.b0 * pt.x + m.b1 * pt.y
43
+ r = m.b2 * pt.x + m.b3 * pt.y
44
+
45
+ Waxy::Geometry::FractionalHex.new(q, r, q * -1.0, r * -1.0)
46
+ end
47
+
48
+ # @param corner [Integer]
49
+ def hex_corner_offset(corner, s = nil)
50
+ s ||= size
51
+ angle = hex_corner_angle(corner)
52
+ Waxy::Geometry::Point.new(s.x * Math.cos(angle), s.y * Math.sin(angle))
53
+ end
54
+
55
+ # @param corner [Integer]
56
+ def hex_corner_angle(corner)
57
+ 2.0 * Math::PI * (orientation.start_angle + corner) / 6
58
+ end
59
+
60
+ # @params h [Waxy::Geometry::Hex]
61
+ def polygon_corners(h)
62
+ corners = []
63
+ center = hex_to_pixel(h)
64
+ (0..5).each do |i|
65
+ offset = hex_corner_offset(i)
66
+
67
+ corners.push Waxy::Geometry::Point.new(
68
+ center.x + offset.x,
69
+ center.y + offset.y)
70
+ end
71
+ corners
72
+ end
73
+
74
+ # Departing from Redblob here
75
+
76
+ def point(hex, i, scale = 1.0 )
77
+ center = hex_to_pixel(hex)
78
+
79
+ resized = size.dup
80
+ resized.x = resized.x * scale
81
+ resized.y = resized.y * scale
82
+
83
+ offset = hex_corner_offset(i, resized)
84
+
85
+ Waxy::Geometry::Point.new( center.x + offset.x, center.y + offset.y )
86
+ end
87
+
88
+ def triangle(hex, i)
89
+ scale = hex.size[i]
90
+
91
+ points = [ hex_to_pixel(hex) ]
92
+ points.push point(hex, i, scale)
93
+ points.push point(hex, (i + 1 == 6 ? 0 : i + 1), scale)
94
+ points
95
+ end
96
+
97
+ def triangles(hex)
98
+ (0..5).each_with_index.collect{|t,i| triangle(hex, i) }
99
+ end
100
+
101
+ #
102
+ # Padding methods are not part of Amit's original code. They are not integrated into geometry compute.
103
+ #
104
+
105
+ def reset_padding
106
+ reset_h_padding
107
+ reset_w_padding
108
+ end
109
+
110
+ def reset_h_padding
111
+ @pad_h_offset = 0.0
112
+ end
113
+
114
+ def reset_w_padding
115
+ @pad_w_offset = 0.0
116
+ end
117
+
118
+ def increase_h_padding
119
+ @pad_h_offset += padding
120
+ end
121
+
122
+ def increase_w_padding
123
+ @pad_w_offset += padding
124
+ end
125
+
126
+ end
127
+
128
+ end
129
+ end
130
+
@@ -0,0 +1,50 @@
1
+ module Waxy
2
+ module Geometry
3
+
4
+ class Orientation
5
+ attr_accessor :f0, :f1, :f2, :f3,
6
+ :b0, :b1, :b2, :b3,
7
+ :start_angle
8
+
9
+ def initialize(_f0, _f1, _f2, _f3, _b0, _b1, _b2, _b3, _start_angle)
10
+ @f0 = _f0
11
+ @f1 = _f1
12
+ @f2 = _f2
13
+ @f3 = _f3
14
+ @b0 = _b0
15
+ @b1 = _b1
16
+ @b2 = _b2
17
+ @b3 = _b3
18
+ @start_angle = _start_angle
19
+ end
20
+
21
+ LAYOUT_POINTY = Orientation.new(
22
+ Math.sqrt(3.0),
23
+ Math.sqrt(3.0) / 2.0,
24
+ 0.0,
25
+ 3.0 / 2.0,
26
+ Math.sqrt(3.0) / 3.0,
27
+ -1.0 / 3.0,
28
+ 0.0,
29
+ 2.0 / 3.0,
30
+ 0.5
31
+ )
32
+
33
+ LAYOUT_FLAT = Orientation.new(
34
+ 3.0 / 2.0,
35
+ 0.0,
36
+ Math.sqrt(3.0) / 2.0,
37
+ Math.sqrt(3.0),
38
+ 2.0 / 3.0,
39
+ 0.0,
40
+ -1.0 / 3.0,
41
+ Math.sqrt(3.0) / 3.0,
42
+ 0.0
43
+ )
44
+
45
+
46
+ end
47
+
48
+ end
49
+ end
50
+
@@ -0,0 +1,30 @@
1
+ module Waxy
2
+ module Geometry
3
+
4
+ class Point
5
+ attr_accessor :x, :y
6
+
7
+ def initialize(_x, _y)
8
+ @x = _x
9
+ @y = _y
10
+ end
11
+
12
+ def hex_to_pixel(layout, h)
13
+ m = layout.orientation
14
+ x = (m.f0 * h.q + m.f1 * h.r) * layout.size.x
15
+ y = (m.f2 * h.q + m.f3 * h.r) * layout.size.y
16
+ return Point.new(x + layout.origin.x, y + layout.origin.y)
17
+ end
18
+
19
+ def hex_corner_offset(layout, corner)
20
+ size = Point.new(layout.size)
21
+ angle = 2.0 * M_PI * (layout.orientation.start_angle + corner ) / 6
22
+ Point.new(size.x * cos(angle), size.y * sin(angle))
23
+ end
24
+
25
+
26
+
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,71 @@
1
+ module Waxy
2
+
3
+ # Instances of Meta contain attributes
4
+ # that describe the visual appearance of a single hexagon.
5
+ class Meta
6
+
7
+ ## -- Attributes for solid hex layouts
8
+
9
+ # Hex border SVG stroke
10
+ attr_accessor :stroke
11
+
12
+ # Hex fill
13
+ # not applicable to all templates
14
+ attr_accessor :fill
15
+
16
+ # a URL for the whole hexagon
17
+ # not applicable to all templates
18
+ attr_accessor :link
19
+
20
+ # title value for hex <a>
21
+ attr_accessor :link_title
22
+
23
+ ## -- Attributes for "pie" layouts
24
+
25
+ # Array of 6 * (0.0..1.0)
26
+ # scales "pie" slices
27
+ attr_accessor :size
28
+
29
+ # An Array (0..5) of links, one for each slice of 'Pie'
30
+ attr_accessor :pie_links
31
+
32
+ # An Array (0..5) of SVG color values
33
+ attr_accessor :colors
34
+
35
+ # @return [Array]
36
+ # 6 strings with SVG color= values
37
+ def colors
38
+ @colors.nil? ? Waxy::COLORS.values : @colors
39
+ end
40
+
41
+ def pie_links
42
+ @pie_links.nil? ? [] : @pie_links
43
+ end
44
+
45
+ # Describes how "full" a pie hexagon is
46
+ def sum_size
47
+ size.sum
48
+ end
49
+
50
+ # Helper methods
51
+
52
+ def hex_link_start
53
+ return nil unless link
54
+ [
55
+ '<a href="' + link + '"',
56
+ 'class="waxy__link"',
57
+ '>'
58
+ ].compact.join(' ')
59
+ end
60
+
61
+ def hex_link_title
62
+ return nil unless link_title
63
+ "<title>#{link_title}</title>"
64
+ end
65
+
66
+ def hex_link_end
67
+ '</a>' if link
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,20 @@
1
+ require 'erb'
2
+ require 'tilt'
3
+
4
+ require_relative 'render/svg'
5
+ require_relative 'render/canvas'
6
+
7
+ module Waxy
8
+
9
+ module Render
10
+ COLORS = {
11
+ 1 => 'yellow',
12
+ 2 => 'orange',
13
+ 3 => 'red',
14
+ 4 => 'purple',
15
+ 5 => 'blue',
16
+ 6 => 'green'
17
+ }
18
+
19
+ end
20
+ end