Class: Phlox::GradientGen::Node

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

Overview

A node in an expression tree for a pixel color calculation. Initializing a node also generates its child nodes, and you can use ‘Node#run` to evaluate the expression tree into a numerical value.

Instance Method Summary collapse

Constructor Details

#initializeNode

Returns a new instance of Node.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/phlox/gradient_gen.rb', line 19

def initialize
  # calculate the node's value - it can either be a constant, one of the parameters,
  # a unary function invocation on another node, or a binary invocation on two other nodes
  types = [:param, :param, :const, :unary, :unary, :binary]
  @type = types.sample
  
  case @type
  when :const
    @val = const
  when :param
    @val = param
  when :unary
    unary_call
  when :binary
    binary_call
  end
end

Instance Method Details

#binary_callObject



75
76
77
78
79
# File 'lib/phlox/gradient_gen.rb', line 75

def binary_call
  @val1 = Node.new
  @val2 = Node.new
  @fn = binary_fn
end

#binary_fnObject

choose a random binary function



87
88
89
# File 'lib/phlox/gradient_gen.rb', line 87

def binary_fn
  [:mul, :add, :and, :or, :xor, :pow, :sub, :div].sample
end

#constObject

calculate a random constant, from 0 to 255



64
# File 'lib/phlox/gradient_gen.rb', line 64

def const; rand 255; end

#paramObject

choose one of the parameters randomly



67
# File 'lib/phlox/gradient_gen.rb', line 67

def param; [:x, :y].sample; end

#radians(n) ⇒ Object

converts a value from degrees to radians



118
119
120
# File 'lib/phlox/gradient_gen.rb', line 118

def radians n
  Math::PI * (n / 180.0)
end

#run(x, y) ⇒ Object

Evaluate the node and its children into a number, given an x and y parameter. Any value that produce an error will equal 0.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/phlox/gradient_gen.rb', line 39

def run x, y
  begin

    # try calculating the value
    case @type
    when :const
      return @val
    when :param
      return {x: x, y: y}[@val]
    when :unary
      v1 = @val1.run x, y
      return run_unary(v1).abs
    when :binary
      v1 = @val1.run x, y
      v2 = @val2.run x, y
      return run_binary(v1, v2).abs
    end
    
  # if something goes wrong, give up and just return 0
  rescue => e
    return 0
  end
end

#run_binary(v1, v2) ⇒ Object

run @fn on the arguments



104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/phlox/gradient_gen.rb', line 104

def run_binary v1, v2
  case @fn
  when :mul then v1 * v2
  when :add then v1 + v2
  when :and then v1.to_i & v2.to_i
  when :or then v1.to_i | v2.to_i
  when :xor then v1.to_i ^ v2.to_i
  when :pow then v1 ** (v2 % 10)
  when :sub then v1 - v2
  when :div then v1 / v2.to_f
  end
end

#run_unary(v1) ⇒ Object

run @fn on the argument



92
93
94
95
96
97
98
99
100
101
# File 'lib/phlox/gradient_gen.rb', line 92

def run_unary v1
  case @fn
  when :sq then v1 ** 2
  when :sin then 50 * Math::sin(radians v1)
  when :cos then 50 * Math::cos(radians v1)
  when :mod5 then 10 * (v1.abs % 5)
  when :log2 then 10 * Math::log2(v1.abs)
  when :tan then 50 * Math::tan(radians v1)
  end
end

#to_sObject



122
123
124
125
126
127
128
129
# File 'lib/phlox/gradient_gen.rb', line 122

def to_s
  case @type
  when :const then @val.to_s
  when :param then @val.to_s
  when :unary then  "#@fn(#@val1)"
  when :binary then "#@fn(#@val1, #@val2)"
  end
end

#unary_callObject

make a new argument node and choose a unary function to apply it to



70
71
72
73
# File 'lib/phlox/gradient_gen.rb', line 70

def unary_call
  @val1 = Node.new
  @fn = unary_fn
end

#unary_fnObject

choose a random unary function



82
83
84
# File 'lib/phlox/gradient_gen.rb', line 82

def unary_fn
  [:sq, :sin, :cos, :mod5, :log2, :tan].sample
end