waxy 0.1.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.
@@ -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