basis-processing 0.4.9 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  *.*~
2
+ *~
2
3
  *.gem
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
- require 'rubygems'`
22
- require 'basis_processing'`
23
-
24
- class Demo < Processing::App
25
- app = self
26
- def setup
27
- smooth
28
- background(0,0,0)
29
- color_mode(RGB, 1.0)
30
-
31
- points = []
32
- 100.times {points << {:x => random(200), :y => random(300)}}
33
-
34
- x_basis_vector = {:x => 1.0, :y => 0.0}
35
- y_basis_vector = {:x => 0.0, :y => 1.0}
36
-
37
- x_range = ContinuousRange.new({:minimum => 0, :maximum => 200})
38
- y_range = ContinuousRange.new({:minimum => 0, :maximum => 300})
39
-
40
- basis = CoordinateSystem.new(Axis.new(x_basis_vector,x_range), Axis.new(y_basis_vector,y_range), [[4,0],[0,2]], self)
41
- screen_transform = SignedTransform.new({:x => 1, :y => -1}, {:x => 300, :y => 900})
42
- screen = Screen.new(screen_transform, self)
43
- screen.join = true
44
- screen.draw_axes(basis,10,10)
45
- stroke(1,1,0,1)
46
- fill(1,1,0)
47
- rect_mode(CENTER)
48
- points.each do |p|
49
- screen.plot(p, basis, :bar => true) {|p| rect(p[:x], p[:y], 5, 5)}
50
- end
51
- end
52
-
53
- def draw
54
- end
55
- end
56
-
57
- w = 1200
58
- h = 1000
59
-
60
- Demo.new(:title => "My Sketch", :width => w, :height => h)
61
-
62
- You have a few options when plotting a point. Consider the line:
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
@@ -1,6 +1,6 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = "basis-processing"
3
- s.version = "0.4.9"
3
+ s.version = "0.5.0"
4
4
  s.author = "Avishek Sen Gupta"
5
5
  s.email = "avishek.sen.gupta@gmail.com"
6
6
  s.homepage = "http://avishek.net/blog"
@@ -3,3 +3,5 @@ require 'ranges.rb'
3
3
  require 'matrix_operations.rb'
4
4
  require 'coordinate_system.rb'
5
5
  require 'screen.rb'
6
+ require 'interactive'
7
+
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
- # smooth
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(basis,10,10)
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, basis) {|p| rect(p[:x], p[:y], 5, 5)}
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
@@ -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, basis, options = {:bar => false}, &block)
16
- standard_point = basis.standard_basis(point)
17
- p = @transform.apply(standard_point)
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 original(onscreen_point, basis)
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(basis, x_interval, y_interval)
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: 29
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 4
9
- - 9
10
- version: 0.4.9
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-03 00:00:00 Z
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