grid_generator 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.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/CODE_OF_CONDUCT.md +84 -0
  4. data/Gemfile +10 -0
  5. data/Gemfile.lock +23 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +39 -0
  8. data/Rakefile +12 -0
  9. data/grid_generator.gemspec +36 -0
  10. data/lib/grid_generator/arrows/arrow.rb +29 -0
  11. data/lib/grid_generator/arrows/diagonal_down_arrow.rb +107 -0
  12. data/lib/grid_generator/arrows/diagonal_up_arrow.rb +108 -0
  13. data/lib/grid_generator/arrows/horizontal_arrow.rb +108 -0
  14. data/lib/grid_generator/arrows/vertical_arrow.rb +108 -0
  15. data/lib/grid_generator/base_element.rb +30 -0
  16. data/lib/grid_generator/cubic/bordered_grid.rb +129 -0
  17. data/lib/grid_generator/cubic/facing_grid.rb +109 -0
  18. data/lib/grid_generator/cubic/facing_square_factory.rb +38 -0
  19. data/lib/grid_generator/cubic/front_grid.rb +27 -0
  20. data/lib/grid_generator/cubic/grid.rb +146 -0
  21. data/lib/grid_generator/cubic/iso_view.rb +30 -0
  22. data/lib/grid_generator/cubic/right_grid.rb +27 -0
  23. data/lib/grid_generator/cubic/square_factory.rb +46 -0
  24. data/lib/grid_generator/cubic/top_grid.rb +27 -0
  25. data/lib/grid_generator/face_parser.rb +43 -0
  26. data/lib/grid_generator/megaminx/common.rb +94 -0
  27. data/lib/grid_generator/megaminx/element_factory.rb +52 -0
  28. data/lib/grid_generator/megaminx/face.rb +79 -0
  29. data/lib/grid_generator/pyraminx/grid.rb +83 -0
  30. data/lib/grid_generator/pyraminx/triangle_factory.rb +45 -0
  31. data/lib/grid_generator/skewb/left_element_factory.rb +90 -0
  32. data/lib/grid_generator/skewb/left_skewb_grid.rb +43 -0
  33. data/lib/grid_generator/skewb/right_element_factory.rb +90 -0
  34. data/lib/grid_generator/skewb/right_skewb_grid.rb +43 -0
  35. data/lib/grid_generator/skewb/skewb_grid.rb +62 -0
  36. data/lib/grid_generator/skewb/top_element_factory.rb +90 -0
  37. data/lib/grid_generator/skewb/top_skewb_grid.rb +43 -0
  38. data/lib/grid_generator/square_one/element.rb +60 -0
  39. data/lib/grid_generator/square_one/element_factory.rb +89 -0
  40. data/lib/grid_generator/square_one/face.rb +82 -0
  41. data/lib/grid_generator/square_one_face_parser.rb +61 -0
  42. data/lib/grid_generator/version.rb +5 -0
  43. data/lib/grid_generator.rb +107 -0
  44. data/sig/grid_generator.rbs +4 -0
  45. metadata +103 -0
@@ -0,0 +1,62 @@
1
+ require './lib/grid_generator/face_parser'
2
+
3
+ module GridGenerator
4
+ module Skewb
5
+ class SkewbGrid
6
+ def initialize(x:, y:, units: , elements: )
7
+ @x, @y = x, y
8
+ @units = units
9
+ @elements = case elements
10
+ when String
11
+ FaceParser.new(elements).to_a
12
+ when Array
13
+ elements
14
+ else
15
+ raise ArgumentError, "squares must be array or string"
16
+ end
17
+ end
18
+
19
+ attr_reader :x, :y, :units, :elements
20
+
21
+ def side_size
22
+ elements.size - 1
23
+ end
24
+
25
+ def build_element(row_num, col_num, data)
26
+ if data
27
+ factory_class.new(
28
+ grid_x: x,
29
+ grid_y: y,
30
+ row_num: row_num,
31
+ col_num: col_num,
32
+ side_size: side_size,
33
+ units: units,
34
+ colour: data[:colour],
35
+ opacity: data[:opacity]
36
+ ).build
37
+ else
38
+ nil
39
+ end
40
+ end
41
+
42
+ def border_points_string
43
+ border_points.map { |x| x.join(',') }.join(' ')
44
+ end
45
+
46
+ def element_shapes
47
+ elements.each_with_index.map do |row, row_num|
48
+ row.each_with_index.map do |col, col_num|
49
+ build_element(row_num, col_num, col)
50
+ end
51
+ end.flatten.compact
52
+ end
53
+
54
+ def as_json
55
+ {
56
+ "border_points_string" => border_points_string,
57
+ "element_shapes" => element_shapes.map(&:as_json)
58
+ }
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,90 @@
1
+ module GridGenerator
2
+ module Skewb
3
+ class TopElementFactory
4
+ def initialize(grid_x:, grid_y:, row_num:, col_num:, side_size:, units:, colour:, opacity:)
5
+ @grid_x, @grid_y = grid_x, grid_y
6
+ @row_num, @col_num = row_num, col_num
7
+ @side_size, @units = side_size, units
8
+ @colour, @opacity = colour, opacity
9
+ end
10
+
11
+ attr_reader :grid_x, :grid_y, :row_num, :col_num, :side_size, :units, :colour, :opacity
12
+
13
+ def x
14
+ @x ||= case [row_num, col_num]
15
+ when [0, 0] # Top Back
16
+ grid_x+(side_size-1)*2*units
17
+ when [0, side_size] # Top Right
18
+ grid_x+((side_size*2)-1)*2*units
19
+ when [side_size, 0] # Top Left
20
+ grid_x
21
+ when [side_size, side_size] # Top Front
22
+ grid_x+(side_size-1)*2*units
23
+ when [(side_size/2),(side_size/2)] # Top Center
24
+ grid_x+(side_size/2)*2*units
25
+ else
26
+ nil
27
+ end
28
+ end
29
+
30
+ def y
31
+ @y ||= case [row_num, col_num]
32
+ when [0, 0] # Top Back
33
+ grid_y
34
+ when [0, side_size] # Top Right
35
+ grid_y+(side_size-1)*units
36
+ when [side_size, 0] # Top Left
37
+ grid_y+(side_size-1)*units
38
+ when [side_size, side_size] # Top Front
39
+ grid_y+(side_size*2-1)*units
40
+ when [(side_size/2),(side_size/2)] # Top Center
41
+ grid_y+(side_size/2)*units
42
+ else
43
+ nil
44
+ end
45
+ end
46
+
47
+ def points
48
+ case [row_num, col_num]
49
+ when [0, 0] # Top Back
50
+ [
51
+ [ x+2*units, y ],
52
+ [ x+4*units, y+units ],
53
+ [ x, y+units ]
54
+ ]
55
+ when [0, side_size] # Top Right
56
+ [
57
+ [ x, y ],
58
+ [ x+2*units, y+units ],
59
+ [ x, y+2*units ]
60
+ ]
61
+ when [side_size, 0] # Top Left
62
+ [
63
+ [ x+2*units, y ],
64
+ [ x+2*units, y+2*units ],
65
+ [ x, y+units ]
66
+ ]
67
+ when [side_size, side_size] # Top Front
68
+ [
69
+ [ x, y ],
70
+ [ x+4*units, y ],
71
+ [ x+2*units, y+units ]
72
+ ]
73
+ when [(side_size/2), (side_size/2)] # Top Center
74
+ [
75
+ [ x, y ],
76
+ [ x+4*units, y ],
77
+ [ x+4*units, y+2*units ],
78
+ [ x, y+2*units ]
79
+ ]
80
+ else
81
+ nil
82
+ end
83
+ end
84
+
85
+ def build
86
+ GridGenerator::BaseElement.new(points: points, colour: colour, opacity: opacity)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,43 @@
1
+ require './lib/grid_generator/skewb/skewb_grid.rb'
2
+ require './lib/grid_generator/skewb/top_element_factory.rb'
3
+
4
+ module GridGenerator
5
+ module Skewb
6
+ class TopSkewbGrid < Skewb::SkewbGrid
7
+ def factory_class
8
+ GridGenerator::Skewb::TopElementFactory
9
+ end
10
+
11
+ def border_points
12
+ [
13
+ [ x + side_size*2*units, y ],
14
+ [ x + side_size*4*units, y + side_size*units ],
15
+ [ x + side_size*2*units, y + side_size*2*units ],
16
+ [ x, y + side_size*units ]
17
+ ]
18
+ end
19
+
20
+ def rows
21
+ Array.new(side_size) do |i|
22
+ {
23
+ x1: x + 2*units,
24
+ y1: y + (2*i+1)*units,
25
+ x2: x + 6*units,
26
+ y2: y + (2*i+1)*units
27
+ }
28
+ end
29
+ end
30
+
31
+ def columns
32
+ Array.new(side_size) do |i|
33
+ {
34
+ x1: x + (4*i+2)*units,
35
+ y1: y + units,
36
+ x2: x + (4*i+2)*units,
37
+ y2: y + 3*units
38
+ }
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,60 @@
1
+ require 'matrix'
2
+
3
+ module GridGenerator
4
+ module SquareOne
5
+ class Element
6
+ def initialize(x:, y:, units:, offset: , colour: , opacity: )
7
+ @x, @y = x, y
8
+ @units = units
9
+ @offset = offset
10
+ @colour = colour
11
+ @opacity = opacity
12
+ end
13
+
14
+ attr_reader :x, :y, :units, :offset, :colour, :opacity
15
+
16
+ def ==(other)
17
+ self.x == other.x &&
18
+ self.y == other.y &&
19
+ self.units == other.units &&
20
+ self.colour == other.colour &&
21
+ self.opacity == other.opacity
22
+ end
23
+
24
+ def offset_radians
25
+ offset*Math::PI/6
26
+ end
27
+
28
+ def half_edge_width
29
+ @half_edge_width ||= half_face_size * Math.tan(Math::PI/12)
30
+ end
31
+
32
+ def half_face_size
33
+ @half_face_size ||= face_size / 2
34
+ end
35
+
36
+ def face_size
37
+ @face_size ||= 3 * units
38
+ end
39
+
40
+ def rotation_point
41
+ Matrix.column_vector([x+half_face_size, y+half_face_size])
42
+ end
43
+
44
+ def rotation_matrix
45
+ @rotation_matrix ||= Matrix[
46
+ [Math.cos(offset_radians), -1*Math.sin(offset_radians)],
47
+ [Math.sin(offset_radians), Math.cos(offset_radians)]
48
+ ]
49
+ end
50
+
51
+ def points
52
+ base_points.map { |p| (rotation_matrix * (p - rotation_point)) + rotation_point }
53
+ end
54
+
55
+ def points_string
56
+ points.map { |p| "#{p[0,0].round},#{p[1,0].round}" }.join(' ')
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,89 @@
1
+ require 'matrix'
2
+ require './lib/grid_generator/base_element'
3
+
4
+ module GridGenerator
5
+ module SquareOne
6
+ class ElementFactory
7
+ def initialize(x: , y:, units:, shape:, offset:, colour:, opacity:)
8
+ @x, @y = x, y
9
+ @units = units
10
+ @shape = shape
11
+ @offset = offset
12
+ @colour = colour
13
+ @opacity = opacity
14
+ end
15
+
16
+ attr_reader :x, :y, :units, :shape, :offset, :colour, :opacity
17
+
18
+ def base_points
19
+ case shape
20
+ when :edge
21
+ [
22
+ Matrix.column_vector([x+half_face_size-half_edge_width, y]),
23
+ Matrix.column_vector([x+half_face_size+half_edge_width, y]),
24
+ Matrix.column_vector([x+half_face_size, y+half_face_size])
25
+ ]
26
+ when :corner
27
+ [
28
+ Matrix.column_vector([x+half_face_size+half_edge_width, y]),
29
+ Matrix.column_vector([x+face_size, y]),
30
+ Matrix.column_vector([x+face_size, y+half_face_size-half_edge_width]),
31
+ Matrix.column_vector([x+half_face_size, y+half_face_size])
32
+ ]
33
+ when :middle
34
+ [
35
+ Matrix.column_vector([x+half_face_size+half_edge_width, y]),
36
+ Matrix.column_vector([x+face_size, y]),
37
+ Matrix.column_vector([x+face_size, y+face_size]),
38
+ Matrix.column_vector([x+half_face_size-half_edge_width, y+face_size])
39
+ ]
40
+ when :middle_flipped
41
+ @base_points ||= [
42
+ Matrix.column_vector([x+half_face_size-half_edge_width, y]),
43
+ Matrix.column_vector([x+face_size, y]),
44
+ Matrix.column_vector([x+face_size, y+face_size]),
45
+ Matrix.column_vector([x+half_face_size+half_edge_width, y+face_size])
46
+ ]
47
+ else
48
+ raise ArgumentError, "unknown face shape: #{edge}"
49
+ end
50
+ end
51
+
52
+ def offset_radians
53
+ offset*Math::PI/6
54
+ end
55
+
56
+ def half_edge_width
57
+ @half_edge_width ||= half_face_size * Math.tan(Math::PI/12)
58
+ end
59
+
60
+ def half_face_size
61
+ @half_face_size ||= face_size / 2
62
+ end
63
+
64
+ def face_size
65
+ @face_size ||= 3 * units
66
+ end
67
+
68
+ def rotation_point
69
+ Matrix.column_vector([x+half_face_size, y+half_face_size])
70
+ end
71
+
72
+ def rotation_matrix
73
+ @rotation_matrix ||= Matrix[
74
+ [Math.cos(offset_radians), -1*Math.sin(offset_radians)],
75
+ [Math.sin(offset_radians), Math.cos(offset_radians)]
76
+ ]
77
+ end
78
+
79
+
80
+ def points
81
+ base_points.map { |p| (rotation_matrix * (p - rotation_point)) + rotation_point }
82
+ end
83
+
84
+ def build
85
+ GridGenerator::BaseElement.new(points: points, colour: colour, opacity: opacity)
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,82 @@
1
+ require './lib/grid_generator/square_one_face_parser'
2
+ require './lib/grid_generator/square_one/element_factory'
3
+
4
+ module GridGenerator
5
+ module SquareOne
6
+ class Face
7
+ def initialize(x:, y: , units: , elements:, axis_direction: :forward)
8
+ @x, @y = x, y
9
+ @units = units
10
+ @elements = case elements
11
+ when String
12
+ SquareOneFaceParser.new(elements).to_a
13
+ when Array
14
+ elements
15
+ else
16
+ raise ArgumentError, "squares must be array or string"
17
+ end
18
+ @axis_direction = axis_direction
19
+ end
20
+
21
+ attr_reader :x, :y, :units, :elements, :axis_direction
22
+
23
+ def half_edge_width
24
+ @half_edge_width ||= half_face_size * Math.tan(Math::PI/12)
25
+ end
26
+
27
+ def half_face_size
28
+ @half_face_size ||= face_size / 2
29
+ end
30
+
31
+ def face_size
32
+ @face_size ||= 3 * units
33
+ end
34
+
35
+ def axis
36
+ if axis_direction == :back
37
+ back_axis
38
+ else
39
+ forward_axis
40
+ end
41
+ end
42
+
43
+ def forward_axis
44
+ {
45
+ x1: x+half_face_size+half_edge_width,
46
+ y1: y,
47
+ x2: x+half_face_size-half_edge_width,
48
+ y2: y+face_size
49
+ }
50
+ end
51
+
52
+ def back_axis
53
+ {
54
+ x1: x+half_face_size-half_edge_width,
55
+ y1: y,
56
+ x2: x+half_face_size+half_edge_width,
57
+ y2: y+face_size
58
+ }
59
+ end
60
+
61
+ def element_shapes
62
+ elements.map do |element|
63
+ GridGenerator::SquareOne::ElementFactory.new(
64
+ x: x,
65
+ y: y,
66
+ units: units,
67
+ shape: element[:shape],
68
+ offset: element[:offset],
69
+ colour: element[:colour],
70
+ opacity: element[:opacity]
71
+ ).build
72
+ end
73
+ end
74
+
75
+ def as_json
76
+ {
77
+ "element_shapes" => element_shapes.map(&:as_json)
78
+ }
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,61 @@
1
+ module GridGenerator
2
+ class SquareOneFaceParser
3
+ COLOURS = {
4
+ 'w' => '#ffffff',
5
+ 'y' => '#ffff00',
6
+ 'b' => '#0000ff',
7
+ 'g' => '#00ff00',
8
+ 'r' => '#ff0000',
9
+ 'o' => '#ff8000',
10
+ 'f' => '#d0d0d0'
11
+ }
12
+
13
+ OPACITY = {
14
+ full: 1,
15
+ faded: 0.4
16
+ }
17
+
18
+ SHAPES = {
19
+ 'e' => :edge,
20
+ 'c' => :corner,
21
+ 'm' => :middle,
22
+ 'f' => :middle_flipped
23
+ }
24
+
25
+ ELEMENT_DEFINITION = /(e|c|m|f)(\d+)([a-zA-Z])/
26
+
27
+ def initialize(string)
28
+ @string = string
29
+ end
30
+
31
+ attr_reader :string
32
+
33
+ def to_a
34
+ string.split(',').map(&:strip).map do |col|
35
+ shape_def, offset_def, colour_def = ELEMENT_DEFINITION.match(col).captures
36
+ {
37
+ shape: shape(shape_def),
38
+ offset: offset(offset_def),
39
+ colour: colour(colour_def),
40
+ opacity: opacity(colour_def)
41
+ }
42
+ end
43
+ end
44
+
45
+ def shape(definition)
46
+ SHAPES[definition]
47
+ end
48
+
49
+ def offset(definition)
50
+ definition.to_i
51
+ end
52
+
53
+ def colour(definition)
54
+ COLOURS[definition.downcase]
55
+ end
56
+
57
+ def opacity(definition)
58
+ OPACITY[(/[[:upper:]]/.match(definition) ? :full : :faded)]
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GridGenerator
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "grid_generator/version"
4
+
5
+ require './lib/grid_generator/cubic/iso_view.rb'
6
+ require './lib/grid_generator/cubic/top_grid'
7
+ require './lib/grid_generator/cubic/front_grid'
8
+ require './lib/grid_generator/cubic/right_grid'
9
+ require './lib/grid_generator/cubic/facing_grid'
10
+ require './lib/grid_generator/cubic/bordered_grid'
11
+ require './lib/grid_generator/cubic/square_factory'
12
+ require './lib/grid_generator/skewb/top_skewb_grid'
13
+ require './lib/grid_generator/skewb/left_skewb_grid'
14
+ require './lib/grid_generator/skewb/right_skewb_grid'
15
+ require './lib/grid_generator/square_one/face'
16
+ require './lib/grid_generator/arrows/vertical_arrow'
17
+ require './lib/grid_generator/arrows/horizontal_arrow'
18
+ require './lib/grid_generator/arrows/diagonal_down_arrow'
19
+ require './lib/grid_generator/arrows/diagonal_up_arrow'
20
+ require './lib/grid_generator/pyraminx/grid'
21
+ require './lib/grid_generator/megaminx/face'
22
+
23
+ module GridGenerator
24
+ def self.iso_view(args)
25
+ Cubic::IsoView.new(**args)
26
+ end
27
+
28
+ def self.top_grid(args)
29
+ Cubic::TopGrid.new(**args)
30
+ end
31
+
32
+ def self.front_grid(args)
33
+ Cubic::FrontGrid.new(**args)
34
+ end
35
+
36
+ def self.right_grid(args)
37
+ Cubic::RightGrid.new(**args)
38
+ end
39
+
40
+ def self.facing_grid(args)
41
+ Cubic::FacingGrid.new(**args)
42
+ end
43
+
44
+ def self.bordered_grid(args)
45
+ Cubic::BorderedGrid.new(**args)
46
+ end
47
+
48
+ def self.top_square(args)
49
+ #??
50
+ Cubic::TopSquareFactory.new(**args).build
51
+ end
52
+
53
+ def self.front_square(args)
54
+ #??
55
+ Cubic::FrontSquareFactory.new(**args).build
56
+ end
57
+
58
+ def self.right_square(args)
59
+ #??
60
+ Cubic::RightSquareFactory.new(**args).build
61
+ end
62
+
63
+ def self.top_skewb_grid(args)
64
+ Skewb::TopSkewbGrid.new(**args)
65
+ end
66
+
67
+ def self.left_skewb_grid(args)
68
+ Skewb::LeftSkewbGrid.new(**args)
69
+ end
70
+
71
+ def self.right_skewb_grid(args)
72
+ Skewb::RightSkewbGrid.new(**args)
73
+ end
74
+
75
+ def self.square_one_face(args)
76
+ SquareOne::Face.new(**args)
77
+ end
78
+
79
+ def self.vertical_arrow(args)
80
+ Arrows::VerticalArrow.new(**args)
81
+ end
82
+
83
+ def self.horizontal_arrow(args)
84
+ Arrows::HorizontalArrow.new(**args)
85
+ end
86
+
87
+ def self.diagonal_down_arrow(args)
88
+ Arrows::DiagonalDownArrow.new(**args)
89
+ end
90
+
91
+ def self.diagonal_up_arrow(args)
92
+ Arrows::DiagonalUpArrow.new(**args)
93
+ end
94
+
95
+ def self.pyraminx_grid(args)
96
+ Pyraminx::Grid.new(**args)
97
+ end
98
+
99
+ def self.pyraminx_triangle(args)
100
+ Pyraminx::Triangle.new(**args)
101
+ end
102
+
103
+ def self.megaminx_face(args)
104
+ Megaminx::Face.new(**args)
105
+ end
106
+ end
107
+
@@ -0,0 +1,4 @@
1
+ module GridGenerator
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end