basis-processing 0.4.9 → 0.5.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.
- data/.gitignore +1 -0
- data/README +65 -43
- data/basis.gemspec +1 -1
- data/lib/basis_processing.rb +2 -0
- data/lib/demo.rb +20 -9
- data/lib/interactive.rb +30 -0
- data/lib/screen.rb +21 -14
- metadata +6 -5
data/.gitignore
CHANGED
data/README
CHANGED
@@ -18,52 +18,74 @@ To use Basis functionality in your code, it is enough to:
|
|
18
18
|
|
19
19
|
Here's some example code, which plots random points.
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
21
|
+
require 'rubygems'
|
22
|
+
Gem.clear_paths
|
23
|
+
ENV['GEM_HOME'] = '/home/avishek/jruby/jruby-1.6.3/lib/ruby/gems/1.8'
|
24
|
+
ENV['GEM_PATH'] = '/home/avishek/jruby/jruby-1.6.3/lib/ruby/gems/1.8'
|
25
|
+
|
26
|
+
require 'basis_processing'
|
27
|
+
|
28
|
+
class Demo < Processing::App
|
29
|
+
include Interactive
|
30
|
+
app = self
|
31
|
+
def setup
|
32
|
+
smooth
|
33
|
+
background(0,0,0)
|
34
|
+
color_mode(RGB, 1.0)
|
35
|
+
stroke(1,1,0,1)
|
36
|
+
@highlight_block = lambda do |p|
|
37
|
+
rect_mode(CENTER)
|
38
|
+
stroke(1,0,0)
|
39
|
+
fill(1,0,0)
|
40
|
+
rect(p[:x], p[:y], 5, 5)
|
41
|
+
end
|
42
|
+
|
43
|
+
@passive_block = lambda do |p|
|
44
|
+
rect_mode(CENTER)
|
45
|
+
stroke(1,1,0,1)
|
46
|
+
fill(1,1,0)
|
47
|
+
rect(p[:x], p[:y], 5, 5)
|
48
|
+
end
|
49
|
+
|
50
|
+
points = []
|
51
|
+
200.times {|n|points << {:x => n, :y => random(300)}}
|
52
|
+
|
53
|
+
x_basis_vector = {:x => 1.0, :y => 0.0}
|
54
|
+
y_basis_vector = {:x => 0.0, :y => 1.0}
|
55
|
+
|
56
|
+
x_range = ContinuousRange.new({:minimum => 0, :maximum => 200})
|
57
|
+
y_range = ContinuousRange.new({:minimum => 0, :maximum => 300})
|
58
|
+
|
59
|
+
@basis = CoordinateSystem.new(Axis.new(x_basis_vector,x_range), Axis.new(y_basis_vector,y_range), [[4,0],[0,2]], self)
|
60
|
+
screen_transform = SignedTransform.new({:x => 1, :y => -1}, {:x => 300, :y => 900})
|
61
|
+
@screen = Screen.new(screen_transform, self, @basis)
|
62
|
+
@screen.join=true
|
63
|
+
@screen.draw_axes(10,10)
|
64
|
+
stroke(1,1,0,1)
|
65
|
+
fill(1,1,0)
|
66
|
+
rect_mode(CENTER)
|
67
|
+
points.each do |p|
|
68
|
+
@screen.plot(p, :track => true) {|p| rect(p[:x], p[:y], 5, 5)}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
w = 1200
|
74
|
+
h = 1000
|
75
|
+
|
76
|
+
Demo.new(:title => "My Sketch", :width => w, :height => h)
|
77
|
+
|
78
|
+
You have a few options when plotting a point. If you specify ':bar => true', like the line below:
|
63
79
|
|
64
80
|
screen.plot(p, basis, :bar => true) {|p| rect(p[:x], p[:y], 5, 5)}
|
65
81
|
|
66
|
-
If you omit `:bar => true` or don't specify any options, Basis will plot the points without connecting them to the X-axis.
|
82
|
+
it will connect the point with the x-axis. If you omit `:bar => true` or don't specify any options, Basis will plot the points without connecting them to the X-axis.
|
67
83
|
If you omit the block at the end of the call, Basis will plot the point using a circle. Use the block to customise how you wish to represent the point graphically.
|
68
84
|
You can toggle the joining of the points with lines by setting the join attribute of Screen to on (joins points)/off (no joining). The default is false.
|
69
85
|
|
86
|
+
Version 0.5.0 introduces experimental support for mouseover interactivity without extra effort on your part. To allow interactions to happen, you must specify ':track => true' while plotting a point, as in the line below:
|
87
|
+
|
88
|
+
@screen.plot(p, :track => true) {|p| rect(p[:x], p[:y], 5, 5)}
|
89
|
+
|
90
|
+
To actually enable interactivity, you must 'include' the Interactive module in your sketch class, as in the demonstration code above. Interactivity is a work in progress at the moment.
|
91
|
+
|
data/basis.gemspec
CHANGED
data/lib/basis_processing.rb
CHANGED
data/lib/demo.rb
CHANGED
@@ -6,12 +6,26 @@ ENV['GEM_PATH'] = '/home/avishek/jruby/jruby-1.6.3/lib/ruby/gems/1.8'
|
|
6
6
|
require 'basis_processing'
|
7
7
|
|
8
8
|
class Demo < Processing::App
|
9
|
+
include Interactive
|
9
10
|
app = self
|
10
11
|
def setup
|
11
|
-
|
12
|
+
smooth
|
12
13
|
background(0,0,0)
|
13
14
|
color_mode(RGB, 1.0)
|
14
15
|
stroke(1,1,0,1)
|
16
|
+
@highlight_block = lambda do |p|
|
17
|
+
rect_mode(CENTER)
|
18
|
+
stroke(1,0,0)
|
19
|
+
fill(1,0,0)
|
20
|
+
rect(p[:x], p[:y], 5, 5)
|
21
|
+
end
|
22
|
+
|
23
|
+
@passive_block = lambda do |p|
|
24
|
+
rect_mode(CENTER)
|
25
|
+
stroke(1,1,0,1)
|
26
|
+
fill(1,1,0)
|
27
|
+
rect(p[:x], p[:y], 5, 5)
|
28
|
+
end
|
15
29
|
|
16
30
|
points = []
|
17
31
|
200.times {|n|points << {:x => n, :y => random(300)}}
|
@@ -22,21 +36,18 @@ class Demo < Processing::App
|
|
22
36
|
x_range = ContinuousRange.new({:minimum => 0, :maximum => 200})
|
23
37
|
y_range = ContinuousRange.new({:minimum => 0, :maximum => 300})
|
24
38
|
|
25
|
-
basis = CoordinateSystem.new(Axis.new(x_basis_vector,x_range), Axis.new(y_basis_vector,y_range), [[4,0],[0,2]], self)
|
39
|
+
@basis = CoordinateSystem.new(Axis.new(x_basis_vector,x_range), Axis.new(y_basis_vector,y_range), [[4,0],[0,2]], self)
|
26
40
|
screen_transform = SignedTransform.new({:x => 1, :y => -1}, {:x => 300, :y => 900})
|
27
|
-
screen = Screen.new(screen_transform, self)
|
28
|
-
screen.join=true
|
29
|
-
screen.draw_axes(
|
41
|
+
@screen = Screen.new(screen_transform, self, @basis)
|
42
|
+
@screen.join=true
|
43
|
+
@screen.draw_axes(10,10)
|
30
44
|
stroke(1,1,0,1)
|
31
45
|
fill(1,1,0)
|
32
46
|
rect_mode(CENTER)
|
33
47
|
points.each do |p|
|
34
|
-
screen.plot(p,
|
48
|
+
@screen.plot(p, :track => true) {|p| rect(p[:x], p[:y], 5, 5)}
|
35
49
|
end
|
36
50
|
end
|
37
|
-
|
38
|
-
def draw
|
39
|
-
end
|
40
51
|
end
|
41
52
|
|
42
53
|
w = 1200
|
data/lib/interactive.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Interactive
|
2
|
+
attr :screen, :basis
|
3
|
+
|
4
|
+
def mouseMoved(p)
|
5
|
+
p = {:x => p.getX(), :y => p.getY()}
|
6
|
+
@old_points ||= []
|
7
|
+
@points_to_highlight = []
|
8
|
+
index = @screen.points.index do |i|
|
9
|
+
onscreen_point = @screen.transformed(i)
|
10
|
+
(p[:x] - onscreen_point[:x]).abs < 4.0 && (p[:y] - onscreen_point[:y]).abs < 4.0
|
11
|
+
end
|
12
|
+
return if index == nil
|
13
|
+
@points_to_highlight = [{:x => @screen.points[index][:x], :y => @screen.points[index][:y]}]
|
14
|
+
redraw
|
15
|
+
end
|
16
|
+
|
17
|
+
def draw
|
18
|
+
@screen.join = false
|
19
|
+
@old_points ||= []
|
20
|
+
@points_to_highlight ||= []
|
21
|
+
@old_points.each do |old|
|
22
|
+
@screen.plot(old) {|p| @passive_block.call(p) if @passive_block}
|
23
|
+
end
|
24
|
+
@points_to_highlight.each do |new_rectangle|
|
25
|
+
@screen.plot(new_rectangle) {|p| @highlight_block.call(p) if @highlight_block}
|
26
|
+
end
|
27
|
+
@old_points = @points_to_highlight
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
data/lib/screen.rb
CHANGED
@@ -1,22 +1,25 @@
|
|
1
1
|
require 'transform'
|
2
2
|
|
3
3
|
class Screen
|
4
|
+
attr_accessor :points
|
5
|
+
|
4
6
|
def join=(should_join)
|
5
7
|
@should_join = should_join
|
6
8
|
@buffer = nil if !@should_join
|
7
9
|
end
|
8
10
|
|
9
|
-
def initialize(transform, artist)
|
11
|
+
def initialize(transform, artist, basis)
|
10
12
|
@transform = transform
|
11
13
|
@artist = artist
|
14
|
+
@basis = basis
|
12
15
|
join = false
|
16
|
+
@points = []
|
13
17
|
end
|
14
18
|
|
15
|
-
def plot(point,
|
16
|
-
|
17
|
-
p =
|
18
|
-
|
19
|
-
standard_x_axis_point = @transform.apply(basis.standard_basis({:x => point[:x], :y => 0}))
|
19
|
+
def plot(point, options = {:bar => false, :track => false}, &block)
|
20
|
+
@points << point if options[:track]
|
21
|
+
p = transformed(point)
|
22
|
+
standard_x_axis_point = @transform.apply(@basis.standard_basis({:x => point[:x], :y => 0}))
|
20
23
|
if (block)
|
21
24
|
block.call(p)
|
22
25
|
else
|
@@ -28,9 +31,14 @@ class Screen
|
|
28
31
|
@buffer = p
|
29
32
|
end
|
30
33
|
|
31
|
-
def
|
34
|
+
def transformed(data_point)
|
35
|
+
standard_point = @basis.standard_basis(data_point)
|
36
|
+
@transform.apply(standard_point)
|
37
|
+
end
|
38
|
+
|
39
|
+
def original(onscreen_point)
|
32
40
|
p = @transform.unapply(onscreen_point)
|
33
|
-
basis.original(p)
|
41
|
+
@basis.original(p)
|
34
42
|
end
|
35
43
|
|
36
44
|
def draw_ticks(ticks, displacement)
|
@@ -51,18 +59,17 @@ class Screen
|
|
51
59
|
{:x => 5*vector[:x]/magnitude, :y => 5*vector[:y]/magnitude}
|
52
60
|
end
|
53
61
|
|
54
|
-
def draw_axes(
|
62
|
+
def draw_axes(x_interval, y_interval)
|
55
63
|
f = @artist.createFont("Georgia", 24, true);
|
56
64
|
@artist.text_font(f,16)
|
57
|
-
@artist.stroke(1,1,1,1)
|
58
65
|
axis_screen_transform = Transform.new({:x => 800, :y => -800}, @transform.origin)
|
59
66
|
origin = {:x => 0, :y => 0}
|
60
67
|
screen_origin = @transform.apply(origin)
|
61
|
-
x_basis_edge = axis_screen_transform.apply(basis.x_basis_vector)
|
62
|
-
y_basis_edge = axis_screen_transform.apply(basis.y_basis_vector)
|
68
|
+
x_basis_edge = axis_screen_transform.apply(@basis.x_basis_vector)
|
69
|
+
y_basis_edge = axis_screen_transform.apply(@basis.y_basis_vector)
|
63
70
|
|
64
|
-
x_ticks = basis.x_ticks(x_interval)
|
65
|
-
y_ticks = basis.y_ticks(y_interval)
|
71
|
+
x_ticks = @basis.x_ticks(x_interval)
|
72
|
+
y_ticks = @basis.y_ticks(y_interval)
|
66
73
|
|
67
74
|
x_ticks = x_ticks.collect {|t| {:from => @transform.apply(t[:from]), :to => @transform.apply(t[:to]), :label => t[:label]}}
|
68
75
|
y_ticks = y_ticks.collect {|t| {:from => @transform.apply(t[:from]), :to => @transform.apply(t[:to]), :label => t[:label]}}
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: basis-processing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 5
|
9
|
+
- 0
|
10
|
+
version: 0.5.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Avishek Sen Gupta
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-10-
|
18
|
+
date: 2011-10-05 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description: Basis provides a set of classes for easily plotting and transforming arbitrary 2D coordinate systems by specifying their basis vectors in Ruby-Processing.
|
@@ -33,6 +33,7 @@ files:
|
|
33
33
|
- lib/basis_processing.rb
|
34
34
|
- lib/coordinate_system.rb
|
35
35
|
- lib/demo.rb
|
36
|
+
- lib/interactive.rb
|
36
37
|
- lib/matrix_operations.rb
|
37
38
|
- lib/ranges.rb
|
38
39
|
- lib/screen.rb
|