basis-processing 0.4 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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