basis-processing 0.5.1 → 0.5.2
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.
- data/.gitignore +1 -0
- data/README +12 -8
- data/basis.gemspec +1 -1
- data/lib/cache.rb +17 -0
- data/lib/coordinate_system.rb +12 -6
- data/lib/demo.rb +11 -5
- data/lib/hash_vector.rb +9 -0
- data/lib/interactive.rb +22 -5
- data/lib/screen.rb +17 -2
- data/lib/text_output.rb +7 -0
- metadata +7 -4
data/.gitignore
CHANGED
data/README
CHANGED
@@ -22,13 +22,19 @@ To use Basis functionality in your code, it is enough to:
|
|
22
22
|
|
23
23
|
Here's some example code, which plots random points.
|
24
24
|
|
25
|
+
require 'rubygems'
|
26
|
+
|
27
|
+
Gem.clear_paths
|
28
|
+
ENV['GEM_HOME'] = '/home/avishek/jruby/jruby-1.6.4/lib/ruby/gems/1.8'
|
29
|
+
ENV['GEM_PATH'] = '/home/avishek/jruby/jruby-1.6.4/lib/ruby/gems/1.8'
|
30
|
+
|
25
31
|
require 'basis_processing'
|
26
32
|
|
27
33
|
class Demo < Processing::App
|
28
|
-
include Interactive
|
29
34
|
app = self
|
30
35
|
def setup
|
31
36
|
smooth
|
37
|
+
no_loop
|
32
38
|
background(0,0,0)
|
33
39
|
color_mode(RGB, 1.0)
|
34
40
|
stroke(1,1,0,1)
|
@@ -50,13 +56,13 @@ Here's some example code, which plots random points.
|
|
50
56
|
200.times {|n|points << {:x => n, :y => random(300)}}
|
51
57
|
|
52
58
|
x_basis_vector = {:x => 1.0, :y => 0.0}
|
53
|
-
y_basis_vector = {:x => 0.
|
59
|
+
y_basis_vector = {:x => 0.2, :y => 1.0}
|
54
60
|
|
55
61
|
x_range = ContinuousRange.new({:minimum => 0, :maximum => 200})
|
56
62
|
y_range = ContinuousRange.new({:minimum => 0, :maximum => 300})
|
57
63
|
|
58
|
-
@basis = CoordinateSystem.new(Axis.new(x_basis_vector,x_range), Axis.new(y_basis_vector,y_range), [[
|
59
|
-
screen_transform =
|
64
|
+
@basis = CoordinateSystem.new(Axis.new(x_basis_vector,x_range), Axis.new(y_basis_vector,y_range), [[1,0],[0,1]], self)
|
65
|
+
screen_transform = Transform.new({:x => 3, :y => -2}, {:x => 300, :y => 900})
|
60
66
|
@screen = Screen.new(screen_transform, self, @basis)
|
61
67
|
@screen.join=true
|
62
68
|
@screen.draw_axes(10,10)
|
@@ -66,13 +72,13 @@ Here's some example code, which plots random points.
|
|
66
72
|
points.each do |p|
|
67
73
|
@screen.plot(p, :track => true) {|p| rect(p[:x], p[:y], 5, 5)}
|
68
74
|
end
|
69
|
-
@index = @screen.build
|
70
75
|
end
|
71
76
|
end
|
72
77
|
|
73
78
|
w = 1200
|
74
79
|
h = 1000
|
75
80
|
|
81
|
+
Demo.send :include, Interactive
|
76
82
|
Demo.new(:title => "My Sketch", :width => w, :height => h)
|
77
83
|
|
78
84
|
You have a few options when plotting a point. If you specify ':bar => true', like the line below:
|
@@ -107,10 +113,8 @@ Experimental support exists for mouseover interactivity without (too much) extra
|
|
107
113
|
|
108
114
|
To actually enable interactivity, you must do a few things:
|
109
115
|
|
110
|
-
* 'include' the Interactive module in your sketch class, as in the demonstration code above.
|
111
|
-
* Build the data sample index from the data, by calling `@index = @screen.build`.
|
116
|
+
* 'include' the Interactive module in your sketch class, as in the demonstration code above, namely the line `Demo.send :include, Interactive`
|
112
117
|
* `@highlight_block` specifies what to plot when the data point is hovered upon.
|
113
|
-
* `@passive_block` specifies what to plot when the data point is **not** being hovered on.
|
114
118
|
|
115
119
|
Interactivity is a work in progress at the moment; some of the above steps may change or be removed.
|
116
120
|
|
data/basis.gemspec
CHANGED
data/lib/cache.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class Cache
|
2
|
+
def initialize(artist)
|
3
|
+
@artist = artist
|
4
|
+
end
|
5
|
+
|
6
|
+
def refresh
|
7
|
+
@artist.save("buffer.jpg")
|
8
|
+
@cached_image = @artist.loadImage("buffer.jpg")
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def restore
|
13
|
+
@artist.image(@cached_image, 0, 0)
|
14
|
+
self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
data/lib/coordinate_system.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'ranges'
|
2
2
|
require 'ruby-processing'
|
3
3
|
require 'matrix_operations'
|
4
|
+
require 'hash_vector'
|
4
5
|
|
5
6
|
include Math
|
6
7
|
|
@@ -13,6 +14,7 @@ class Axis
|
|
13
14
|
end
|
14
15
|
|
15
16
|
class CoordinateSystem
|
17
|
+
CROSSHAIR_SCALE = 5000
|
16
18
|
include MatrixOperations
|
17
19
|
attr_accessor :x_basis_vector, :y_basis_vector
|
18
20
|
|
@@ -46,16 +48,12 @@ class CoordinateSystem
|
|
46
48
|
}
|
47
49
|
end
|
48
50
|
|
49
|
-
def sum(v1, v2)
|
50
|
-
{:x => v1[:x] + v2[:x], :y => v1[:y] + v2[:y]}
|
51
|
-
end
|
52
|
-
|
53
51
|
def x_ticks(x_basis_interval)
|
54
52
|
lines = []
|
55
53
|
t_vectors = tick_vectors
|
56
54
|
@x_axis.range.run(x_basis_interval) do |i,v|
|
57
55
|
tick_origin = standard_basis({:x => i, :y => 0})
|
58
|
-
lines << {:label => v, :from => tick_origin, :to =>
|
56
|
+
lines << {:label => v, :from => tick_origin, :to => tick_origin + t_vectors[:x_tick_vector]}
|
59
57
|
end
|
60
58
|
lines
|
61
59
|
end
|
@@ -65,7 +63,7 @@ class CoordinateSystem
|
|
65
63
|
t_vectors = tick_vectors
|
66
64
|
@y_axis.range.run(y_basis_interval) do |i,v|
|
67
65
|
tick_origin = standard_basis({:x => 0, :y => i})
|
68
|
-
lines << {:label => v, :from => tick_origin, :to =>
|
66
|
+
lines << {:label => v, :from => tick_origin, :to => tick_origin + t_vectors[:y_tick_vector]}
|
69
67
|
end
|
70
68
|
lines
|
71
69
|
end
|
@@ -96,5 +94,13 @@ class CoordinateSystem
|
|
96
94
|
]
|
97
95
|
MatrixOperations::into2Dx1D(MatrixOperations::inverse2D(basis_matrix), p1)
|
98
96
|
end
|
97
|
+
|
98
|
+
def crosshairs(p)
|
99
|
+
crosshair_x_p1 = (@x_basis_vector*CROSSHAIR_SCALE) + standard_basis(p)
|
100
|
+
crosshair_x_p2 = (@x_basis_vector*(-CROSSHAIR_SCALE)) + standard_basis(p)
|
101
|
+
crosshair_y_p1 = (@y_basis_vector*CROSSHAIR_SCALE) + standard_basis(p)
|
102
|
+
crosshair_y_p2 = (@y_basis_vector*(-CROSSHAIR_SCALE)) + standard_basis(p)
|
103
|
+
[{:from => crosshair_x_p1, :to => crosshair_x_p2}, {:from => crosshair_y_p1, :to => crosshair_y_p2}]
|
104
|
+
end
|
99
105
|
end
|
100
106
|
|
data/lib/demo.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
Gem.clear_paths
|
4
|
+
ENV['GEM_HOME'] = '/home/avishek/jruby/jruby-1.6.4/lib/ruby/gems/1.8'
|
5
|
+
ENV['GEM_PATH'] = '/home/avishek/jruby/jruby-1.6.4/lib/ruby/gems/1.8'
|
6
|
+
|
1
7
|
require 'basis_processing'
|
2
8
|
|
3
9
|
class Demo < Processing::App
|
4
|
-
include Interactive
|
5
10
|
app = self
|
6
11
|
def setup
|
7
12
|
smooth
|
13
|
+
no_loop
|
8
14
|
background(0,0,0)
|
9
15
|
color_mode(RGB, 1.0)
|
10
16
|
stroke(1,1,0,1)
|
@@ -26,13 +32,13 @@ class Demo < Processing::App
|
|
26
32
|
200.times {|n|points << {:x => n, :y => random(300)}}
|
27
33
|
|
28
34
|
x_basis_vector = {:x => 1.0, :y => 0.0}
|
29
|
-
y_basis_vector = {:x => 0.
|
35
|
+
y_basis_vector = {:x => 0.2, :y => 1.0}
|
30
36
|
|
31
37
|
x_range = ContinuousRange.new({:minimum => 0, :maximum => 200})
|
32
38
|
y_range = ContinuousRange.new({:minimum => 0, :maximum => 300})
|
33
39
|
|
34
|
-
@basis = CoordinateSystem.new(Axis.new(x_basis_vector,x_range), Axis.new(y_basis_vector,y_range), [[
|
35
|
-
screen_transform =
|
40
|
+
@basis = CoordinateSystem.new(Axis.new(x_basis_vector,x_range), Axis.new(y_basis_vector,y_range), [[1,0],[0,1]], self)
|
41
|
+
screen_transform = Transform.new({:x => 3, :y => -2}, {:x => 300, :y => 900})
|
36
42
|
@screen = Screen.new(screen_transform, self, @basis)
|
37
43
|
@screen.join=true
|
38
44
|
@screen.draw_axes(10,10)
|
@@ -42,12 +48,12 @@ class Demo < Processing::App
|
|
42
48
|
points.each do |p|
|
43
49
|
@screen.plot(p, :track => true) {|p| rect(p[:x], p[:y], 5, 5)}
|
44
50
|
end
|
45
|
-
@index = @screen.build
|
46
51
|
end
|
47
52
|
end
|
48
53
|
|
49
54
|
w = 1200
|
50
55
|
h = 1000
|
51
56
|
|
57
|
+
Demo.send :include, Interactive
|
52
58
|
Demo.new(:title => "My Sketch", :width => w, :height => h)
|
53
59
|
|
data/lib/hash_vector.rb
ADDED
data/lib/interactive.rb
CHANGED
@@ -1,5 +1,18 @@
|
|
1
|
+
require 'cache'
|
2
|
+
|
1
3
|
module Interactive
|
2
4
|
attr :screen, :basis, :index
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
alias :old_setup :setup
|
8
|
+
def setup
|
9
|
+
puts "LoL"
|
10
|
+
old_setup
|
11
|
+
@index = @screen.build
|
12
|
+
@cache = Cache.new(self).refresh
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
3
16
|
|
4
17
|
def mouseMoved(p)
|
5
18
|
p = {:x => p.getX(), :y => p.getY()}
|
@@ -8,13 +21,15 @@ module Interactive
|
|
8
21
|
original_point = @screen.original(p)
|
9
22
|
closest_point = @index.nearest([original_point[:x], original_point[:y]])
|
10
23
|
closest = @screen.points[closest_point[:id]]
|
11
|
-
|
12
|
-
|
24
|
+
closest_onscreen_point = @screen.transformed(closest)
|
25
|
+
distance = (closest_onscreen_point[:x] - p[:x])**2 + (closest_onscreen_point[:y] - p[:y])**2
|
26
|
+
if distance > 14.0
|
13
27
|
@points_to_highlight = []
|
14
28
|
redraw
|
15
29
|
return
|
16
30
|
end
|
17
31
|
@points_to_highlight = [closest]
|
32
|
+
@screen.write(closest)
|
18
33
|
redraw
|
19
34
|
end
|
20
35
|
|
@@ -22,11 +37,13 @@ module Interactive
|
|
22
37
|
@screen.join = false
|
23
38
|
@old_points ||= []
|
24
39
|
@points_to_highlight ||= []
|
25
|
-
@old_points.
|
26
|
-
|
27
|
-
|
40
|
+
@cache.restore if @old_points.count > 0
|
41
|
+
# @old_points.each do |old|
|
42
|
+
# @screen.plot(old) {|p| @passive_block.call(p) if @passive_block}
|
43
|
+
# end
|
28
44
|
@points_to_highlight.each do |new_rectangle|
|
29
45
|
@screen.plot(new_rectangle) {|p| @highlight_block.call(p) if @highlight_block}
|
46
|
+
@screen.draw_crosshairs(new_rectangle)
|
30
47
|
end
|
31
48
|
@old_points = @points_to_highlight
|
32
49
|
end
|
data/lib/screen.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'transform'
|
2
2
|
require 'knnball'
|
3
|
+
require 'text_output'
|
3
4
|
|
4
5
|
class Screen
|
5
6
|
attr_accessor :points
|
@@ -9,24 +10,34 @@ class Screen
|
|
9
10
|
@buffer = nil if !@should_join
|
10
11
|
end
|
11
12
|
|
12
|
-
def initialize(transform, artist, basis)
|
13
|
+
def initialize(transform, artist, basis, output=TextOutput.new)
|
13
14
|
@transform = transform
|
14
15
|
@artist = artist
|
15
16
|
@basis = basis
|
16
17
|
join = false
|
17
18
|
@points = []
|
18
19
|
@data = []
|
20
|
+
@output = output
|
21
|
+
p output
|
19
22
|
end
|
20
23
|
|
21
24
|
def build
|
22
25
|
KnnBall.build(@data)
|
23
26
|
end
|
24
27
|
|
28
|
+
def draw_crosshairs(p)
|
29
|
+
@basis.crosshairs(p).each do |hair|
|
30
|
+
from = @transform.apply(hair[:from])
|
31
|
+
to = @transform.apply(hair[:to])
|
32
|
+
@artist.line(from[:x], from[:y], to[:x], to[:y])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
25
36
|
def plot(point, options = {:bar => false, :track => false}, &block)
|
26
37
|
@points << point if options[:track]
|
27
38
|
@data << {:id => @points.count - 1, :point => [point[:x], point[:y]]}
|
28
39
|
p = transformed(point)
|
29
|
-
standard_x_axis_point =
|
40
|
+
standard_x_axis_point = transformed({:x => point[:x], :y => 0})
|
30
41
|
if (block)
|
31
42
|
block.call(p)
|
32
43
|
else
|
@@ -87,5 +98,9 @@ class Screen
|
|
87
98
|
draw_ticks(x_ticks, {:x => 0, :y => 20})
|
88
99
|
draw_ticks(y_ticks, {:x => -50, :y => 0})
|
89
100
|
end
|
101
|
+
|
102
|
+
def write(p)
|
103
|
+
@output.notify(p)
|
104
|
+
end
|
90
105
|
end
|
91
106
|
|
data/lib/text_output.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: basis-processing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-10-
|
12
|
+
date: 2011-10-07 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: knnball
|
16
|
-
requirement: &
|
16
|
+
requirement: &8852080 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: 0.0.6
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *8852080
|
25
25
|
description: Basis provides a set of classes for easily plotting and transforming
|
26
26
|
arbitrary 2D coordinate systems by specifying their basis vectors in Ruby-Processing.
|
27
27
|
email: avishek.sen.gupta@gmail.com
|
@@ -33,12 +33,15 @@ files:
|
|
33
33
|
- README
|
34
34
|
- basis.gemspec
|
35
35
|
- lib/basis_processing.rb
|
36
|
+
- lib/cache.rb
|
36
37
|
- lib/coordinate_system.rb
|
37
38
|
- lib/demo.rb
|
39
|
+
- lib/hash_vector.rb
|
38
40
|
- lib/interactive.rb
|
39
41
|
- lib/matrix_operations.rb
|
40
42
|
- lib/ranges.rb
|
41
43
|
- lib/screen.rb
|
44
|
+
- lib/text_output.rb
|
42
45
|
- lib/transform.rb
|
43
46
|
homepage: http://avishek.net/blog
|
44
47
|
licenses: []
|