basis-processing 0.4 → 0.4.1

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/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"
3
+ s.version = "0.4.1"
4
4
  s.author = "Avishek Sen Gupta"
5
5
  s.email = "avishek.sen.gupta@gmail.com"
6
6
  s.homepage = "http://avishek.net/blog"
@@ -0,0 +1,4 @@
1
+ require 'transform.rb'
2
+ require 'ranges.rb'
3
+ require 'matrix_operations.rb'
4
+ require 'screen.rb'
@@ -0,0 +1,99 @@
1
+ require 'ranges'
2
+ require 'ruby-processing'
3
+ require 'matrix_operations'
4
+
5
+ include Math
6
+
7
+ class Axis
8
+ attr_accessor :basis_vector, :range
9
+ def initialize(basis_vector, range)
10
+ @basis_vector = basis_vector
11
+ @range = range
12
+ end
13
+ end
14
+
15
+ class CoordinateSystem
16
+ include MatrixOperations
17
+ attr_accessor :x_basis_vector, :y_basis_vector
18
+
19
+ def initialize(x_axis, y_axis, transform, artist)
20
+ @artist = artist
21
+ @x_axis = x_axis
22
+ @y_axis = y_axis
23
+ @x_basis_vector = x_axis.basis_vector
24
+ @y_basis_vector = y_axis.basis_vector
25
+ @basis_transform = transform
26
+ @basis_matrix =
27
+ [
28
+ [@x_basis_vector[:x],@y_basis_vector[:x]],
29
+ [@x_basis_vector[:y],@y_basis_vector[:y]]
30
+ ]
31
+
32
+ d = @basis_matrix[0][0]*@basis_matrix[1][1] - @basis_matrix[0][1]*@basis_matrix[1][0]
33
+ @inverse_basis =
34
+ [
35
+ [@basis_matrix[1][1]/d, -@basis_matrix[0][1]/d],
36
+ [-@basis_matrix[1][0]/d, @basis_matrix[0][0]/d]
37
+ ]
38
+
39
+ @standard_transform = MatrixOperations::into2Dx2D(MatrixOperations::into2Dx2D(@basis_matrix, @basis_transform), @inverse_basis)
40
+ end
41
+
42
+ def tick_vectors
43
+ unnormalised_vectors =
44
+ {
45
+ :x_tick_vector => MatrixOperations::into2Dx1D(rotation(-90),@x_basis_vector),
46
+ :y_tick_vector => MatrixOperations::into2Dx1D(rotation(90),@y_basis_vector)
47
+ }
48
+ {
49
+ :x_tick_vector => normal(unnormalised_vectors[:x_tick_vector]),
50
+ :y_tick_vector => normal(unnormalised_vectors[:y_tick_vector])
51
+ }
52
+ end
53
+
54
+ def normal(vector)
55
+ magnitude = sqrt(vector[:x]**2 + vector[:y]**2)
56
+ {:x => 5*vector[:x]/magnitude, :y => 5*vector[:y]/magnitude}
57
+ end
58
+
59
+ def sum(v1, v2)
60
+ {:x => v1[:x] + v2[:x], :y => v1[:y] + v2[:y]}
61
+ end
62
+
63
+ def x_ticks(x_basis_interval)
64
+ lines = []
65
+ t_vectors = tick_vectors
66
+ @x_axis.range.run(x_basis_interval) do |i,v|
67
+ tick_origin = standard_basis({:x => i, :y => 0})
68
+ lines << {:label => v, :from => tick_origin, :to => sum(tick_origin, t_vectors[:x_tick_vector])}
69
+ end
70
+ lines
71
+ end
72
+
73
+ def y_ticks(y_basis_interval)
74
+ lines = []
75
+ t_vectors = tick_vectors
76
+ @y_axis.range.run(y_basis_interval) do |i,v|
77
+ tick_origin = standard_basis({:x => 0, :y => i})
78
+ lines << {:label => v, :from => tick_origin, :to => sum(tick_origin, t_vectors[:y_tick_vector])}
79
+ end
80
+ lines
81
+ end
82
+
83
+ def rotation(angle)
84
+ radians = angle * PI/180.0
85
+ [[cos(radians), -sin(radians)],[sin(radians),cos(radians)]]
86
+ end
87
+
88
+
89
+ def standard_basis(point)
90
+ standard_point =
91
+ {
92
+ :x => @x_basis_vector[:x]*point[:x] + @y_basis_vector[:x]*point[:y],
93
+ :y => @x_basis_vector[:y]*point[:x] + @y_basis_vector[:y]*point[:y]
94
+ }
95
+
96
+ MatrixOperations::into2Dx1D(@standard_transform, standard_point)
97
+ end
98
+ end
99
+
data/lib/demo.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'ranges'
2
+ require 'transform'
3
+ require 'coordinate_system'
4
+ require 'screen'
5
+
6
+ class Demo < Processing::App
7
+ app = self
8
+ def setup
9
+ smooth
10
+ background(0,0,0)
11
+ color_mode(RGB, 1.0)
12
+ stroke(1,1,0,1)
13
+
14
+ points = []
15
+ 100.times {points << {:x => random(200), :y => random(300)}}
16
+
17
+ x_basis_vector = {:x => 1.0, :y => 0.0}
18
+ y_basis_vector = {:x => 0.0, :y => 1.0}
19
+
20
+ x_range = ContinuousRange.new({:minimum => 0, :maximum => 200})
21
+ y_range = ContinuousRange.new({:minimum => 0, :maximum => 300})
22
+
23
+ basis = CoordinateSystem.new(Axis.new(x_basis_vector,x_range), Axis.new(y_basis_vector,y_range), [[4,0],[0,2]], self)
24
+ screen_transform = SignedTransform.new({:x => 10, :y => -1}, {:x => 300, :y => 900})
25
+ screen = Screen.new(screen_transform, self)
26
+ screen.draw_axes(basis,10,10)
27
+ stroke(1,1,0,1)
28
+ fill(1,1,0)
29
+ points.each do |p|
30
+ screen.plot(p, basis)
31
+ end
32
+ end
33
+
34
+ def draw
35
+ end
36
+ end
37
+
38
+ w = 1200
39
+ h = 1000
40
+
41
+ Demo.new(:title => "My Sketch", :width => w, :height => h)
42
+
@@ -0,0 +1,16 @@
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
+ end
16
+
data/lib/ranges.rb ADDED
@@ -0,0 +1,48 @@
1
+ class ContinuousRange
2
+ attr_accessor :minimum, :maximum
3
+
4
+ def initialize(range)
5
+ @minimum = range[:minimum]
6
+ @maximum = range[:maximum]
7
+ end
8
+
9
+ def interval
10
+ @maximum - @minimum
11
+ end
12
+
13
+ def index(element)
14
+ element.to_f
15
+ end
16
+
17
+ def run(interval)
18
+ current = @minimum
19
+ while(current <= @maximum)
20
+ yield(current,current)
21
+ current += interval
22
+ end
23
+ end
24
+ end
25
+
26
+ class DiscreteRange
27
+ attr_accessor :values
28
+ def initialize(v)
29
+ @values = v[:values]
30
+ end
31
+
32
+ def interval
33
+ @values.count
34
+ end
35
+
36
+ def index(element)
37
+ @values.index(element)
38
+ end
39
+
40
+ def run(interval)
41
+ current = 0
42
+ while(current <= @values.count - 1)
43
+ yield(current,@values[current])
44
+ current += interval
45
+ end
46
+ end
47
+ end
48
+
data/lib/screen.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'transform'
2
+
3
+ class Screen
4
+ def initialize(transform, artist)
5
+ @transform = transform
6
+ @artist = artist
7
+ end
8
+
9
+ def plot(point, basis)
10
+ standard_point = basis.standard_basis(point)
11
+ p = @transform.apply(standard_point)
12
+ @artist.ellipse(p[:x], p[:y], 5, 5)
13
+ end
14
+
15
+ def draw_ticks(ticks, displacement)
16
+ ticks.each do |l|
17
+ from = @transform.apply(l[:from])
18
+ to = @transform.apply(l[:to])
19
+ @artist.line(from[:x],from[:y],to[:x],to[:y])
20
+ @artist.fill(1)
21
+ @artist.text(l[:label], to[:x]+displacement[:x], to[:y]+displacement[:y])
22
+ end
23
+ end
24
+
25
+ def draw_axes(basis, x_interval, y_interval)
26
+ f = @artist.createFont("Georgia", 24, true);
27
+ @artist.text_font(f,16)
28
+ @artist.stroke(1,1,1,1)
29
+ axis_screen_transform = Transform.new({:x => 800, :y => -800}, @transform.origin)
30
+ origin = {:x => 0, :y => 0}
31
+ screen_origin = @transform.apply(origin)
32
+ x_basis_edge = axis_screen_transform.apply(basis.x_basis_vector)
33
+ y_basis_edge = axis_screen_transform.apply(basis.y_basis_vector)
34
+ @artist.line(screen_origin[:x],screen_origin[:y],x_basis_edge[:x],x_basis_edge[:y])
35
+ @artist.line(screen_origin[:x],screen_origin[:y],y_basis_edge[:x],y_basis_edge[:y])
36
+
37
+ draw_ticks(basis.x_ticks(x_interval), {:x => 0, :y => 20})
38
+ draw_ticks(basis.y_ticks(y_interval), {:x => -50, :y => 0})
39
+ end
40
+ end
41
+
data/lib/transform.rb ADDED
@@ -0,0 +1,18 @@
1
+ class Transform
2
+ attr_accessor :scale, :origin
3
+ def initialize(scale, origin)
4
+ @origin = origin
5
+ @scale = scale
6
+ end
7
+
8
+ def apply(p)
9
+ { :x => @origin[:x] + p[:x] * @scale[:x], :y => @origin[:y] + p[:y] * @scale[:y]}
10
+ end
11
+ end
12
+
13
+ class SignedTransform < Transform
14
+ def apply(p)
15
+ { :x => @origin[:x] + p[:x] * (@scale[:x]<=>0.0).to_i, :y => @origin[:y] + p[:y] * (@scale[:y]<=>0.0).to_i}
16
+ end
17
+ end
18
+
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: basis-processing
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
4
+ hash: 13
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- version: "0.4"
9
+ - 1
10
+ version: 0.4.1
10
11
  platform: ruby
11
12
  authors:
12
13
  - Avishek Sen Gupta
@@ -29,6 +30,13 @@ files:
29
30
  - .gitignore
30
31
  - README
31
32
  - basis.gemspec
33
+ - lib/basis_processing.rb
34
+ - lib/coordinate_system.rb
35
+ - lib/demo.rb
36
+ - lib/matrix_operations.rb
37
+ - lib/ranges.rb
38
+ - lib/screen.rb
39
+ - lib/transform.rb
32
40
  homepage: http://avishek.net/blog
33
41
  licenses: []
34
42