straightedge 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +7 -0
- data/README.md +44 -2
- data/gemspec.yml +3 -0
- data/lib/straightedge.rb +33 -11
- data/lib/straightedge/aspects.rb +3 -0
- data/lib/straightedge/aspects/colorable.rb +8 -0
- data/lib/straightedge/aspects/figural.rb +12 -0
- data/lib/straightedge/aspects/positional.rb +10 -0
- data/lib/straightedge/colors.rb +72 -0
- data/lib/straightedge/config.rb +6 -0
- data/lib/straightedge/director.rb +39 -0
- data/lib/straightedge/extend/array.rb +2 -13
- data/lib/straightedge/figures.rb +8 -0
- data/lib/straightedge/{adapters.rb → figures/circle.rb} +0 -0
- data/lib/straightedge/figures/figure.rb +44 -0
- data/lib/straightedge/figures/grid.rb +65 -0
- data/lib/straightedge/figures/grid_cell.rb +0 -0
- data/lib/straightedge/figures/hexagon.rb +33 -0
- data/lib/straightedge/figures/label.rb +13 -0
- data/lib/straightedge/figures/line.rb +25 -0
- data/lib/straightedge/figures/mark.rb +23 -0
- data/lib/straightedge/figures/quadrilateral.rb +20 -0
- data/lib/straightedge/motor/adapter.rb +54 -0
- data/lib/straightedge/motor/engine.rb +16 -0
- data/lib/straightedge/origin.rb +3 -0
- data/lib/straightedge/presenter.rb +29 -0
- data/lib/straightedge/scene.rb +20 -0
- data/lib/straightedge/surface.rb +21 -0
- data/lib/straightedge/toolkit/compass.rb +19 -0
- data/lib/straightedge/toolkit/rose.rb +60 -0
- data/lib/straightedge/toolkit/ruler.rb +23 -0
- data/lib/straightedge/tools.rb +3 -0
- data/lib/straightedge/version.rb +1 -1
- data/spec/spec_helper.rb +4 -1
- data/spec/straightedge/adapter_spec.rb +14 -0
- data/spec/straightedge/director_spec.rb +10 -0
- data/spec/straightedge/extend/array_spec.rb +1 -6
- data/spec/straightedge/{figure_spec.rb → figures/figure_spec.rb} +0 -5
- data/spec/straightedge/figures/grid_spec.rb +31 -0
- data/spec/straightedge/figures/hexagon_spec.rb +7 -0
- data/spec/straightedge/motor/engine_spec.rb +11 -0
- data/spec/straightedge/scene_spec.rb +27 -0
- data/spec/straightedge/{compass_spec.rb → toolkit/compass_spec.rb} +0 -4
- data/spec/straightedge/{rose_spec.rb → toolkit/rose_spec.rb} +0 -5
- data/spec/straightedge/toolkit/ruler_spec.rb +14 -0
- data/spec/straightedge_spec.rb +35 -0
- metadata +54 -16
- data/.rvmrc +0 -1
- data/lib/straightedge/compass.rb +0 -17
- data/lib/straightedge/figure.rb +0 -28
- data/lib/straightedge/grid.rb +0 -34
- data/lib/straightedge/line.rb +0 -21
- data/lib/straightedge/mark.rb +0 -26
- data/lib/straightedge/rose.rb +0 -44
- data/lib/straightedge/ruler.rb +0 -21
- data/spec/straightedge/grid_spec.rb +0 -33
- data/spec/straightedge/ruler_spec.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8b2f60d62255936247fe75932dc27426760a1e9
|
4
|
+
data.tar.gz: 05cc12291ebbf0518a608b1f1e0f3ef6f0ca376d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 176f4ae297d81ab3c94e6daf7a0ea0aa3ad94cd12594ead81123822e0704ba6b7dd56f2026a1e9094e5840eb0320fc7c64c2e8b49787e1468f52e2e2c8e059aa
|
7
|
+
data.tar.gz: 8e600b22c8cf4463e7a55e5d1883da258e81ea4668e8e686f36af5dbbe0bc35e9e7b277c39a651f6431dbe3ce81703143d14167b630567ddc4b857a1998c9ab6
|
data/.gitignore
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.1.5
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,28 +1,70 @@
|
|
1
1
|
# straightedge
|
2
2
|
|
3
|
+
[![Code Climate](https://codeclimate.com/github/jweissman/straightedge/badges/gpa.svg)](https://codeclimate.com/github/jweissman/straightedge)
|
4
|
+
|
3
5
|
* [Homepage](https://rubygems.org/gems/straightedge)
|
4
6
|
* [Documentation](http://rubydoc.info/gems/straightedge/frames)
|
5
7
|
* [Email](mailto:jweissman1986 at gmail.com)
|
6
8
|
|
7
9
|
## Description
|
8
10
|
|
9
|
-
|
11
|
+
Give me a compass and straightedge and I will conquer the world
|
12
|
+
|
13
|
+
[![Compass and Straightedge XKCD](http://imgs.xkcd.com/comics/compass_and_straightedge.png)](http://xkcd.com/866/)
|
14
|
+
|
15
|
+
Geometry primitives and graphical app (game) framework framework.
|
10
16
|
|
11
17
|
## Features
|
12
18
|
|
19
|
+
* Geometry toolkit
|
20
|
+
- extensible Compass
|
21
|
+
- Ruler (for measuring distances)
|
22
|
+
|
23
|
+
* Figures composed of points called Marks
|
24
|
+
- Line
|
25
|
+
- Quadrilateral
|
26
|
+
- Hexagon
|
27
|
+
|
28
|
+
* Some fledgling support for grids
|
29
|
+
|
30
|
+
* Some reactor-pattern framework platform components
|
31
|
+
to help standardize interfaces (see straightedge-gosu
|
32
|
+
and straightedge-canvas for examples)
|
33
|
+
|
13
34
|
## Examples
|
14
35
|
|
15
36
|
require 'straightedge'
|
16
37
|
|
38
|
+
# you need an adapter to actually render something
|
39
|
+
require 'straightedge-gosu'
|
40
|
+
|
41
|
+
class Example::GameController < Straightedge::Director
|
42
|
+
def current_scene
|
43
|
+
{
|
44
|
+
[200,300] => Quadrilateral.new(dimensions: [200,100], color: :green),
|
45
|
+
[200,305] => "rectangle",
|
46
|
+
|
47
|
+
[400,300] => Hexagon.new(scale: 40.0, color: :blue),
|
48
|
+
[400,305] => "hexagon"
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
17
53
|
## Requirements
|
18
54
|
|
55
|
+
Ruby 2.x should be enough
|
56
|
+
|
19
57
|
## Install
|
20
58
|
|
21
59
|
$ gem install straightedge
|
22
60
|
|
23
61
|
## Synopsis
|
24
62
|
|
25
|
-
|
63
|
+
Eventually it would be nice to support a CLI that wraps around tasks (note: not implemented yet)
|
64
|
+
|
65
|
+
$ straightedge create [app] — builds an example app skeleton
|
66
|
+
$ straightedge serve — stands up a canvas webserver
|
67
|
+
$ straightedge play — connects to local instance or plays through OpenGL adapter… etc
|
26
68
|
|
27
69
|
## Copyright
|
28
70
|
|
data/gemspec.yml
CHANGED
data/lib/straightedge.rb
CHANGED
@@ -1,17 +1,39 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
require 'straightedge/compass'
|
4
|
-
require 'straightedge/rose'
|
5
|
-
require 'straightedge/ruler'
|
6
|
-
|
7
|
-
require 'straightedge/mark'
|
8
|
-
require 'straightedge/line'
|
9
|
-
require 'straightedge/figure'
|
1
|
+
require 'mini/config'
|
10
2
|
|
11
|
-
|
12
|
-
require 'straightedge/
|
3
|
+
require 'straightedge/version'
|
4
|
+
require 'straightedge/config'
|
5
|
+
require 'straightedge/origin'
|
6
|
+
require 'straightedge/aspects'
|
7
|
+
require 'straightedge/tools'
|
8
|
+
require 'straightedge/figures'
|
9
|
+
require 'straightedge/colors'
|
10
|
+
require 'straightedge/scene'
|
11
|
+
require 'straightedge/presenter'
|
13
12
|
|
14
13
|
require 'straightedge/extend/array'
|
15
14
|
|
15
|
+
# for integration with viewing/gaming engines...
|
16
|
+
# TODO try to downstream as much of this to supporting libs
|
17
|
+
# as possible
|
18
|
+
require 'straightedge/motor/engine'
|
19
|
+
require 'straightedge/motor/adapter'
|
20
|
+
require 'straightedge/director'
|
21
|
+
require 'straightedge/surface'
|
22
|
+
|
16
23
|
module Straightedge
|
24
|
+
include Toolkit
|
25
|
+
include Figures
|
26
|
+
|
27
|
+
# create constructors around out configured default components
|
28
|
+
class << self
|
29
|
+
%w[ engine agent surface adapter ].each do |elem|
|
30
|
+
define_method("new_#{elem}") do |*args|
|
31
|
+
Straightedge.config.send("#{elem}_class").new(*args)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.bootstrap
|
37
|
+
new_engine.boot
|
38
|
+
end
|
17
39
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Straightedge
|
2
|
+
module Colors
|
3
|
+
class Palette
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
attr_reader :names_and_values
|
7
|
+
def initialize(names_and_hex_values={})
|
8
|
+
@names_and_values = names_and_hex_values
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
def list; @names_and_values.keys end
|
13
|
+
def_delegator :list, :sample
|
14
|
+
|
15
|
+
def hex_value_for(name)
|
16
|
+
raise "no such color: #{name}" unless list.include?(name)
|
17
|
+
@names_and_values[name]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.base
|
21
|
+
@core ||= new({
|
22
|
+
white: 0xFFFFFFFF,
|
23
|
+
black: 0xFF000000,
|
24
|
+
none: 0x00000000,
|
25
|
+
})
|
26
|
+
end
|
27
|
+
|
28
|
+
# http://paletton.com/#uid=b5C4c2O0kfUu76fODb3COkppkonk+
|
29
|
+
def self.clean_rgb
|
30
|
+
@smooth_rgb ||= new(base.names_and_values.merge({
|
31
|
+
red: 0xFFEE787B, red1: 0xFFFECDCE, red2: 0xFFFDA6A8, red3: 0xFFC8494C, red4: 0xFFA6282B,
|
32
|
+
blue: 0xFF6C5DA5, blue1: 0xFFC2BAE0, blue2: 0xFF9488C3, blue3: 0xFF4D3D8B, blue4: 0xFF362673,
|
33
|
+
green: 0xFF67C262, green1: 0xFFC0ECBE, green2: 0xFF93DA8F, green3: 0xFF40A33B, green4: 0xFF258720
|
34
|
+
}))
|
35
|
+
end
|
36
|
+
|
37
|
+
# Palette URL: http://paletton.com/#uid=72s0u0k8kpR26GB4Wuzc2lNfjho
|
38
|
+
#
|
39
|
+
# the '4' is closer to the base color, we may want to rethink the naming strategy
|
40
|
+
# also -- we need a color concept and to generate these but that's another day!
|
41
|
+
def self.pleasant_pastels
|
42
|
+
@pastels ||= new(base.names_and_values.merge({
|
43
|
+
tan: 0xFFA9BD8C, tan1: 0xFFEBF2E2, tan2: 0xFFD2E0BD, tan3: 0xFF87A063, tan4: 0xFF667F42,
|
44
|
+
green: 0xFF71987D, green1: 0xFFC7D5CB, green2: 0xFF98B4A1, green3: 0xFF50805F, green4: 0xFF356644,
|
45
|
+
pink: 0xFFCEA098, pink1: 0xFFFFF1EE, pink2: 0xFFF4D3CE, pink3: 0xFFAE756C, pink4: 0xFF8B5148,
|
46
|
+
purple: 0xFFAD8095, purple1: 0xFFE5D6DD, purple2: 0xFFCDADBC, purple3: 0xFF925B74, purple4: 0xFF743D56,
|
47
|
+
}))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# expose module-level wrappers around the currently-configured palette
|
52
|
+
#
|
53
|
+
def self.palette
|
54
|
+
@current_palette ||= Straightedge.config.palette
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.all
|
58
|
+
palette.list
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.pick
|
62
|
+
palette.sample
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.hex_value(color)
|
66
|
+
palette.hex_value_for color
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# assign a basic rgb default color palette
|
71
|
+
config.palette = Colors::Palette.clean_rgb
|
72
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Straightedge
|
2
|
+
class Director
|
3
|
+
extend Forwardable
|
4
|
+
include Straightedge::Figures
|
5
|
+
|
6
|
+
def prepare_stage(geometry)
|
7
|
+
@width, @height = *geometry
|
8
|
+
@space = Grid.new([30,30], scale: 20.0)
|
9
|
+
@space.paint!
|
10
|
+
end
|
11
|
+
|
12
|
+
def orchestrate
|
13
|
+
@space.paint!
|
14
|
+
end
|
15
|
+
|
16
|
+
def current_scene
|
17
|
+
Scene.new({
|
18
|
+
ORIGIN => @space,
|
19
|
+
[10,10] => "grid",
|
20
|
+
|
21
|
+
[200,300] => Quadrilateral.new(dimensions: [200,100], color: :green),
|
22
|
+
[200,305] => "rectangle",
|
23
|
+
|
24
|
+
[400,300] => Hexagon.new(scale: 40.0, color: :blue),
|
25
|
+
[400,305] => "hexagon"
|
26
|
+
})
|
27
|
+
end
|
28
|
+
|
29
|
+
## handle custom events from the surface (clicks)...
|
30
|
+
# how should we handle socket/player connects?
|
31
|
+
#
|
32
|
+
def handle(evt_name, *args)
|
33
|
+
#puts "--- got event #{evt_name} with args #{args}"
|
34
|
+
send(evt_name.to_sym, *args)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
config.agent_class = Director
|
39
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class Array
|
2
|
-
|
2
|
+
include Straightedge::Aspects::Positional
|
3
|
+
include Straightedge::Aspects::Figural
|
3
4
|
|
4
5
|
def sum
|
5
6
|
inject(&:+)
|
@@ -8,16 +9,4 @@ class Array
|
|
8
9
|
def mean
|
9
10
|
sum / size
|
10
11
|
end
|
11
|
-
|
12
|
-
# consider the array as a vector in n-space (where n is the self.length)
|
13
|
-
def to_point
|
14
|
-
Straightedge::Mark.new(*self)
|
15
|
-
end
|
16
|
-
def_delegators :to_point, :x, :y
|
17
|
-
|
18
|
-
# consider the array as an array of points
|
19
|
-
def to_points
|
20
|
-
Straightedge::Figure.new(self)
|
21
|
-
end
|
22
|
-
def_delegators :to_points, :adjacent, :center
|
23
12
|
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'straightedge/figures/figure'
|
2
|
+
require 'straightedge/figures/mark'
|
3
|
+
require 'straightedge/figures/label'
|
4
|
+
require 'straightedge/figures/line'
|
5
|
+
require 'straightedge/figures/quadrilateral'
|
6
|
+
require 'straightedge/figures/hexagon'
|
7
|
+
require 'straightedge/figures/grid'
|
8
|
+
|
File without changes
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Straightedge
|
2
|
+
module Figures
|
3
|
+
# TODO the idea is that a figure is a collection of marks (and possibly other figures...?)
|
4
|
+
# marks should be represented relative to the *figural* origin
|
5
|
+
class Figure
|
6
|
+
include Straightedge::Aspects::Colorable
|
7
|
+
|
8
|
+
extend Forwardable
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
def_delegators :marks, :each
|
12
|
+
def_delegators :compass, :project
|
13
|
+
def_delegators :location, :x, :y
|
14
|
+
|
15
|
+
attr_accessor :marks, :color, :location
|
16
|
+
|
17
|
+
def initialize(marks=[], location: nil, color: :none)
|
18
|
+
@marks = marks
|
19
|
+
@color = color
|
20
|
+
@location = location
|
21
|
+
end
|
22
|
+
|
23
|
+
def compass; @compass ||= Straightedge::Toolkit::Compass.default end
|
24
|
+
|
25
|
+
def adjacent
|
26
|
+
approximate_adjacent = map(&method(:project)).flatten(1).uniq
|
27
|
+
actual_adjacent = approximate_adjacent.reject(&method(:include?))
|
28
|
+
actual_adjacent.sort_by(&method(:distance_from_center))
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
# note this is center of the collection of raw marks
|
33
|
+
# in terms of their own space; not displaced by location
|
34
|
+
# or scaled by dimensions
|
35
|
+
def center
|
36
|
+
[map(&:x).mean, map(&:y).mean]
|
37
|
+
end
|
38
|
+
|
39
|
+
def distance_from_center(xy)
|
40
|
+
Straightedge::Toolkit::Ruler.distance(xy,center)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Straightedge
|
2
|
+
module Figures
|
3
|
+
class Grid < Figure
|
4
|
+
include Enumerable
|
5
|
+
def_delegators :to_a, :sample, :map!
|
6
|
+
def_delegator :dimensions, :x, :width
|
7
|
+
def_delegator :dimensions, :y, :height
|
8
|
+
|
9
|
+
attr_reader :dimensions, :scale, :figure
|
10
|
+
|
11
|
+
def initialize(dimensions=[1,1], opts={})
|
12
|
+
@dimensions = dimensions
|
13
|
+
@scale = opts.delete(:scale) { 1.0 }
|
14
|
+
super(to_a, opts)
|
15
|
+
end
|
16
|
+
|
17
|
+
def at(xy)
|
18
|
+
[xy.x, xy.y]
|
19
|
+
end
|
20
|
+
|
21
|
+
def each
|
22
|
+
Grid.each_coordinate([width, height]) do |x, y|
|
23
|
+
yield(at([x,y]))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def cell_at(xy)
|
28
|
+
@cells ||= {}
|
29
|
+
@cells[xy] ||= Figures::Quadrilateral.new(dimensions: [@scale, @scale], location: to_pixels(xy)) #[xy.x+1,xy.y+1])) #to_pixels(xy))
|
30
|
+
end
|
31
|
+
|
32
|
+
def each_cell
|
33
|
+
each { |xy| yield cell_at(xy) }
|
34
|
+
end
|
35
|
+
|
36
|
+
def paint!
|
37
|
+
#each(&:to_point)
|
38
|
+
each_cell(&:paint)
|
39
|
+
end
|
40
|
+
|
41
|
+
def clip(xys=[])
|
42
|
+
xys.reject do |xy|
|
43
|
+
_x,_y = *xy
|
44
|
+
_x < 0 || _y < 0 || x >= _x || y >= _y
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.each_coordinate(dimensions)
|
49
|
+
dimensions.x.times do |x|
|
50
|
+
dimensions.y.times do |y|
|
51
|
+
yield [x,y]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_pixels(xy)
|
57
|
+
[xy.x * (@scale/2), xy.y * (@scale/2)]
|
58
|
+
end
|
59
|
+
|
60
|
+
#def to_coords(xy)
|
61
|
+
# [xy.x / (@scale/2), xy.y / (@scale/2) ]
|
62
|
+
#end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|