Class: Keisanjaku::Scale

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

Constant Summary collapse

DEGREE =
Math::PI / 180.0
S_MIN_DEGREES =
Math.asin(0.1) / DEGREE
T_MIN_DEGREES =
Math.atan(0.1) / DEGREE
SCALES =
{
  "K" => Scale.new("K", kind: :power, decades: 3),
  "A" => Scale.new("A", kind: :power, decades: 2),
  "B" => Scale.new("B", kind: :power, decades: 2),
  "CI" => Scale.new("CI", kind: :inverse_log),
  "C" => Scale.new("C", kind: :log),
  "S" => Scale.new("S", kind: :sin),
  "T" => Scale.new("T", kind: :tan),
  "D" => Scale.new("D", kind: :log),
  "L" => Scale.new("L", kind: :linear)
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, kind:, decades: 1) ⇒ Scale

Returns a new instance of Scale.



11
12
13
14
15
# File 'lib/keisanjaku/scale.rb', line 11

def initialize(name, kind:, decades: 1)
  @name = name.to_s.upcase
  @kind = kind
  @decades = decades
end

Instance Attribute Details

#decadesObject (readonly)

Returns the value of attribute decades.



9
10
11
# File 'lib/keisanjaku/scale.rb', line 9

def decades
  @decades
end

#kindObject (readonly)

Returns the value of attribute kind.



9
10
11
# File 'lib/keisanjaku/scale.rb', line 9

def kind
  @kind
end

#nameObject (readonly)

Returns the value of attribute name.



9
10
11
# File 'lib/keisanjaku/scale.rb', line 9

def name
  @name
end

Class Method Details

.fetch(name) ⇒ Object



81
82
83
84
# File 'lib/keisanjaku/scale.rb', line 81

def self.fetch(name)
  key = name.to_s.upcase
  SCALES.fetch(key) { raise ScaleError, "unknown scale: #{name}" }
end

.namesObject



86
87
88
# File 'lib/keisanjaku/scale.rb', line 86

def self.names
  SCALES.keys
end

Instance Method Details

#position(value) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/keisanjaku/scale.rb', line 17

def position(value)
  numeric = Float(value)
  pos = case kind
        when :log
          require_range(numeric, 1.0, 10.0)
          Math.log10(numeric)
        when :inverse_log
          require_range(numeric, 1.0, 10.0)
          1.0 - Math.log10(numeric)
        when :power
          require_range(numeric, 1.0, 10.0**decades)
          Math.log10(numeric) / decades
        when :linear
          require_range(numeric, 0.0, 1.0)
          numeric
        when :sin
          require_range(numeric, S_MIN_DEGREES, 90.0)
          Math.log10(10.0 * Math.sin(numeric * DEGREE))
        when :tan
          require_range(numeric, T_MIN_DEGREES, 45.0)
          Math.log10(10.0 * Math.tan(numeric * DEGREE))
        else
          raise ScaleError, "unknown scale kind: #{kind}"
        end
  clamp_unit(pos)
end

#ticks(width) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/keisanjaku/scale.rb', line 64

def ticks(width)
  case kind
  when :log, :inverse_log
    log_ticks(width)
  when :power
    power_ticks(width)
  when :linear
    linear_ticks(width)
  when :sin
    trigonometric_ticks(:sin, width)
  when :tan
    trigonometric_ticks(:tan, width)
  else
    []
  end
end

#value_at(pos) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/keisanjaku/scale.rb', line 44

def value_at(pos)
  numeric = clamp_unit(Float(pos))
  case kind
  when :log
    10.0**numeric
  when :inverse_log
    10.0**(1.0 - numeric)
  when :power
    10.0**(decades * numeric)
  when :linear
    numeric
  when :sin
    Math.asin((10.0**numeric) / 10.0) / DEGREE
  when :tan
    Math.atan((10.0**numeric) / 10.0) / DEGREE
  else
    raise ScaleError, "unknown scale kind: #{kind}"
  end
end