ivan 0.1.0.pre
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/lib/composition.rb +29 -0
- data/lib/geometry.rb +16 -0
- data/lib/glyph.rb +47 -0
- data/lib/has_transforms.rb +25 -0
- data/lib/ivan.rb +61 -0
- data/lib/models/cube.yml +51 -0
- data/lib/models/square.yml +23 -0
- data/lib/models/tetrahedron.yml +27 -0
- data/lib/point.rb +153 -0
- data/lib/sender.rb +64 -0
- data/lib/teensyv_sender.rb +41 -0
- metadata +194 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: dcd063d2fffdb9889308d5c7e7fb2a43ccbc4e14
|
4
|
+
data.tar.gz: 06dafb619d91ba6f672a7dc9f339dbdc913a76eb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: da3adf2ac9a6f67a2a4d64b03be438765e1ce98b2a2d60489f2d8fa13bd7a83fbd3dcc3636c1cdaf0ee6f4b5d9604e47c445081c4ad5e84269d386c2efe2040f
|
7
|
+
data.tar.gz: 6ba4cf550c4125084211595819d5704f2a8e93af7323a02a7c652dd988700cddebebf8ed9b6efa28db1b20e600f23804aa1a06d6533020a103ac571a74059497
|
data/lib/composition.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
class Composition
|
2
|
+
attr_reader :buffer
|
3
|
+
|
4
|
+
def initialize(buffer)
|
5
|
+
@buffer = buffer
|
6
|
+
end
|
7
|
+
|
8
|
+
def clip_to_boundary(boundary)
|
9
|
+
@buffer.each_slice(2).with_index do |slice, i|
|
10
|
+
index = i * 2
|
11
|
+
clipped_points = Point.clip_to_boundary(boundary, slice)
|
12
|
+
@buffer[index] = clipped_points[0]
|
13
|
+
@buffer[index+1] = clipped_points[1]
|
14
|
+
end
|
15
|
+
@buffer.reject! {|p| !p }
|
16
|
+
return self
|
17
|
+
end
|
18
|
+
|
19
|
+
def normalize(boundary)
|
20
|
+
scale = 1.0
|
21
|
+
trans = 127
|
22
|
+
@buffer = @buffer.map do |point|
|
23
|
+
point \
|
24
|
+
.scale([scale, scale, 0])
|
25
|
+
.translate([trans, trans, 0])
|
26
|
+
end
|
27
|
+
return self.clip_to_boundary(boundary)
|
28
|
+
end
|
29
|
+
end
|
data/lib/geometry.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
class LineStructError < Exception
|
2
|
+
end
|
3
|
+
|
4
|
+
class LineIndexRangeError < Exception
|
5
|
+
end
|
6
|
+
|
7
|
+
Struct.new("Geometry", :points, :lines) do
|
8
|
+
def valid?
|
9
|
+
lines.each do |l|
|
10
|
+
raise LineStructError, "This line is not a 2-tuple" \
|
11
|
+
if l.length != 2
|
12
|
+
raise LineIndexRangeError, "Line vertex with invalid point index" \
|
13
|
+
if not points[l[0]] or not points[l[1]]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/glyph.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
class Glyph
|
2
|
+
extend HasTransforms
|
3
|
+
attr_reader :children
|
4
|
+
|
5
|
+
has_transforms_for Point
|
6
|
+
|
7
|
+
def self.new_from_model(model)
|
8
|
+
return new(Ivan::Models[model])
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(geometry)
|
12
|
+
if geometry.valid? then
|
13
|
+
@points = geometry[:points].map do |p|
|
14
|
+
Point.new(*p)
|
15
|
+
end
|
16
|
+
@lines = geometry[:lines]
|
17
|
+
@children = []
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def << (child_glyph)
|
22
|
+
@children << child_glyph
|
23
|
+
end
|
24
|
+
|
25
|
+
def project(x = 0, y = 0, z = Ivan.default_focal_length)
|
26
|
+
@points = @points.map do |p|
|
27
|
+
p.project(x, y, z)
|
28
|
+
end
|
29
|
+
@children = @children.map do |c|
|
30
|
+
c.send(:project, x, y, z)
|
31
|
+
end
|
32
|
+
return self
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_buffer
|
36
|
+
my_instructions = []
|
37
|
+
@lines.each do |l|
|
38
|
+
l.each do |p|
|
39
|
+
my_instructions << @points[p]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
self.children.each do |c|
|
43
|
+
my_instructions << c.to_buffer
|
44
|
+
end
|
45
|
+
return my_instructions.flatten
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module HasTransforms
|
2
|
+
private
|
3
|
+
def delegate_transforms(transforms)
|
4
|
+
transforms.each do |method_name|
|
5
|
+
define_method(method_name) do |param|
|
6
|
+
@points = @points.map do |p|
|
7
|
+
p.send(method_name, param)
|
8
|
+
end
|
9
|
+
@children = @children.map do |c|
|
10
|
+
c.send(method_name, param)
|
11
|
+
end
|
12
|
+
return self
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def has_transforms_for(*class_names)
|
18
|
+
transform_methods = []
|
19
|
+
class_names.each do |c|
|
20
|
+
transform_methods += c.transforms
|
21
|
+
end
|
22
|
+
transform_methods.uniq!
|
23
|
+
delegate_transforms(transform_methods)
|
24
|
+
end
|
25
|
+
end
|
data/lib/ivan.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
require_relative 'point'
|
4
|
+
require_relative 'has_transforms'
|
5
|
+
require_relative 'geometry'
|
6
|
+
require_relative 'glyph'
|
7
|
+
require_relative 'composition'
|
8
|
+
require_relative 'sender'
|
9
|
+
require_relative 'teensyv_sender'
|
10
|
+
|
11
|
+
module Ivan
|
12
|
+
@model_path = File.join(File.dirname(File.expand_path(__FILE__)), 'models')
|
13
|
+
@default_focal_length = -125.0
|
14
|
+
Models = {}
|
15
|
+
|
16
|
+
def self.models
|
17
|
+
return Models
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.set_focal_length(val)
|
21
|
+
@default_focal_length = val
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.set_model_path(path)
|
25
|
+
@model_path = path
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.default_focal_length
|
29
|
+
return @default_focal_length
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.load_models(*model_names)
|
33
|
+
model_names.each do |model_name|
|
34
|
+
model_file = File.read("#{ @model_path }/#{ model_name }.yml")
|
35
|
+
if model_file then
|
36
|
+
geom = YAML.load(model_file)
|
37
|
+
if geom.valid? then
|
38
|
+
Models[model_name] = geom
|
39
|
+
end
|
40
|
+
else
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
return true
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.copy_model(source, destination)
|
48
|
+
if Models[source] then
|
49
|
+
Models[destination] = Models[source]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.save_model(model_name)
|
54
|
+
yaml_out = YAML.dump(Models[model_name])
|
55
|
+
if yaml_out then
|
56
|
+
file_out = File.open("#{ @model_path }/#{model_name}.yml","w")
|
57
|
+
file_out << yaml_out
|
58
|
+
file_out.close
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/models/cube.yml
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/struct:Struct::Geometry
|
2
|
+
points:
|
3
|
+
- - -1
|
4
|
+
- -1
|
5
|
+
- 1
|
6
|
+
- - 1
|
7
|
+
- -1
|
8
|
+
- 1
|
9
|
+
- - 1
|
10
|
+
- 1
|
11
|
+
- 1
|
12
|
+
- - -1
|
13
|
+
- 1
|
14
|
+
- 1
|
15
|
+
- - -1
|
16
|
+
- 1
|
17
|
+
- -1
|
18
|
+
- - 1
|
19
|
+
- 1
|
20
|
+
- -1
|
21
|
+
- - -1
|
22
|
+
- -1
|
23
|
+
- -1
|
24
|
+
- - 1
|
25
|
+
- -1
|
26
|
+
- -1
|
27
|
+
lines:
|
28
|
+
- - 0
|
29
|
+
- 1
|
30
|
+
- - 1
|
31
|
+
- 2
|
32
|
+
- - 2
|
33
|
+
- 3
|
34
|
+
- - 3
|
35
|
+
- 0
|
36
|
+
- - 3
|
37
|
+
- 4
|
38
|
+
- - 2
|
39
|
+
- 5
|
40
|
+
- - 1
|
41
|
+
- 7
|
42
|
+
- - 4
|
43
|
+
- 6
|
44
|
+
- - 4
|
45
|
+
- 5
|
46
|
+
- - 0
|
47
|
+
- 6
|
48
|
+
- - 6
|
49
|
+
- 7
|
50
|
+
- - 7
|
51
|
+
- 5
|
@@ -0,0 +1,27 @@
|
|
1
|
+
--- !ruby/struct:Struct::Geometry
|
2
|
+
points:
|
3
|
+
- - 1
|
4
|
+
- 1
|
5
|
+
- 1
|
6
|
+
- - -1
|
7
|
+
- -1
|
8
|
+
- 1
|
9
|
+
- - -1
|
10
|
+
- 1
|
11
|
+
- -1
|
12
|
+
- - 1
|
13
|
+
- -1
|
14
|
+
- -1
|
15
|
+
lines:
|
16
|
+
- - 0
|
17
|
+
- 1
|
18
|
+
- - 0
|
19
|
+
- 2
|
20
|
+
- - 0
|
21
|
+
- 3
|
22
|
+
- - 1
|
23
|
+
- 2
|
24
|
+
- - 1
|
25
|
+
- 3
|
26
|
+
- - 2
|
27
|
+
- 3
|
data/lib/point.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
class Point
|
2
|
+
include Math
|
3
|
+
attr_reader :x, :y, :z
|
4
|
+
|
5
|
+
INSIDE = 0; # 0000
|
6
|
+
LEFT = 1; # 0001
|
7
|
+
RIGHT = 2; # 0010
|
8
|
+
BOTTOM = 4; # 0100
|
9
|
+
TOP = 8; # 1000
|
10
|
+
|
11
|
+
def initialize (x = 0, y = 0, z = 0)
|
12
|
+
@x = x;
|
13
|
+
@y = y;
|
14
|
+
@z = z;
|
15
|
+
end
|
16
|
+
|
17
|
+
def screen_safe?(boundary)
|
18
|
+
return ( @x >= boundary[:x_min] and \
|
19
|
+
@x <= boundary[:x_max] and \
|
20
|
+
@y >= boundary[:y_min] and \
|
21
|
+
@y <= boundary[:y_max] and \
|
22
|
+
@z == 0 )
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.interpolate(point1, point2, weight)
|
26
|
+
return Point.new(
|
27
|
+
point1.x + (point2.x - point1.x) * weight,
|
28
|
+
point1.y + (point2.y - point1.y) * weight,
|
29
|
+
point1.z + (point2.z - point1.z) * weight,
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def outcode(boundary)
|
34
|
+
outcode = 0
|
35
|
+
|
36
|
+
if self.x < boundary[:x_min] then
|
37
|
+
outcode |= LEFT
|
38
|
+
end
|
39
|
+
if self.x > boundary[:x_max] then
|
40
|
+
outcode |= RIGHT
|
41
|
+
end
|
42
|
+
if self.y < boundary[:y_min] then
|
43
|
+
outcode |= BOTTOM
|
44
|
+
end
|
45
|
+
if self.y > boundary[:y_max] then
|
46
|
+
outcode |= TOP
|
47
|
+
end
|
48
|
+
|
49
|
+
return outcode
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.clip_to_boundary(boundary, points)
|
53
|
+
accepted = false
|
54
|
+
|
55
|
+
while !accepted do
|
56
|
+
outcode0 = points[0].outcode(boundary)
|
57
|
+
outcode1 = points[1].outcode(boundary)
|
58
|
+
if ( (outcode0 | outcode1) == 0 ) then
|
59
|
+
return points
|
60
|
+
elsif (outcode0 & outcode1 != 0) then
|
61
|
+
return [nil, nil]
|
62
|
+
else
|
63
|
+
if (outcode0 != 0) then
|
64
|
+
outcode_out = outcode0
|
65
|
+
else
|
66
|
+
outcode_out = outcode1
|
67
|
+
end
|
68
|
+
x0 = points[0].x
|
69
|
+
y0 = points[0].y
|
70
|
+
x1 = points[1].x
|
71
|
+
y1 = points[1].y
|
72
|
+
if (outcode_out & TOP != 0) then
|
73
|
+
x = x0 + (x1 - x0) * (boundary[:y_max] - y0) / (y1 - y0)
|
74
|
+
y = boundary[:y_max]
|
75
|
+
elsif (outcode_out & BOTTOM != 0) then
|
76
|
+
x = x0 + (x1 - x0) * (boundary[:y_min] - y0) / (y1 - y0)
|
77
|
+
y = boundary[:y_min]
|
78
|
+
elsif (outcode_out & RIGHT != 0) then
|
79
|
+
y = y0 + (y1 - y0) * (boundary[:x_max] - x0) / (x1 - x0)
|
80
|
+
x = boundary[:x_max]
|
81
|
+
elsif (outcode_out & LEFT != 0) then
|
82
|
+
y = y0 + (y1 - y0) * (boundary[:x_min] - x0) / (x1 - x0)
|
83
|
+
x = boundary[:x_min]
|
84
|
+
end
|
85
|
+
|
86
|
+
if (outcode_out == outcode0) then
|
87
|
+
x0 = x
|
88
|
+
y0 = y
|
89
|
+
else
|
90
|
+
x1 = x
|
91
|
+
y1 = y
|
92
|
+
end
|
93
|
+
points[0] = Point.new(x0,y0)
|
94
|
+
points[1] = Point.new(x1,y1)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
return points
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.transforms
|
103
|
+
return [:translate,
|
104
|
+
:scale,
|
105
|
+
:rotate_x,
|
106
|
+
:rotate_y,
|
107
|
+
:rotate_z ]
|
108
|
+
end
|
109
|
+
|
110
|
+
def translate(delta)
|
111
|
+
return Point.new(
|
112
|
+
@x + delta[0],
|
113
|
+
@y + delta[1],
|
114
|
+
@z + delta[2] )
|
115
|
+
end
|
116
|
+
|
117
|
+
def scale(delta)
|
118
|
+
return Point.new(
|
119
|
+
@x * delta[0],
|
120
|
+
@y * delta[1],
|
121
|
+
@z * delta[2] )
|
122
|
+
end
|
123
|
+
|
124
|
+
def rotate_x(theta)
|
125
|
+
return Point.new(
|
126
|
+
@x,
|
127
|
+
@y * cos(theta) - @z * sin(theta),
|
128
|
+
@y * sin(theta) + @z * cos(theta) )
|
129
|
+
end
|
130
|
+
|
131
|
+
def rotate_y(theta)
|
132
|
+
return Point.new(
|
133
|
+
@z * sin(theta) + @x * cos(theta),
|
134
|
+
@y,
|
135
|
+
@z * cos(theta) - @x * sin(theta) )
|
136
|
+
end
|
137
|
+
|
138
|
+
def rotate_z(theta)
|
139
|
+
return Point.new(
|
140
|
+
@x * cos(theta) - @y * sin(theta),
|
141
|
+
@x * sin(theta) + @y * cos(theta),
|
142
|
+
@z )
|
143
|
+
end
|
144
|
+
|
145
|
+
def project(x = 0, y = 0, z = Ivan.default_focal_length)
|
146
|
+
pov = Point.new(x, y, z)
|
147
|
+
return Point.new(
|
148
|
+
pov.z * (@x - pov.x) / (@z + pov.z) + pov.x,
|
149
|
+
pov.z * (@y - pov.y) / (@z + pov.z) + pov.y,
|
150
|
+
0 )
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
data/lib/sender.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
class OutputInitError < Exception
|
2
|
+
end
|
3
|
+
|
4
|
+
class UnsafeOutputError < Exception
|
5
|
+
end
|
6
|
+
|
7
|
+
# Sender is an abstract class, and is not meant to be instantiated.
|
8
|
+
# Subclass it for the requirements of your application's display hardware.
|
9
|
+
|
10
|
+
class Sender
|
11
|
+
@output = nil
|
12
|
+
@boundary = nil
|
13
|
+
|
14
|
+
attr_reader :boundary
|
15
|
+
|
16
|
+
def initialize(config_params)
|
17
|
+
begin
|
18
|
+
post_initialize(config_params)
|
19
|
+
rescue
|
20
|
+
raise OutputInitError, "Output device couldn't be initialized"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def send(buffer)
|
25
|
+
check_safe(buffer)
|
26
|
+
pre_send(buffer)
|
27
|
+
buffer.each_slice(2) do |slice|
|
28
|
+
send_line(slice)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def check_safe(buffer)
|
35
|
+
buffer.each do |i|
|
36
|
+
raise UnsafeOutputError, "Found point #{i.inspect} outside output boundary #{@boundary.inspect}" \
|
37
|
+
if (!i.screen_safe?(@boundary))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def send_line(line)
|
42
|
+
[line[0].x, line[0].y, line[1].x, line[1].y].each do |coord|
|
43
|
+
@output.send(output_message, coordinate_format(coord) )
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Override these methods in concrete subclasses
|
48
|
+
|
49
|
+
def post_initialize(config_params)
|
50
|
+
raise NotImplementedError
|
51
|
+
end
|
52
|
+
|
53
|
+
def pre_send(buffer)
|
54
|
+
raise NotImplementedError
|
55
|
+
end
|
56
|
+
|
57
|
+
def output_message
|
58
|
+
raise NotImplementedError
|
59
|
+
end
|
60
|
+
|
61
|
+
def coordinate_format(value)
|
62
|
+
raise NotImplementedError
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'serialport'
|
2
|
+
|
3
|
+
class TeensyVSender < Sender
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
def post_initialize(config_params)
|
8
|
+
@output = config_params.fetch(:output_class, SerialPort).new(
|
9
|
+
config_params[:port],
|
10
|
+
config_params.fetch(:baud, 9600),
|
11
|
+
config_params.fetch(:data_bits, 8),
|
12
|
+
config_params.fetch(:stop_bits, 1)
|
13
|
+
)
|
14
|
+
@boundary = config_params.fetch(:boundary, {
|
15
|
+
x_min: 0,
|
16
|
+
y_min: 0,
|
17
|
+
x_max: 255,
|
18
|
+
y_max: 255
|
19
|
+
})
|
20
|
+
end
|
21
|
+
|
22
|
+
def pre_send(buffer)
|
23
|
+
transmit_instruction_length(buffer.length / 2)
|
24
|
+
end
|
25
|
+
|
26
|
+
def output_message
|
27
|
+
return :write
|
28
|
+
end
|
29
|
+
|
30
|
+
def coordinate_format(value)
|
31
|
+
return value.to_i.chr
|
32
|
+
end
|
33
|
+
|
34
|
+
def transmit_instruction_length(length)
|
35
|
+
high_byte = (length >> 8) & 0xff
|
36
|
+
low_byte = length & 0xff
|
37
|
+
@output.write(high_byte.to_i.chr)
|
38
|
+
@output.write(low_byte.to_i.chr)
|
39
|
+
return length
|
40
|
+
end
|
41
|
+
end
|
metadata
ADDED
@@ -0,0 +1,194 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ivan
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.pre
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Duncan Malashock
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: serialport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.7'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.7'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: guard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.12'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.12'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: guard-minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.4'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.4'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '10.4'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '10.4'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.10'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.10'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: pry-byebug
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.1'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.1'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: ruby-prof
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.15'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.15'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: codeclimate-test-reporter
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.4'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.4'
|
153
|
+
description: Creates imagery on analog vector monitors
|
154
|
+
email: duncanmalashock@gmail.com
|
155
|
+
executables: []
|
156
|
+
extensions: []
|
157
|
+
extra_rdoc_files: []
|
158
|
+
files:
|
159
|
+
- lib/composition.rb
|
160
|
+
- lib/geometry.rb
|
161
|
+
- lib/glyph.rb
|
162
|
+
- lib/has_transforms.rb
|
163
|
+
- lib/ivan.rb
|
164
|
+
- lib/models/cube.yml
|
165
|
+
- lib/models/square.yml
|
166
|
+
- lib/models/tetrahedron.yml
|
167
|
+
- lib/point.rb
|
168
|
+
- lib/sender.rb
|
169
|
+
- lib/teensyv_sender.rb
|
170
|
+
homepage: http://rubygems.org/gems/ivan
|
171
|
+
licenses:
|
172
|
+
- MIT
|
173
|
+
metadata: {}
|
174
|
+
post_install_message:
|
175
|
+
rdoc_options: []
|
176
|
+
require_paths:
|
177
|
+
- lib
|
178
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: 1.3.1
|
188
|
+
requirements: []
|
189
|
+
rubyforge_project:
|
190
|
+
rubygems_version: 2.4.5
|
191
|
+
signing_key:
|
192
|
+
specification_version: 4
|
193
|
+
summary: ivan
|
194
|
+
test_files: []
|