basis-processing 0.3 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README +1 -0
- data/basis.gemspec +12 -0
- metadata +6 -9
- data/basis_processing.rb +0 -4
- data/coordinate_system.rb +0 -99
- data/matrix_operations.rb +0 -16
- data/ranges.rb +0 -48
- data/screen.rb +0 -41
- data/transform.rb +0 -18
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.*~
|
data/README
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Basis provides a set of classes for easily plotting and transforming arbitrary 2D coordinate systems by specifying their basis vectors in Ruby-Processing.
|
data/basis.gemspec
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
spec = Gem::Specification.new do |s|
|
2
|
+
s.name = "basis-processing"
|
3
|
+
s.version = "0.4"
|
4
|
+
s.author = "Avishek Sen Gupta"
|
5
|
+
s.email = "avishek.sen.gupta@gmail.com"
|
6
|
+
s.homepage = "http://avishek.net/blog"
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.summary = "Some description"
|
9
|
+
s.files = `git ls-files`.split("\n")
|
10
|
+
s.summary = %q{Basis provides a set of classes for easily plotting and transforming arbitrary 2D coordinate systems by specifying their basis vectors in Ruby-Processing.}
|
11
|
+
s.description = %q{Basis provides a set of classes for easily plotting and transforming arbitrary 2D coordinate systems by specifying their basis vectors in Ruby-Processing.}
|
12
|
+
end
|
metadata
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: basis-processing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: "0.
|
8
|
+
- 4
|
9
|
+
version: "0.4"
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Avishek Sen Gupta
|
@@ -26,12 +26,9 @@ extensions: []
|
|
26
26
|
extra_rdoc_files: []
|
27
27
|
|
28
28
|
files:
|
29
|
-
-
|
30
|
-
-
|
31
|
-
-
|
32
|
-
- matrix_operations.rb
|
33
|
-
- screen.rb
|
34
|
-
- basis_processing.rb
|
29
|
+
- .gitignore
|
30
|
+
- README
|
31
|
+
- basis.gemspec
|
35
32
|
homepage: http://avishek.net/blog
|
36
33
|
licenses: []
|
37
34
|
|
data/basis_processing.rb
DELETED
data/coordinate_system.rb
DELETED
@@ -1,99 +0,0 @@
|
|
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/matrix_operations.rb
DELETED
@@ -1,16 +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
|
-
end
|
16
|
-
|
data/ranges.rb
DELETED
@@ -1,48 +0,0 @@
|
|
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/screen.rb
DELETED
@@ -1,41 +0,0 @@
|
|
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/transform.rb
DELETED
@@ -1,18 +0,0 @@
|
|
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
|
-
|