class Phlox::GradientGen::Node
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.
Public Class Methods
new()
click to toggle source
# 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
Public Instance Methods
binary_call()
click to toggle source
# File lib/phlox/gradient_gen.rb, line 75 def binary_call @val1 = Node.new @val2 = Node.new @fn = binary_fn end
binary_fn()
click to toggle source
choose a random binary function
# File lib/phlox/gradient_gen.rb, line 87 def binary_fn [:mul, :add, :and, :or, :xor, :pow, :sub, :div].sample end
const()
click to toggle source
calculate a random constant, from 0 to 255
# File lib/phlox/gradient_gen.rb, line 64 def const; rand 255; end
param()
click to toggle source
choose one of the parameters randomly
# File lib/phlox/gradient_gen.rb, line 67 def param; [:x, :y].sample; end
radians(n)
click to toggle source
converts a value from degrees to radians
# File lib/phlox/gradient_gen.rb, line 118 def radians n Math::PI * (n / 180.0) end
run(x, y)
click to toggle source
Evaluate the node and its children into a number, given an x and y parameter. Any value that produce an error will equal 0.
# 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)
click to toggle source
run @fn on the arguments
# 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)
click to toggle source
run @fn on the argument
# 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_s()
click to toggle source
# 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_call()
click to toggle source
make a new argument node and choose a unary function to apply it to
# File lib/phlox/gradient_gen.rb, line 70 def unary_call @val1 = Node.new @fn = unary_fn end
unary_fn()
click to toggle source
choose a random unary function
# File lib/phlox/gradient_gen.rb, line 82 def unary_fn [:sq, :sin, :cos, :mod5, :log2, :tan].sample end