Class: CoordinateSystem

Inherits:
Object
  • Object
show all
Defined in:
lib/coordinate_system.rb

Constant Summary collapse

CROSSHAIR_SCALE =
5000
UNIT_TRANSFORM =
[[1,0],[0,1]]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(x_axis, y_axis, artist, transform = UNIT_TRANSFORM) ⇒ CoordinateSystem

Returns a new instance of CoordinateSystem.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/coordinate_system.rb', line 31

def initialize(x_axis, y_axis, artist, transform = UNIT_TRANSFORM)
  @artist = artist
  @x_axis = x_axis
  @y_axis = y_axis
  @x_basis_vector = x_axis.basis_vector
  @y_basis_vector = y_axis.basis_vector
  @basis_transform = Matrix.rows(transform)
  @basis_matrix = Matrix.rows(
      [
        [@x_basis_vector[:x],@y_basis_vector[:x]],
        [@x_basis_vector[:y],@y_basis_vector[:y]]
      ])

  @inverse_basis = @basis_matrix.inverse
  @standard_transform = @basis_matrix*@basis_transform*@inverse_basis
end

Instance Attribute Details

#basis_matrixObject

Returns the value of attribute basis_matrix.



19
20
21
# File 'lib/coordinate_system.rb', line 19

def basis_matrix
  @basis_matrix
end

#x_basis_vectorObject

Returns the value of attribute x_basis_vector.



19
20
21
# File 'lib/coordinate_system.rb', line 19

def x_basis_vector
  @x_basis_vector
end

#y_basis_vectorObject

Returns the value of attribute y_basis_vector.



19
20
21
# File 'lib/coordinate_system.rb', line 19

def y_basis_vector
  @y_basis_vector
end

Class Method Details

.standard(x_range, y_range, artist, labels = {:x => 'x', :y => 'y'}) ⇒ Object



21
22
23
24
25
26
27
28
29
# File 'lib/coordinate_system.rb', line 21

def self.standard(x_range, y_range, artist, labels = {:x => 'x', :y => 'y'})
  x_basis_vector = {:x => 1.0, :y => 0.0, :label => labels[:x]}
  y_basis_vector = {:x => 0.0, :y => 1.0, :label => labels[:y]}

  x_range = ContinuousRange.new(x_range)
  y_range = ContinuousRange.new(y_range)

  CoordinateSystem.new(Axis.new(x_basis_vector,x_range), Axis.new(y_basis_vector,y_range), artist, UNIT_TRANSFORM)
end

Instance Method Details

#crosshairs(p) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/coordinate_system.rb', line 93

def crosshairs(p)
  crosshair_x_p1 = (@x_basis_vector*CROSSHAIR_SCALE) + standard_basis(p)
  crosshair_x_p2 = (@x_basis_vector*(-CROSSHAIR_SCALE)) + standard_basis(p)
  crosshair_y_p1 = (@y_basis_vector*CROSSHAIR_SCALE) + standard_basis(p)
  crosshair_y_p2 = (@y_basis_vector*(-CROSSHAIR_SCALE)) + standard_basis(p)
  [{:from => crosshair_x_p1, :to => crosshair_x_p2}, {:from => crosshair_y_p1, :to => crosshair_y_p2}]
end

#grid_lines(x_basis_interval, y_basis_interval) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/coordinate_system.rb', line 101

def grid_lines(x_basis_interval, y_basis_interval)
  lines = []
  @x_axis.range.run(x_basis_interval) do |i,v|
    raw_origin = {:x => i, :y => @y_axis.range.minimum}
    hair_origin = standard_basis(raw_origin)
    hair_end = @y_basis_vector*@y_axis.range.interval + standard_basis(raw_origin)
    lines << {:from => hair_origin, :to => hair_end}
  end
  @y_axis.range.run(y_basis_interval) do |i,v|
    raw_origin = {:x => @x_axis.range.minimum, :y => i}
    hair_origin = standard_basis(raw_origin)
    hair_end = @x_basis_vector*@x_axis.range.interval + standard_basis(raw_origin)
    lines << {:from => hair_origin, :to => hair_end}
  end
  lines
end

#original(onscreen_point) ⇒ Object



87
88
89
90
91
# File 'lib/coordinate_system.rb', line 87

def original(onscreen_point)
  p1 = @standard_transform.inverse * onscreen_point
  o = @basis_matrix.inverse* p1
  {:x => o[0][0], :y => o[1][0]}
end

#rotation(angle) ⇒ Object



75
76
77
78
# File 'lib/coordinate_system.rb', line 75

def rotation(angle)
  radians = angle * PI/180.0
  Matrix.rows([[cos(radians), -sin(radians)],[sin(radians),cos(radians)]])
end

#standard_basis(point) ⇒ Object



81
82
83
84
85
# File 'lib/coordinate_system.rb', line 81

def standard_basis(point)
  standard_point = @basis_matrix* point
  r = @standard_transform * standard_point
  {:x => r[0,0], :y => r[1,0]}
end

#tick_vectorsObject



48
49
50
51
52
53
# File 'lib/coordinate_system.rb', line 48

def tick_vectors
  {
    :x_tick_vector => (rotation(-90)*@x_basis_vector).as_hash,
    :y_tick_vector => (rotation(90)*@y_basis_vector).as_hash
  }
end

#x_ticks(x_basis_interval) ⇒ Object



55
56
57
58
59
60
61
62
63
# File 'lib/coordinate_system.rb', line 55

def x_ticks(x_basis_interval)
  lines = []
  t_vectors = tick_vectors
  @x_axis.range.run(x_basis_interval) do |i,v|
    tick_origin = standard_basis({:x => i, :y => 0})
    lines << {:label => v, :from => tick_origin, :to => tick_origin + t_vectors[:x_tick_vector]}
  end
  lines
end

#y_ticks(y_basis_interval) ⇒ Object



65
66
67
68
69
70
71
72
73
# File 'lib/coordinate_system.rb', line 65

def y_ticks(y_basis_interval)
  lines = []
  t_vectors = tick_vectors
  @y_axis.range.run(y_basis_interval) do |i,v|
    tick_origin = standard_basis({:x => 0, :y => i})
    lines << {:label => v, :from => tick_origin, :to => tick_origin + t_vectors[:y_tick_vector]}
  end
  lines
end