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