Class: Perlin::Noise
- Inherits:
-
Object
- Object
- Perlin::Noise
- Defined in:
- lib/perlin/noise.rb
Constant Summary collapse
Instance Method Summary collapse
-
#[](*coords) ⇒ Float
Noise value between (-1..1).
-
#initialize(dim, options = {}) ⇒ Noise
constructor
A new instance of Noise.
Constructor Details
#initialize(dim, options = {}) ⇒ Noise
Returns a new instance of Noise.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/perlin/noise.rb', line 9 def initialize(dim, = {}) = DEFAULT_OPTIONS.merge @dim = dim @interval = .fetch(:interval) @curve = .fetch(:curve) @seed = .fetch(:seed) raise ArgumentError.new('Invalid dimension: must be a positive integer') unless @dim.is_a?(Integer) && @dim > 0 raise ArgumentError.new('Invalid interval: must be a positive integer') unless @interval.is_a?(Integer) && @interval > 0 raise ArgumentError.new('Invalid curve specified: must be a Proc object') unless @curve.is_a?(Proc) raise ArgumentError.new('Invalid seed: must be a number') unless @seed.nil? || @seed.is_a?(Numeric) # Generate pseudo-random gradient vector for each grid point @gradient_table = Perlin::GradientTable.new @dim, @interval, @seed end |
Instance Method Details
#[](*coords) ⇒ Float
Returns Noise value between (-1..1).
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/perlin/noise.rb', line 28 def [](*coords) raise ArgumentError.new("Invalid coordinates") unless coords.length == @dim coords = Perlin::Vector[*coords] cell = Perlin::Vector[*coords.map(&:to_i)] diff = coords - cell # Calculate noise factor at each surrouning vertex nf = {} iterate @dim, 2 do |idx| idx = Perlin::Vector[*idx] # "The value of each gradient ramp is computed by means of a scalar # product (dot product) between the gradient vectors of each grid point # and the vectors from the grid points." gv = @gradient_table[*(cell + idx).to_a] nf[idx.to_a] = gv.inner_product(diff - idx) end dim = @dim diff.to_a.each do |u| bu = @curve.call u # Pair-wise interpolation, trimming down dimensions iterate dim, 2 do |idx1| next if idx1.first == 1 idx2 = idx1.dup idx2[0] = 1 idx3 = idx1[1..-1] nf[idx3] = nf[idx1] + bu * (nf[idx2] - nf[idx1]) end dim -= 1 end (nf[[]] + 1) * 0.5 end |