basis-processing 0.5.8 → 0.5.9

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -1,8 +1,18 @@
1
+ Please send bug reports to (avishek.sen.gupta at gmail.com)
2
+
1
3
  **NOTE: Starting from version 0.5.1, Basis has been ported to Ruby 1.9.2, because of the kd-tree library dependency. Currently, there are no plans of maintaining Basis compatibility with Ruby 1.8.x.**
2
4
 
3
5
  **Basis** provides a set of classes for easily plotting and transforming arbitrary 2D coordinate systems by specifying their basis vectors. Originally developed to work with Ruby-Processing, it now supports any class which supports Processing-like semantics.
4
6
 
5
- Starting from version 0.5.0, experimental support has been added for mouseover interactivity without (too much) extra effort on your part. This is still a work in progress, though.
7
+ UPDATE: Starting from version 0.5.9, you can turn grid lines on or off.
8
+
9
+ UPDATE: Starting from version 0.5.8, you can customise axis labels, draw arbitrary shapes/text/plot custom graphics at any point in your coordinate system. See below for more details.
10
+
11
+ UPDATE: With version 0.5.7, experimental support has been added for drawing objects which aren’t points. Interactions with such objects is currently not supported. Additional support for drawing markers/highlighting in custom bases is now in.
12
+
13
+ UPDATE: Starting from version 0.5.1, Basis has been ported to Ruby 1.9.2, because of the kd-tree library dependency. Currently, there are no plans of maintaining Basis compatibility with Ruby 1.8.x. As an aside, I personally recommend using RVM to manage the mess of Ruby/JRuby installations that you’re likely to have on your machine.
14
+
15
+ UPDATE: Basis has hit version 0.5.0 with experimental support for mouseover interactivity. More work is incoming, but the demo code below is up-to-date, for now. Starting from version 0.5.0, experimental support has been added for mouseover interactivity without (too much) extra effort on your part. This is still a work in progress, though.
6
16
 
7
17
  ## Installation
8
18
 
@@ -247,7 +257,21 @@ The other interesting thing about the above code will become evident if we speci
247
257
 
248
258
  The box plot in this modified basis acquires the properties of skewness, rotation, etc. of the host coordinate system. This lets you get on with drawing the object without really worrying about the specific properties of the coordinate space you are plotting in.
249
259
 
250
- ## Convenience methods for setting up default CoordinateSystem
260
+ The other variation you can use is the at() method of a Screen object. at() behaves like plot(), except that it never plots anything by itself, instead deferring full control to the block that you pass to it. Think of it as a simple way of accessing any point in your custom coordinate system, without having to perform any of the messy transformations yourself. So, for example, the following code fragment, puts some text at whichever point on screen corresponds to (some_x, some_y) in your custom basis.
261
+
262
+ @screen.at({:x => some_x, :y => some_y}) {|o,m,s| text(o[:y], m[:x] + 5, m[:y] + 14)}
263
+
264
+ ## Axis drawing options
265
+
266
+ Starting from version 0.5.8, you can customise labels, if you pass two blocks to the draw_axes() method, one for the x-axis, the other for the y-axis. For example, in the fragment below, we're not outputting anything for the x-axis labels (returning an empty string), and converting the y-axis value to an integer.
267
+
268
+ @screen.draw_axes(10, 10, :x => ->(p){''}, :y => ->(p){p.to_i})
269
+
270
+ Grid lines are drawn by default. To turn them off, set the :gridlines key to false in the call to draw_axes(), like so:
271
+
272
+ @screen.draw_axes(10, 10, :x => ->(p){''}, :y => ->(p){p.to_i}, :gridlines => false)
273
+
274
+ ## Convenience method for setting up default CoordinateSystem
251
275
 
252
276
  If you're doing a simple plot, with standard basis vectors with no transformations, you can use the convenience method in CoordinateSystem to set up a default system.
253
277
 
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.5.8"
3
+ s.version = "0.5.9"
4
4
  s.add_dependency('knnball', '>= 0.0.6')
5
5
  s.author = "Avishek Sen Gupta"
6
6
  s.email = "avishek.sen.gupta@gmail.com"
@@ -1,6 +1,6 @@
1
1
  require 'transform.rb'
2
2
  require 'ranges.rb'
3
- require 'matrix_operations.rb'
3
+ require 'matrix_extensions.rb'
4
4
  require 'coordinate_system.rb'
5
5
  require 'screen.rb'
6
6
  require 'interactive'
@@ -1,7 +1,7 @@
1
1
  require 'ranges'
2
2
  require 'ruby-processing'
3
- require 'matrix_operations'
4
3
  require 'hash_vector'
4
+ require 'matrix_extensions'
5
5
 
6
6
  include Math
7
7
 
@@ -16,8 +16,6 @@ end
16
16
  class CoordinateSystem
17
17
  CROSSHAIR_SCALE = 5000
18
18
  UNIT_TRANSFORM = [[1,0],[0,1]]
19
-
20
- include MatrixOperations
21
19
  attr_accessor :x_basis_vector, :y_basis_vector, :basis_matrix
22
20
 
23
21
  def self.standard(x_range, y_range, artist)
@@ -36,27 +34,21 @@ class CoordinateSystem
36
34
  @y_axis = y_axis
37
35
  @x_basis_vector = x_axis.basis_vector
38
36
  @y_basis_vector = y_axis.basis_vector
39
- @basis_transform = transform
40
- @basis_matrix =
37
+ @basis_transform = Matrix.rows(transform)
38
+ @basis_matrix = Matrix.rows(
41
39
  [
42
40
  [@x_basis_vector[:x],@y_basis_vector[:x]],
43
41
  [@x_basis_vector[:y],@y_basis_vector[:y]]
44
- ]
45
-
46
- d = @basis_matrix[0][0]*@basis_matrix[1][1] - @basis_matrix[0][1]*@basis_matrix[1][0]
47
- @inverse_basis =
48
- [
49
- [@basis_matrix[1][1]/d, -@basis_matrix[0][1]/d],
50
- [-@basis_matrix[1][0]/d, @basis_matrix[0][0]/d]
51
- ]
42
+ ])
52
43
 
53
- @standard_transform = MatrixOperations::into2Dx2D(MatrixOperations::into2Dx2D(@basis_matrix, @basis_transform), @inverse_basis)
44
+ @inverse_basis = @basis_matrix.inverse
45
+ @standard_transform = @basis_matrix*@basis_transform*@inverse_basis
54
46
  end
55
47
 
56
48
  def tick_vectors
57
49
  {
58
- :x_tick_vector => MatrixOperations::into2Dx1D(rotation(-90),@x_basis_vector),
59
- :y_tick_vector => MatrixOperations::into2Dx1D(rotation(90),@y_basis_vector)
50
+ :x_tick_vector => (rotation(-90)*@x_basis_vector).as_hash,
51
+ :y_tick_vector => (rotation(90)*@y_basis_vector).as_hash
60
52
  }
61
53
  end
62
54
 
@@ -82,29 +74,20 @@ class CoordinateSystem
82
74
 
83
75
  def rotation(angle)
84
76
  radians = angle * PI/180.0
85
- [[cos(radians), -sin(radians)],[sin(radians),cos(radians)]]
77
+ Matrix.rows([[cos(radians), -sin(radians)],[sin(radians),cos(radians)]])
86
78
  end
87
79
 
88
80
 
89
81
  def standard_basis(point)
90
- basis_matrix =
91
- [
92
- [@x_basis_vector[:x], @y_basis_vector[:x]],
93
- [@x_basis_vector[:y], @y_basis_vector[:y]]
94
- ]
95
- standard_point = MatrixOperations::into2Dx1D(basis_matrix, point)
96
-
97
- MatrixOperations::into2Dx1D(@standard_transform, standard_point)
82
+ standard_point = @basis_matrix* point
83
+ r = @standard_transform * standard_point
84
+ {:x => r[0,0], :y => r[1,0]}
98
85
  end
99
86
 
100
87
  def original(onscreen_point)
101
- p1 = MatrixOperations::into2Dx1D(MatrixOperations::inverse2D(@standard_transform), onscreen_point)
102
- basis_matrix =
103
- [
104
- [@x_basis_vector[:x], @y_basis_vector[:x]],
105
- [@x_basis_vector[:y], @y_basis_vector[:y]]
106
- ]
107
- MatrixOperations::into2Dx1D(MatrixOperations::inverse2D(basis_matrix), p1)
88
+ p1 = @standard_transform.inverse * onscreen_point
89
+ o = @basis_matrix.inverse* p1
90
+ {:x => o[0][0], :y => o[1][0]}
108
91
  end
109
92
 
110
93
  def crosshairs(p)
data/lib/demo.rb CHANGED
@@ -39,7 +39,7 @@ class Demo < Processing::App
39
39
 
40
40
  screen_transform = Transform.new({:x => 2, :y => -2}, {:x => 300, :y => 900})
41
41
  @screen = Screen.new(screen_transform, self, @basis)
42
- @screen.draw_axes(10,10)
42
+ @screen.draw_axes(10,10, :gridlines => false)
43
43
  stroke(1,1,0,1)
44
44
  fill(1,1,0)
45
45
  rect_mode(CENTER)
data/lib/hash_vector.rb CHANGED
@@ -1,9 +1,16 @@
1
+ require 'matrix'
2
+
1
3
  class Hash
2
4
  def *(scalar)
3
5
  {:x => self[:x] * scalar.to_f, :y => self[:y] * scalar.to_f}
4
6
  end
5
7
  def +(vector)
6
- {:x => self[:x] + vector[:x], :y => self[:y] + vector[:y]}
8
+ return {:x => self[:x] + vector[:x], :y => self[:y] + vector[:y]} if vector.kind_of? Hash
9
+ {:x => self[:x] + vector[0,0], :y => self[:y] + vector[1,0]}
10
+ end
11
+
12
+ def as_matrix
13
+ Matrix.columns([[self[:x], self[:y]]])
7
14
  end
8
15
  end
9
16
 
@@ -0,0 +1,14 @@
1
+ require 'matrix'
2
+
3
+ class Matrix
4
+ alias_method :multiply, :*
5
+ def *(another)
6
+ return multiply(Matrix.columns([[another[:x], another[:y]]])) if another.kind_of? Hash
7
+ multiply(another)
8
+ end
9
+
10
+ def as_hash
11
+ {:x => self[0,0], :y => self[1,0]}
12
+ end
13
+ end
14
+
data/lib/screen.rb CHANGED
@@ -19,9 +19,9 @@ class Screen
19
19
  @points = []
20
20
  @data = []
21
21
  @output = output
22
- @transform_matrix = [[@transform.scale[:x], 0],[0, @transform.scale[:y]]]
23
- nhm = MatrixOperations::into2Dx2D(@transform_matrix, @basis.basis_matrix)
24
- @affine_transform = PMatrix2D.new(nhm[0][0],nhm[0][1],@transform.origin[:x],nhm[1][0],nhm[1][1],@transform.origin[:y])
22
+ @transform_matrix = Matrix.rows([[@transform.scale[:x], 0],[0, @transform.scale[:y]]])
23
+ nhm = @transform_matrix* @basis.basis_matrix
24
+ @affine_transform = PMatrix2D.new(nhm[0,0],nhm[0,1],@transform.origin[:x],nhm[1,0],nhm[1,1],@transform.origin[:y])
25
25
  @inverse_affine_transform = @affine_transform.get
26
26
  @inverse_affine_transform.invert
27
27
  end
@@ -111,7 +111,7 @@ class Screen
111
111
  {:x => 5*vector[:x]/magnitude, :y => 5*vector[:y]/magnitude}
112
112
  end
113
113
 
114
- def draw_axes(x_interval, y_interval, labelling_blocks = {})
114
+ def draw_axes(x_interval, y_interval, options = {})
115
115
  f = @artist.createFont("Georgia", 24, true);
116
116
  @artist.text_font(f,16)
117
117
  axis_screen_transform = Transform.new({:x => 800, :y => -800}, @transform.origin)
@@ -129,10 +129,11 @@ class Screen
129
129
  @artist.line(x_ticks.first[:from][:x],x_ticks.first[:from][:y],x_ticks.last[:from][:x],x_ticks.last[:from][:y])
130
130
  @artist.line(y_ticks.first[:from][:x],y_ticks.first[:from][:y],y_ticks.last[:from][:x],y_ticks.last[:from][:y])
131
131
 
132
- draw_ticks(x_ticks, {:x => 0, :y => 20}, labelling_blocks[:x])
133
- draw_ticks(y_ticks, {:x => -50, :y => 0}, labelling_blocks[:y])
132
+ draw_ticks(x_ticks, {:x => 0, :y => 20}, options[:x])
133
+ draw_ticks(y_ticks, {:x => -50, :y => 0}, options[:y])
134
134
 
135
135
  @artist.stroke(0.4, 1.0, 0.5, 0.2)
136
+ return if !options[:gridlines].nil? && options[:gridlines] == false
136
137
  grid_lines = @basis.grid_lines(x_interval, y_interval).collect {|gl| {:from => @transform.apply(gl[:from]), :to => @transform.apply(gl[:to])}}
137
138
  grid_lines.each do |l|
138
139
  @artist.line(l[:from][:x],l[:from][:y],l[:to][:x],l[:to][:y])
data/redeploy.sh ADDED
@@ -0,0 +1,3 @@
1
+ gem build basis.gemspec
2
+ sudo /home/avishek/jruby/jruby-1.6.4/bin/jruby -S gem uninstall basis-processing
3
+ sudo /home/avishek/jruby/jruby-1.6.4/bin/jruby -S gem install basis-processing-0.5.9.gem
metadata CHANGED
@@ -1,34 +1,47 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: basis-processing
3
- version: !ruby/object:Gem::Version
4
- version: 0.5.8
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 5
9
+ - 9
10
+ version: 0.5.9
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Avishek Sen Gupta
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2011-10-11 00:00:00.000000000Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2011-10-25 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: knnball
16
- requirement: &17679680 !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
17
24
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 19
29
+ segments:
30
+ - 0
31
+ - 0
32
+ - 6
21
33
  version: 0.0.6
22
34
  type: :runtime
23
- prerelease: false
24
- version_requirements: *17679680
25
- description: Basis provides a set of classes for easily plotting and transforming
26
- arbitrary 2D coordinate systems by specifying their basis vectors in Ruby-Processing.
35
+ version_requirements: *id001
36
+ description: Basis provides a set of classes for easily plotting and transforming arbitrary 2D coordinate systems by specifying their basis vectors in Ruby-Processing.
27
37
  email: avishek.sen.gupta@gmail.com
28
38
  executables: []
39
+
29
40
  extensions: []
41
+
30
42
  extra_rdoc_files: []
31
- files:
43
+
44
+ files:
32
45
  - .gitignore
33
46
  - README
34
47
  - basis.gemspec
@@ -40,34 +53,44 @@ files:
40
53
  - lib/demo.rb
41
54
  - lib/hash_vector.rb
42
55
  - lib/interactive.rb
43
- - lib/matrix_operations.rb
56
+ - lib/matrix_extensions.rb
44
57
  - lib/ranges.rb
45
58
  - lib/screen.rb
46
59
  - lib/text_output.rb
47
60
  - lib/transform.rb
61
+ - redeploy.sh
48
62
  homepage: http://avishek.net/blog
49
63
  licenses: []
64
+
50
65
  post_install_message:
51
66
  rdoc_options: []
52
- require_paths:
67
+
68
+ require_paths:
53
69
  - lib
54
- required_ruby_version: !ruby/object:Gem::Requirement
70
+ required_ruby_version: !ruby/object:Gem::Requirement
55
71
  none: false
56
- requirements:
57
- - - ! '>='
58
- - !ruby/object:Gem::Version
59
- version: '0'
60
- required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
80
  none: false
62
- requirements:
63
- - - ! '>='
64
- - !ruby/object:Gem::Version
65
- version: '0'
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
66
88
  requirements: []
89
+
67
90
  rubyforge_project:
68
- rubygems_version: 1.8.6
91
+ rubygems_version: 1.7.2
69
92
  signing_key:
70
93
  specification_version: 3
71
- summary: Basis provides a set of classes for easily plotting and transforming arbitrary
72
- 2D coordinate systems by specifying their basis vectors in Ruby-Processing.
94
+ summary: Basis provides a set of classes for easily plotting and transforming arbitrary 2D coordinate systems by specifying their basis vectors in Ruby-Processing.
73
95
  test_files: []
96
+
@@ -1,24 +0,0 @@
1
- module MatrixOperations
2
- def MatrixOperations.into2Dx2D(first, second)
3
- [
4
- [second[0][0]*first[0][0] + second[1][0]*first[0][1], second[0][1]*first[0][0] + second[1][1]*first[0][1]],
5
- [second[0][0]*first[1][0] + second[1][0]*first[1][1], second[0][1]*first[1][0] + second[1][1]*first[1][1]]
6
- ]
7
- end
8
-
9
- def MatrixOperations.into2Dx1D(transform, point)
10
- {
11
- :x => transform[0][0]*point[:x] + transform[0][1]*point[:y],
12
- :y => transform[1][0]*point[:x] + transform[1][1]*point[:y]
13
- }
14
- end
15
-
16
- def MatrixOperations.inverse2D(m)
17
- determinant = (m[0][0]*m[1][1] - m[0][1]*m[1][0]).to_f;
18
- [
19
- [m[1][1]/determinant, -m[0][1]/determinant],
20
- [-m[1][0]/determinant, m[0][0]/determinant]
21
- ]
22
- end
23
- end
24
-